98 lines
4.1 KiB
Python
98 lines
4.1 KiB
Python
import pandas as pd
|
||
import numpy as np
|
||
from sqlalchemy import create_engine
|
||
from sklearn.model_selection import train_test_split
|
||
from sklearn.ensemble import RandomForestRegressor
|
||
from sklearn.metrics import mean_squared_error
|
||
|
||
# TODO
|
||
# 1.Добавить поля
|
||
# -barTrend - перечисление и правило какое-то (смотрим через один если повысилось после steady то rising если уменьшилось после steady то falling)
|
||
# -DateStamp - берется с последнего предсказанного + время опроса
|
||
# -SunRise - берется с последнего предсказанного
|
||
# -SunSet - берется с последнего предсказанного
|
||
#
|
||
# 12-10-2024 12:00
|
||
# 12-10-2024 12:01
|
||
#
|
||
# 2.Отделить вставку данных в бд от парсера данных с метеостанции
|
||
#
|
||
# 3.Возвращение результата в бд
|
||
|
||
# Настройка подключения к базе данных
|
||
|
||
|
||
DATABASE_URI = 'mysql+pymysql://wind:wind@193.124.203.110:3306/wind_towers' # Замените на вашу строку подключения
|
||
engine = create_engine(DATABASE_URI)
|
||
|
||
# Запрос данных из базы данных
|
||
query = """
|
||
SELECT CRC, DateStamp, DewPoint, HeatIndex, ETDay, HumIn, HumOut,
|
||
Pressure, RainDay, RainMonth, RainRate, RainStorm, RainYear,
|
||
TempIn, TempOut, WindDir, WindSpeed, WindSpeed10Min
|
||
FROM weather_data
|
||
WHERE DateStamp >= '2024-10-14 21:00:00' - INTERVAL 12 HOUR;
|
||
"""
|
||
df = pd.read_sql(query, engine)
|
||
|
||
# Преобразование даты и установка индекса
|
||
df['DateStamp'] = pd.to_datetime(df['DateStamp'])
|
||
df.set_index('DateStamp', inplace=True)
|
||
df.sort_index(inplace=True)
|
||
|
||
# Создание временных признаков с использованием pd.concat для минимизации фрагментации
|
||
lags = 3
|
||
shifted_dfs = [df] # Начинаем с оригинальных данных
|
||
|
||
# Создаем лаговые признаки
|
||
for lag in range(1, lags + 1):
|
||
shifted_df = df.shift(lag).add_suffix(f'_t-{lag}')
|
||
shifted_dfs.append(shifted_df)
|
||
|
||
# Объединяем все данные вместе, избегая фрагментации
|
||
df_with_lags = pd.concat(shifted_dfs, axis=1)
|
||
|
||
# Удаляем строки с NaN значениями
|
||
df_with_lags.dropna(inplace=True)
|
||
df_with_lags = df_with_lags.copy() # Устраняем фрагментацию
|
||
|
||
# Исключаем все нечисловые столбцы
|
||
df_with_lags = df_with_lags.select_dtypes(include=['float64', 'int64'])
|
||
|
||
# Словарь для хранения моделей и оценок
|
||
models = {}
|
||
mse_scores = {}
|
||
|
||
# Обучение модели для каждого целевого поля
|
||
for target_column in df.columns[:22]: # Ограничиваем до 22 полей
|
||
if target_column not in df_with_lags.columns:
|
||
continue # Пропускаем, если колонка отсутствует в данных с лагами
|
||
|
||
X = df_with_lags.drop(columns=[target_column])
|
||
y = df_with_lags[target_column]
|
||
|
||
# Разделение на обучающую и тестовую выборки
|
||
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)
|
||
|
||
# Оценка модели
|
||
y_pred = model.predict(X_test)
|
||
mse = mean_squared_error(y_test, y_pred)
|
||
mse_scores[target_column] = mse
|
||
models[target_column] = model
|
||
|
||
print(f"MSE для {target_column}: {mse}")
|
||
|
||
# Предсказание для следующего шага по всем моделям
|
||
predictions = {}
|
||
last_data = X.iloc[-1].values.reshape(1, -1) # Последняя строка данных для прогноза
|
||
|
||
for target_column, model in models.items():
|
||
predictions[target_column] = model.predict(last_data)[0]
|
||
print(f"Предсказание для {target_column}: {predictions[target_column]}")
|
||
print(predictions)
|
||
|