weather_forecasting_tutorial / pages /3_Training the Model.py
Shafeek Saleem
ss
92e31e2
raw
history blame
6.48 kB
import time
from utils.levels import complete_level, render_page, initialize_level
from utils.login import get_login, initialize_login
import streamlit as st
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import RandomizedSearchCV
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import RendererAgg
_lock = RendererAgg.lock
import base64
from io import BytesIO
from PIL import Image, ImageFilter
import lightgbm as lgb
initialize_login()
initialize_level()
LEVEL = 3
File_PATH = 'datasets/Building_forcasting.csv'
def process_file(csv_file):
data = pd.read_csv(csv_file, index_col='Timestamp')
data.index = pd.to_datetime(data.index)
data = data.fillna(0)
return data
def model_predict(data, model_choice, train_size, tune_model):
if model_choice == 'LightGBM':
model = lgb.LGBMRegressor() if not tune_model else lgb.LGBMRegressor(**tuned_parameters('lgbm'))
elif model_choice == 'Random Forest':
model = RandomForestRegressor(n_estimators=100, random_state=42) if not tune_model else RandomForestRegressor(**tuned_parameters('rf'))
X, y = create_model_inputs(data, 288, 288)
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=train_size/100, random_state=42, shuffle=False)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
return y_test, y_pred, model
def create_model_inputs(data, lag, mean_period):
df_processed = data.copy()
df_processed['PV_Output_lag'] = df_processed['PV_Output'].shift(lag)
df_processed['PV_Output_mean'] = df_processed['PV_Output'].rolling(window=mean_period).mean()
X = df_processed[['Solar_Irradiance', 'Temperature', 'Rain_Fall', 'Wind_speed', 'PV_Output_lag', 'PV_Output_mean']].dropna()
y = df_processed[['PV_Output']].loc[X.index]
return X, y
def show_output(y_test, y_pred):
st.sidebar.subheader("Model Performance")
st.sidebar.write(f"Test R2 score: {r2_score(y_test, y_pred):.2f}")
fig, axs = plt.subplots(3, figsize=(12, 18))
axs[0].plot(y_test.index, y_pred/1000, label='Predicted')
axs[0].plot(y_test.index, y_test['PV_Output']/1000, label='Actual')
axs[0].legend()
axs[0].set_title('Prediction vs Actual (Solar Power Generation)')
axs[0].set_xlabel('Date')
axs[0].set_ylabel('Solar Power Generation (kW)')
axs[1].plot(y_test.index, y_pred/1000, label='Predicted')
axs[1].set_title('Predicted Solar Power Generation')
axs[1].set_xlabel('Date')
axs[1].set_ylabel('Solar Power Generation (kW)')
axs[2].plot(y_test.index, y_test['PV_Output']/1000, label='Actual')
axs[2].set_title('Actual Solar Power Generation')
axs[2].set_xlabel('Date')
axs[2].set_ylabel('Solar Power Generation (kW)')
fig.tight_layout()
with _lock:
st.pyplot(fig)
return fig
def download_link(y_test, y_pred):
y_pred_df = pd.DataFrame({'Timestamp': y_test.index, 'Predicted_Power': y_pred, 'Actual_Total_Power_(kW)': y_test['PV_Output']})
csv = y_pred_df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode()
href = f'<a href="data:file/csv;base64,{b64}" download="Predicted_Solar_Power.csv">Download Predicted Power CSV File</a>'
st.sidebar.markdown(href, unsafe_allow_html=True)
def feature_importance_plot(model, feature_names):
# Get feature importances
importance = model.feature_importances_
# Normalize by the sum of all importances
importance = 100.0 * (importance / importance.sum())
plt.figure(figsize=(10, 6))
plt.bar(feature_names, importance)
plt.title('Feature Importance')
plt.xlabel('Features')
plt.ylabel('Importance (%)')
return plt.gcf()
def download_plot(fig):
tmpfile = BytesIO()
fig.savefig(tmpfile, format='png')
encoded = base64.b64encode(tmpfile.getvalue()).decode('utf-8')
href = f'<a href="data:image/png;base64,{encoded}" download="plot.png">Download Result Plot</a>'
st.sidebar.markdown(href, unsafe_allow_html=True)
def tuned_parameters(model):
if model == 'lgbm':
params = {
'num_leaves': [10, 20, 30, 40, 50],
'max_depth': [-1, 3, 5, 10],
'learning_rate': [0.01, 0.05, 0.1],
'n_estimators': [100, 500, 1000]
}
return params
elif model == 'rf':
params = {
'n_estimators': [10, 100, 500, 1000],
'max_depth': [None, 10, 20, 30, 40, 50],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
return params
def step3_page():
st.header("Training the Model")
st.subheader("Exploring the data")
st.title("Solar Forecasting App")
# Display the image and information in a grid layout
col1 = st.columns([1])
with col1[0]:
data = {
'Timestamp': ['11/1/2022 0:20', '11/1/2022 0:25'],
'Total_Power (kW)': [37337, 44590],
'PV_Output': [296.6, 298.4],
'Solar_Irradiance': [0, 0],
'Temperature': [25.1, 24.7],
'Rain_Fall': [42.6, 42.6],
'Wind_Speed': [0.6, 0.4]
}
df = pd.DataFrame(data)
st.subheader("Example of CSV file DataFrame")
st.table(df)
csv_file = st.sidebar.file_uploader("Upload CSV", type=['csv'])
if csv_file is not None:
data = process_file(csv_file)
train_size = st.sidebar.slider("Select Train Dataset Size (%)", min_value=10, max_value=90, value=70)
models = ['LightGBM', 'Random Forest']
model_choice = st.sidebar.selectbox('Choose Model', models)
tune_model = st.sidebar.checkbox('Tune Hyperparameters')
y_test, y_pred, model = model_predict(data, model_choice, train_size, tune_model)
# Display feature importance
if st.sidebar.checkbox('Show feature importance'):
feature_names = ['Solar_Irradiance', 'Temperature', 'Rain_Fall', 'Wind_speed', 'PV_Output_lag',
'PV_Output_mean']
fig = feature_importance_plot(model, feature_names)
with _lock:
st.pyplot(fig)
fig = show_output(y_test, y_pred)
download_link(y_test, y_pred)
download_plot(fig)
if st.button("Complete"):
complete_level(LEVEL)
render_page(step3_page, LEVEL)