добавили комменты к строкам, возможно придется переписать бд🤩🤩🤩
This commit is contained in:
parent
cf0ff194d2
commit
7022fdb50b
@ -1,12 +1,12 @@
|
||||
import gc
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from pprint import pprint
|
||||
import mariadb
|
||||
import serial.tools.list_ports
|
||||
|
||||
from PyWeather.weather.stations.davis import VantagePro
|
||||
#from PyWeather.weather.stations.davis import VantagePro
|
||||
from prediction import run_prediction_module
|
||||
|
||||
logging.basicConfig(filename="Stations.log",
|
||||
@ -54,28 +54,27 @@ def write_data(device, station, send=True):
|
||||
|
||||
|
||||
def get_previous_values(cursor):
|
||||
cursor.execute("SELECT SunRise, SunSet, WindDir FROM weather_data ORDER BY DateStamp DESC LIMIT 1")
|
||||
cursor.execute("SELECT SunRise, SunSet, WindDir, DateStamp FROM weather_data ORDER BY DateStamp DESC LIMIT 1")
|
||||
result = cursor.fetchone()
|
||||
|
||||
if result is None:
|
||||
return None, None, None
|
||||
return None, None, None, None
|
||||
|
||||
sun_rise, sun_set, wind_dir = result
|
||||
return sun_rise, sun_set, wind_dir
|
||||
sun_rise, sun_set, wind_dir, datestamp = result
|
||||
return sun_rise, sun_set, wind_dir, datestamp
|
||||
|
||||
|
||||
def save_prediction_to_db(predictions):
|
||||
try:
|
||||
current_timestamp = datetime.now()
|
||||
|
||||
sun_rise, sun_set, wind_dir = get_previous_values(cursor)
|
||||
sun_rise, sun_set, wind_dir, datestamp = get_previous_values(cursor)
|
||||
|
||||
fields = ['DateStamp', 'SunRise', 'SunSet', 'WindDir'] + list(predictions.keys())
|
||||
placeholders = ', '.join(['%s'] * len(fields))
|
||||
field_names = ', '.join(fields)
|
||||
|
||||
values = [current_timestamp, sun_rise, sun_set, wind_dir] + list(predictions.values())
|
||||
|
||||
values = [datestamp + timedelta(minutes = 1), sun_rise, sun_set, wind_dir] + list(predictions.values())
|
||||
pprint(dict(zip(fields, values)))
|
||||
sql = f"INSERT INTO weather_data ({field_names}) VALUES ({placeholders})"
|
||||
# cursor.execute(sql, values)
|
||||
# conn.commit()
|
||||
@ -97,7 +96,7 @@ try:
|
||||
except mariadb.Error as e:
|
||||
logger.error('DB_ERR: ' + str(e))
|
||||
raise e
|
||||
|
||||
while True:
|
||||
try:
|
||||
ports = serial.tools.list_ports.comports()
|
||||
available_ports = {}
|
||||
@ -107,18 +106,21 @@ try:
|
||||
available_ports[port.name] = port.vid
|
||||
|
||||
devices = [VantagePro(port) for port in available_ports.keys()]
|
||||
|
||||
while True:
|
||||
for i in range(1):
|
||||
if len(devices) != 0:
|
||||
logger.info(devices)
|
||||
# write_data(devices[i], 'st' + str(available_ports[list(available_ports.keys())[i]]), True)
|
||||
else:
|
||||
raise Exception("Can't connect to device")
|
||||
time.sleep(1)
|
||||
raise Exception('Can`t connect to device')
|
||||
time.sleep(60)
|
||||
except Exception as e:
|
||||
logger.error('Device_error: ' + str(e))
|
||||
logger.error('Device_error' + str(e))
|
||||
predictions = run_prediction_module()
|
||||
logger.info(predictions)
|
||||
#logger.info(predictions)
|
||||
if predictions is not None:
|
||||
save_prediction_to_db(predictions)
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
#todo переписать под influx, для линухи приколы сделать
|
@ -16,86 +16,88 @@ def run_prediction_module():
|
||||
FROM weather_data
|
||||
WHERE DateStamp >= '2024-10-14 21:00:00' - INTERVAL 36 HOUR;
|
||||
"""
|
||||
df = pd.read_sql(query, engine)
|
||||
df = pd.read_sql(query, engine) # Загружаем данные из SQL-запроса в DataFrame
|
||||
|
||||
df['DateStamp'] = pd.to_datetime(df['DateStamp'])
|
||||
df.set_index('DateStamp', inplace=True)
|
||||
df.sort_index(inplace=True)
|
||||
df['DateStamp'] = pd.to_datetime(df['DateStamp']) # Преобразуем столбец 'DateStamp' в формат datetime
|
||||
df.set_index('DateStamp', inplace=True) # Устанавливаем 'DateStamp' как индекс
|
||||
df.sort_index(inplace=True) # Сортируем DataFrame по индексу (по дате)
|
||||
|
||||
lags = 3
|
||||
shifted_dfs = [df]
|
||||
lags = 3 # Задаем количество временных сдвигов (лагов)
|
||||
shifted_dfs = [df] # Создаем список для хранения исходного DataFrame и его лаговых версий
|
||||
|
||||
for lag in range(1, lags + 1):
|
||||
shifted_df = df.shift(lag).add_suffix(f'_t-{lag}')
|
||||
shifted_dfs.append(shifted_df)
|
||||
shifted_df = df.shift(lag).add_suffix(f'_t-{lag}') # Создаем сдвинутый на lag строк DataFrame
|
||||
shifted_dfs.append(shifted_df) # Добавляем его в список
|
||||
|
||||
df_with_lags = pd.concat(shifted_dfs, axis=1)
|
||||
df_with_lags = pd.concat(shifted_dfs, axis=1) # Объединяем исходный DataFrame и все лаги по столбцам
|
||||
|
||||
df_with_lags.dropna(inplace=True)
|
||||
df_with_lags = df_with_lags.copy()
|
||||
df_with_lags.dropna(inplace=True) # Удаляем строки с пропущенными значениями
|
||||
df_with_lags = df_with_lags.copy() # Создаем копию DataFrame (для предотвращения предупреждений)
|
||||
|
||||
# Преобразуем BarTrend в числовой формат
|
||||
# Преобразуем столбец 'BarTrend' в числовой формат, используя кодировщик категорий
|
||||
le = LabelEncoder()
|
||||
df_with_lags['BarTrend_encoded'] = le.fit_transform(df_with_lags['BarTrend'])
|
||||
|
||||
# Выбор только числовых данных
|
||||
# Оставляем в DataFrame только числовые столбцы
|
||||
df_with_lags = df_with_lags.select_dtypes(include=['float64', 'int64'])
|
||||
|
||||
# Словари для хранения моделей и MSE
|
||||
# Создаем словари для хранения моделей и значений MSE
|
||||
models = {}
|
||||
mse_scores = {}
|
||||
|
||||
# Обучение моделей для каждого целевого столбца
|
||||
# Обучаем модели для каждого целевого столбца
|
||||
for target_column in df.columns:
|
||||
if target_column not in df_with_lags.columns:
|
||||
if target_column not in df_with_lags.columns: # Пропускаем, если столбец отсутствует в df_with_lags
|
||||
continue
|
||||
|
||||
X = df_with_lags.drop(columns=[target_column]).values
|
||||
y = df_with_lags[target_column].values
|
||||
X = df_with_lags.drop(columns=[target_column]).values # Признаки - все столбцы, кроме целевого
|
||||
y = df_with_lags[target_column].values # Целевой столбец
|
||||
|
||||
# Разделяем данные на обучающую и тестовую выборки без перемешивания (временной ряд)
|
||||
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
|
||||
|
||||
model = RandomForestRegressor()
|
||||
model.fit(X_train, y_train)
|
||||
model = RandomForestRegressor() # Инициализируем модель случайного леса
|
||||
model.fit(X_train, y_train) # Обучаем модель
|
||||
|
||||
y_pred = model.predict(X_test)
|
||||
mse = mean_squared_error(y_test, y_pred)
|
||||
mse_scores[target_column] = mse
|
||||
models[target_column] = model
|
||||
y_pred = model.predict(X_test) # Делаем предсказания на тестовой выборке
|
||||
mse = mean_squared_error(y_test, y_pred) # Вычисляем среднеквадратичную ошибку
|
||||
mse_scores[target_column] = mse # Сохраняем MSE для целевого столбца
|
||||
models[target_column] = model # Сохраняем модель для целевого столбца
|
||||
|
||||
quality = "хорошая" if mse < 1.0 else "плохая"
|
||||
print(f"MSE для {target_column}: {mse} ({quality})")
|
||||
quality = "хорошая" if mse < 1.0 else "плохая" # Определяем качество модели
|
||||
print(f"MSE для {target_column}: {mse} ({quality})") # Выводим MSE и качество
|
||||
|
||||
# Обучаем модель для BarTrend_encoded отдельно
|
||||
X_bartrend = df_with_lags.drop(columns=['BarTrend_encoded']).values
|
||||
y_bartrend = df_with_lags['BarTrend_encoded'].values
|
||||
# Обучаем модель для столбца 'BarTrend_encoded' отдельно
|
||||
X_bartrend = df_with_lags.drop(columns=['BarTrend_encoded']).values # Признаки
|
||||
y_bartrend = df_with_lags['BarTrend_encoded'].values # Целевой столбец 'BarTrend_encoded'
|
||||
|
||||
# Разделяем данные на обучающую и тестовую выборки без перемешивания
|
||||
X_train_bartrend, X_test_bartrend, y_train_bartrend, y_test_bartrend = train_test_split(X_bartrend, y_bartrend,
|
||||
test_size=0.2,
|
||||
shuffle=False)
|
||||
|
||||
model_bartrend = RandomForestRegressor()
|
||||
model_bartrend.fit(X_train_bartrend, y_train_bartrend)
|
||||
model_bartrend = RandomForestRegressor() # Инициализируем модель случайного леса
|
||||
model_bartrend.fit(X_train_bartrend, y_train_bartrend) # Обучаем модель
|
||||
|
||||
y_pred_bartrend = model_bartrend.predict(X_test_bartrend)
|
||||
mse_bartrend = mean_squared_error(y_test_bartrend, y_pred_bartrend)
|
||||
models['BarTrend_encoded'] = model_bartrend
|
||||
mse_scores['BarTrend_encoded'] = mse_bartrend
|
||||
y_pred_bartrend = model_bartrend.predict(X_test_bartrend) # Предсказания на тестовой выборке для 'BarTrend_encoded'
|
||||
mse_bartrend = mean_squared_error(y_test_bartrend, y_pred_bartrend) # Вычисляем MSE
|
||||
models['BarTrend_encoded'] = model_bartrend # Сохраняем модель для 'BarTrend_encoded'
|
||||
mse_scores['BarTrend_encoded'] = mse_bartrend # Сохраняем MSE для 'BarTrend_encoded'
|
||||
|
||||
quality_bartrend = "хорошая" if mse_bartrend < 1.0 else "плохая"
|
||||
print(f"MSE для BarTrend: {mse_bartrend} ({quality_bartrend})")
|
||||
quality_bartrend = "хорошая" if mse_bartrend < 1.0 else "плохая" # Определяем качество модели для 'BarTrend_encoded'
|
||||
print(f"MSE для BarTrend: {mse_bartrend} ({quality_bartrend})") # Выводим MSE и качество
|
||||
|
||||
last_data = X[-1].reshape(1, -1)
|
||||
last_data = X[-1].reshape(1, -1) # Берем последнюю строку данных и преобразуем в формат для предсказания
|
||||
|
||||
predictions = {}
|
||||
predictions = {} # Создаем словарь для хранения предсказаний
|
||||
for target_column, model in models.items():
|
||||
prediction = model.predict(last_data)[0]
|
||||
prediction = model.predict(last_data)[0] # Делаем предсказание для последней строки данных
|
||||
if target_column == 'BarTrend_encoded':
|
||||
prediction = le.inverse_transform([int(prediction)])[0]
|
||||
predictions['BarTrend'] = prediction
|
||||
print(f"Предсказание для BarTrend: {prediction}")
|
||||
break
|
||||
predictions[target_column] = prediction
|
||||
print(f"Предсказание для {target_column}: {prediction}")
|
||||
prediction = le.inverse_transform([int(prediction)])[0] # Декодируем категориальное значение
|
||||
predictions['BarTrend'] = prediction # Сохраняем предсказание для 'BarTrend'
|
||||
#print(f"Предсказание для BarTrend: {prediction}") # Выводим предсказание
|
||||
continue # Продолжаем цикл после предсказания для 'BarTrend_encoded'
|
||||
predictions[target_column] = prediction # Сохраняем предсказание для остальных столбцов
|
||||
#print(f"Предсказание для {target_column}: {prediction}") # Выводим предсказание для столбца
|
||||
|
||||
return predictions # Возвращаем словарь с предсказанными значениями и названиями столбцов
|
||||
|
Loading…
Reference in New Issue
Block a user