initial commit
This commit is contained in:
186
voorspel.py
Normal file
186
voorspel.py
Normal file
@@ -0,0 +1,186 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import xgboost as xgb
|
||||
import mysql.connector
|
||||
from mysql.connector import Error
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
# --- CONFIGURATIE ---
|
||||
MODEL_FILE = 'price_forecast_model.json'
|
||||
TARGET = 'gemiddelde_prijs'
|
||||
AANTAL_UUR_VOORSPELLEN = 120 # Hoeveel uur vooruit wil je kijken?
|
||||
pd.set_option('display.max_rows', None) # Forceert pandas om ALLE rijen te printen
|
||||
|
||||
|
||||
# --- MySQL Database Config ---
|
||||
# VUL DIT IN MET JOUW GEGEVENS
|
||||
DB_CONFIG = {
|
||||
'host': '192.168.178.201',
|
||||
'user': 'energy_prices_user',
|
||||
'password': 'kS9R*xp17ZwCD@CV&E^N',
|
||||
'database': 'energy_prices',
|
||||
'port': 3307
|
||||
}
|
||||
|
||||
# Dit zijn de 16 features die het model MOET hebben
|
||||
FEATURES = [
|
||||
'temperatuur', 'gevoelstemperatuur', 'neerslag', 'wind_richting',
|
||||
'wind_snelheid', 'bewolking', 'luchtdruk', 'luchtvochtigheid',
|
||||
'uur_van_de_dag', 'dag_van_de_week', 'maand', 'dag_van_het_jaar',
|
||||
'prijs_1u_geleden', 'prijs_24u_geleden', 'temp_avg_3u', 'prijs_avg_6u'
|
||||
]
|
||||
|
||||
print("="*70)
|
||||
print("PRIJS VOORSPELLER (op basis van data uit MySQL)")
|
||||
print("="*70)
|
||||
|
||||
def haal_data_uit_database(conn):
|
||||
"""
|
||||
Haalt alle benodigde data op:
|
||||
1. Historie (afgelopen 30 uur, weer + prijs)
|
||||
2. Toekomst (komende 24 uur, alleen weer)
|
||||
"""
|
||||
print("💾 Data ophalen uit MySQL...")
|
||||
|
||||
# 1. Haal recente HISTORIE op (weer + prijs)
|
||||
# We hebben de prijs-tabel (dynamic_price_data) nodig
|
||||
query_hist = """
|
||||
SELECT
|
||||
w.datum_tijd, w.temperatuur, w.gevoelstemperatuur, w.neerslag,
|
||||
w.wind_richting, w.wind_snelheid, w.bewolking, w.luchtdruk, w.luchtvochtigheid,
|
||||
p_avg.gemiddelde_prijs
|
||||
FROM
|
||||
amersfoort_weer_uurlijks AS w
|
||||
JOIN
|
||||
(SELECT datetime, AVG(price) AS gemiddelde_prijs
|
||||
FROM dynamic_price_data GROUP BY datetime) AS p_avg
|
||||
ON w.datum_tijd = p_avg.datetime
|
||||
WHERE
|
||||
w.datum_tijd BETWEEN (NOW() - INTERVAL 30 HOUR) AND NOW()
|
||||
ORDER BY
|
||||
w.datum_tijd;
|
||||
"""
|
||||
|
||||
# 2. Haal TOEKOMSTIG weer op (alleen weer, prijs is NULL)
|
||||
query_toekomst = f"""
|
||||
SELECT
|
||||
datum_tijd, temperatuur, gevoelstemperatuur, neerslag,
|
||||
wind_richting, wind_snelheid, bewolking, luchtdruk, luchtvochtigheid,
|
||||
NULL AS gemiddelde_prijs -- Prijs is nog niet bekend
|
||||
FROM
|
||||
amersfoort_weer_uurlijks
|
||||
WHERE
|
||||
datum_tijd BETWEEN NOW() AND (NOW() + INTERVAL {AANTAL_UUR_VOORSPELLEN} HOUR)
|
||||
ORDER BY
|
||||
datum_tijd;
|
||||
"""
|
||||
|
||||
try:
|
||||
hist_df = pd.read_sql(query_hist, conn, index_col='datum_tijd', parse_dates=['datum_tijd'])
|
||||
toekomst_df = pd.read_sql(query_toekomst, conn, index_col='datum_tijd', parse_dates=['datum_tijd'])
|
||||
|
||||
print(f"✅ {len(hist_df)} uur historie geladen.")
|
||||
print(f"✅ {len(toekomst_df)} uur toekomstig weer geladen.")
|
||||
|
||||
# 3. Combineer ze tot één 'werkblad'
|
||||
combined_df = pd.concat([hist_df, toekomst_df])
|
||||
return combined_df.sort_index()
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Fout bij ophalen data: {e}")
|
||||
return None
|
||||
|
||||
def maak_features_voor_uur(df, timestamp):
|
||||
"""
|
||||
Maak de 16 features voor één specifiek uur.
|
||||
Hiervoor zijn de *vorige* rijen in de DataFrame nodig.
|
||||
"""
|
||||
features = {}
|
||||
|
||||
# Haal data op van het specifieke uur
|
||||
data_nu = df.loc[timestamp]
|
||||
|
||||
# 1. Tijd-features
|
||||
features['uur_van_de_dag'] = timestamp.hour
|
||||
features['dag_van_de_week'] = timestamp.dayofweek
|
||||
features['maand'] = timestamp.month
|
||||
features['dag_van_het_jaar'] = timestamp.dayofyear
|
||||
|
||||
# 2. Weer-features (direct uit de data)
|
||||
weer_cols = ['temperatuur', 'gevoelstemperatuur', 'neerslag', 'wind_richting',
|
||||
'wind_snelheid', 'bewolking', 'luchtdruk', 'luchtvochtigheid']
|
||||
for col in weer_cols:
|
||||
features[col] = data_nu[col]
|
||||
|
||||
# 3. Lag-features (van vorige uren)
|
||||
features['prijs_1u_geleden'] = df.loc[timestamp - timedelta(hours=1)]['gemiddelde_prijs']
|
||||
features['prijs_24u_geleden'] = df.loc[timestamp - timedelta(hours=24)]['gemiddelde_prijs']
|
||||
|
||||
# 4. Rolling-features (gemiddelden van vorige uren)
|
||||
features['temp_avg_3u'] = df.loc[timestamp - timedelta(hours=2) : timestamp]['temperatuur'].mean()
|
||||
features['prijs_avg_6u'] = df.loc[timestamp - timedelta(hours=5) : timestamp]['gemiddelde_prijs'].mean()
|
||||
|
||||
# Converteer naar een DataFrame met de juiste kolomvolgorde
|
||||
return pd.DataFrame([features], columns=FEATURES)
|
||||
|
||||
|
||||
# --- START VAN HET SCRIPT ---
|
||||
try:
|
||||
# 1. Laad het getrainde model
|
||||
print(f"Laden van model: {MODEL_FILE}...")
|
||||
model = xgb.XGBRegressor()
|
||||
model.load_model(MODEL_FILE)
|
||||
print("✅ Model succesvol geladen.")
|
||||
|
||||
# 2. Maak verbinding met de database
|
||||
conn = mysql.connector.connect(**DB_CONFIG)
|
||||
|
||||
# 3. Haal alle data op (historie + toekomstig weer)
|
||||
werk_df = haal_data_uit_database(conn)
|
||||
|
||||
if werk_df is not None:
|
||||
# 4. Zoek de uren die we moeten voorspellen
|
||||
# (Dit zijn de uren waar 'gemiddelde_prijs' NULL is)
|
||||
te_voorspellen_tijden = werk_df[werk_df['gemiddelde_prijs'].isnull()].index
|
||||
|
||||
print(f"\n🧠 Start iteratieve voorspelling voor {len(te_voorspellen_tijden)} uur...")
|
||||
|
||||
voorspellingen = []
|
||||
|
||||
# 5. De Voed-Terug-Lus
|
||||
for timestamp in te_voorspellen_tijden:
|
||||
# a. Maak features voor dit uur (gebruikt data van vorige uren)
|
||||
features_nu = maak_features_voor_uur(werk_df, timestamp)
|
||||
|
||||
# b. Maak de voorspelling
|
||||
voorspelde_prijs = model.predict(features_nu)[0]
|
||||
|
||||
# c. VOED TERUG: Sla de voorspelling op in het 'werkblad'
|
||||
# zodat het volgende uur deze kan gebruiken!
|
||||
werk_df.loc[timestamp, 'gemiddelde_prijs'] = voorspelde_prijs
|
||||
|
||||
# d. Sla op voor het eindresultaat
|
||||
voorspellingen.append(voorspelde_prijs)
|
||||
|
||||
# 6. Toon de resultaten
|
||||
print("\n" + "="*70)
|
||||
print(f"--- VOORSPELDE PRIJZEN (komende {len(te_voorspellen_tijden)} uur) ---")
|
||||
|
||||
resultaat_df = pd.DataFrame({
|
||||
'Voorspelde_Prijs': voorspellingen
|
||||
}, index=te_voorspellen_tijden)
|
||||
|
||||
print(resultaat_df)
|
||||
print("="*70)
|
||||
|
||||
except Error as e:
|
||||
print(f"❌ Fout met MySQL verbinding: {e}")
|
||||
except FileNotFoundError:
|
||||
print(f"❌ Fout: Model bestand '{MODEL_FILE}' niet gevonden.")
|
||||
except Exception as e:
|
||||
print(f"❌ Een onverwachte fout is opgetreden: {e}")
|
||||
finally:
|
||||
if 'conn' in locals() and conn.is_connected():
|
||||
conn.close()
|
||||
print("\nVerbinding met MySQL gesloten.")
|
||||
Reference in New Issue
Block a user