Spaces:
Sleeping
Sleeping
Upload 9 files
Browse files- app.py +30 -0
- pages/__pycache__/home.cpython-312.pyc +0 -0
- pages/about.py +25 -0
- pages/github.py +12 -0
- pages/home.py +492 -0
- pages/linear_regression.py +65 -0
- pages/lstm.py +90 -0
- pages/random_forest.py +68 -0
- pages/xgboost.py +61 -0
app.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
# Set Streamlit page configuration
|
| 4 |
+
st.set_page_config(page_title="Solar Forecast", layout="wide")
|
| 5 |
+
|
| 6 |
+
st.sidebar.title("🔍 Navigation")
|
| 7 |
+
page = st.sidebar.radio("Go to", ["Home", "LSTM Model", "XGBoost Model", "Random Forest", "Linear Regression", "GitHub", "About"])
|
| 8 |
+
|
| 9 |
+
# Redirect to the selected page
|
| 10 |
+
if page == "Home":
|
| 11 |
+
from pages import home
|
| 12 |
+
home.show()
|
| 13 |
+
elif page == "LSTM Model":
|
| 14 |
+
from pages import lstm
|
| 15 |
+
lstm.show()
|
| 16 |
+
elif page == "XGBoost Model":
|
| 17 |
+
from pages import xgboost
|
| 18 |
+
xgboost.show()
|
| 19 |
+
elif page == "Random Forest":
|
| 20 |
+
from pages import random_forest
|
| 21 |
+
random_forest.show()
|
| 22 |
+
elif page == "Linear Regression":
|
| 23 |
+
from pages import linear_regression
|
| 24 |
+
linear_regression.show()
|
| 25 |
+
elif page == "GitHub":
|
| 26 |
+
from pages import github
|
| 27 |
+
github.show()
|
| 28 |
+
elif page == "About":
|
| 29 |
+
from pages import about
|
| 30 |
+
about.show()
|
pages/__pycache__/home.cpython-312.pyc
ADDED
|
Binary file (19.2 kB). View file
|
|
|
pages/about.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
st.title("ℹ About This Project")
|
| 4 |
+
|
| 5 |
+
st.write("""
|
| 6 |
+
This application is designed for **solar power prediction** using multiple machine learning models.
|
| 7 |
+
The models included in this app are:
|
| 8 |
+
- 🔮 **LSTM (Long Short-Term Memory)**
|
| 9 |
+
- 🚀 **XGBoost**
|
| 10 |
+
- 🌳 **Random Forest**
|
| 11 |
+
- 📉 **Linear Regression**
|
| 12 |
+
|
| 13 |
+
### 🚀 Features:
|
| 14 |
+
✅ Upload and process CSV data
|
| 15 |
+
✅ Interactive navigation menu
|
| 16 |
+
✅ Adjustable model parameters
|
| 17 |
+
✅ Progress bar and logs during training
|
| 18 |
+
|
| 19 |
+
### 👨💻 Developer:
|
| 20 |
+
- **Your Name**
|
| 21 |
+
- [GitHub Profile](https://github.com/Sivatech24)
|
| 22 |
+
- [LinkedIn Profile](#) (Add your actual LinkedIn link)
|
| 23 |
+
|
| 24 |
+
Thank you for using this app! 🎉
|
| 25 |
+
""")
|
pages/github.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
st.title("🔗 GitHub Repository")
|
| 4 |
+
|
| 5 |
+
st.write("You can find the complete source code for this project on GitHub.")
|
| 6 |
+
|
| 7 |
+
# Replace with your actual GitHub link
|
| 8 |
+
github_url = "https://github.com/Sivatech24/Streamlit"
|
| 9 |
+
|
| 10 |
+
st.markdown(f"[📂 View Repository]({github_url})")
|
| 11 |
+
|
| 12 |
+
st.write("If you like this project, consider giving it a ⭐ on GitHub!")
|
pages/home.py
ADDED
|
@@ -0,0 +1,492 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import matplotlib.pyplot as plt
|
| 4 |
+
# from statsmodels.tsa.arima.model import ARIMA
|
| 5 |
+
# from statsmodels.tsa.stattools import adfuller
|
| 6 |
+
# from statsmodels.tsa.statespace.sarimax import SARIMAX
|
| 7 |
+
# from sklearn.model_selection import train_test_split
|
| 8 |
+
import matplotlib.image as mpimg
|
| 9 |
+
import seaborn as sns
|
| 10 |
+
import warnings
|
| 11 |
+
import datetime as dt
|
| 12 |
+
from sklearn.metrics import confusion_matrix
|
| 13 |
+
import matplotlib.dates as mdates
|
| 14 |
+
from pandas.tseries.offsets import DateOffset
|
| 15 |
+
import streamlit as st
|
| 16 |
+
# from pmdarima.arima import auto_arima
|
| 17 |
+
# from statsmodels.tsa.stattools import adfuller
|
| 18 |
+
# import streamlit as st
|
| 19 |
+
# import pandas as pd
|
| 20 |
+
# import matplotlib.pyplot as plt
|
| 21 |
+
# from statsmodels.tsa.stattools import adfuller
|
| 22 |
+
# from pmdarima import auto_arima
|
| 23 |
+
# from pandas.tseries.offsets import DateOffset
|
| 24 |
+
# from prophet import Prophet
|
| 25 |
+
warnings.filterwarnings('ignore')
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
# header
|
| 29 |
+
import streamlit as st
|
| 30 |
+
import numpy as np
|
| 31 |
+
import pandas as pd
|
| 32 |
+
import matplotlib.pyplot as plt
|
| 33 |
+
import xgboost as xgb
|
| 34 |
+
from sklearn.model_selection import train_test_split
|
| 35 |
+
from sklearn.preprocessing import MinMaxScaler
|
| 36 |
+
from tensorflow.keras.models import Sequential
|
| 37 |
+
from tensorflow.keras.layers import LSTM, Dense
|
| 38 |
+
from sklearn.ensemble import RandomForestRegressor
|
| 39 |
+
from sklearn.linear_model import LinearRegression
|
| 40 |
+
|
| 41 |
+
# --- Sidebar Navigation ---
|
| 42 |
+
# st.sidebar.title("📌 Navigation")
|
| 43 |
+
# st.sidebar.page_link("app.py", label="🏠 Home", icon="🏠")
|
| 44 |
+
# st.sidebar.page_link("pages/lstm.py", label="🔮 LSTM", icon="📈")
|
| 45 |
+
# st.sidebar.page_link("pages/xgboost.py", label="🚀 XGBoost", icon="📊")
|
| 46 |
+
# st.sidebar.page_link("pages/random_forest.py", label="🌳 Random Forest", icon="🌲")
|
| 47 |
+
# st.sidebar.page_link("pages/linear_regression.py", label="📉 Linear Regression", icon="📏")
|
| 48 |
+
# st.sidebar.page_link("pages/github.py", label="🔗 GitHub", icon="🔗")
|
| 49 |
+
# st.sidebar.page_link("pages/about.py", label="ℹ About", icon="ℹ️")
|
| 50 |
+
|
| 51 |
+
"""# Load Generation Data (Plant 1)"""
|
| 52 |
+
|
| 53 |
+
from sklearn.model_selection import train_test_split
|
| 54 |
+
import warnings
|
| 55 |
+
warnings.filterwarnings('ignore')
|
| 56 |
+
|
| 57 |
+
st.title("Solar Plant Data Analysis and Forecasting")
|
| 58 |
+
|
| 59 |
+
# File Upload
|
| 60 |
+
uploaded_gen = st.file_uploader("Upload Generation Data CSV", type=["csv"], key="gen")
|
| 61 |
+
uploaded_weather = st.file_uploader("Upload Weather Sensor Data CSV", type=["csv"], key="weather")
|
| 62 |
+
|
| 63 |
+
def load_data(file):
|
| 64 |
+
if file is not None:
|
| 65 |
+
return pd.read_csv(file)
|
| 66 |
+
return None
|
| 67 |
+
|
| 68 |
+
# Load Data
|
| 69 |
+
gen_data = load_data(uploaded_gen)
|
| 70 |
+
weather_data = load_data(uploaded_weather)
|
| 71 |
+
|
| 72 |
+
default_gen_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Generation_Data.csv')
|
| 73 |
+
default_weather_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Weather_Sensor_Data.csv')
|
| 74 |
+
|
| 75 |
+
if gen_data is None:
|
| 76 |
+
gen_data = default_gen_data
|
| 77 |
+
gen_1 = default_gen_data
|
| 78 |
+
if weather_data is None:
|
| 79 |
+
weather_data = default_weather_data
|
| 80 |
+
sens_1 = default_weather_data
|
| 81 |
+
|
| 82 |
+
# Data Preview
|
| 83 |
+
st.subheader("Generation Data Preview Head")
|
| 84 |
+
st.dataframe(gen_data.head())
|
| 85 |
+
|
| 86 |
+
st.subheader("Weather Data Preview Head")
|
| 87 |
+
st.dataframe(weather_data.head())
|
| 88 |
+
|
| 89 |
+
st.subheader("Generation Data Preview Tail")
|
| 90 |
+
st.dataframe(gen_data.tail())
|
| 91 |
+
|
| 92 |
+
st.subheader("Weather Data Preview Tail")
|
| 93 |
+
st.dataframe(weather_data.tail())
|
| 94 |
+
|
| 95 |
+
st.subheader("Generation Data Describe")
|
| 96 |
+
st.dataframe(gen_data.describe())
|
| 97 |
+
|
| 98 |
+
st.subheader("Weather Data Describe")
|
| 99 |
+
st.dataframe(weather_data.describe())
|
| 100 |
+
|
| 101 |
+
# Filter out non-numeric columns
|
| 102 |
+
numeric_data = gen_1.select_dtypes(include=['float64', 'int64'])
|
| 103 |
+
|
| 104 |
+
# Calculate the correlation matrix on the numeric data
|
| 105 |
+
corelation = numeric_data.corr()
|
| 106 |
+
|
| 107 |
+
# Plot the heatmap
|
| 108 |
+
fig, ax = plt.subplots(figsize=(14, 12))
|
| 109 |
+
sns.heatmap(corelation, annot=True, ax=ax)
|
| 110 |
+
st.subheader("Generation Data HeatMap")
|
| 111 |
+
st.pyplot(fig)
|
| 112 |
+
|
| 113 |
+
# Filter out non-numeric columns
|
| 114 |
+
numeric_data = sens_1.select_dtypes(include=['float64', 'int64'])
|
| 115 |
+
|
| 116 |
+
# Calculate the correlation matrix on the numeric data
|
| 117 |
+
corelation = numeric_data.corr()
|
| 118 |
+
|
| 119 |
+
# Plot the heatmap
|
| 120 |
+
fig, ax = plt.subplots(figsize=(14, 12))
|
| 121 |
+
sns.heatmap(corelation, annot=True, ax=ax)
|
| 122 |
+
st.subheader("Weather Data HeatMap")
|
| 123 |
+
st.pyplot(fig)
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
st.subheader("Datetime Conversion and Resampling")
|
| 129 |
+
|
| 130 |
+
# Convert DATE_TIME column to datetime format
|
| 131 |
+
gen_data['DATE_TIME'] = pd.to_datetime(gen_data['DATE_TIME'], format='%d-%m-%Y %H:%M')
|
| 132 |
+
weather_data['DATE_TIME'] = pd.to_datetime(weather_data['DATE_TIME'], format='%Y-%m-%d %H:%M:%S')
|
| 133 |
+
gen_1['DATE_TIME'] = pd.to_datetime(gen_1['DATE_TIME'], format='%d-%m-%Y %H:%M')
|
| 134 |
+
sens_1['DATE_TIME'] = pd.to_datetime(sens_1['DATE_TIME'], format='%Y-%m-%d %H:%M:%S')
|
| 135 |
+
|
| 136 |
+
# Resample generation data daily
|
| 137 |
+
gen_data_daily = gen_data.set_index('DATE_TIME').resample('D').sum().reset_index()
|
| 138 |
+
|
| 139 |
+
# Display processed data
|
| 140 |
+
st.subheader("Daily Aggregated Generation Data")
|
| 141 |
+
st.dataframe(gen_data_daily.head())
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
st.subheader("Daily Yield and Power Analysis")
|
| 147 |
+
|
| 148 |
+
# Group by DATE_TIME and sum values
|
| 149 |
+
df_gen = gen_1.groupby('DATE_TIME').sum().reset_index()
|
| 150 |
+
df_gen['time'] = df_gen['DATE_TIME'].dt.time
|
| 151 |
+
|
| 152 |
+
# Create subplots
|
| 153 |
+
fig, ax = plt.subplots(ncols=2, nrows=1, dpi=100, figsize=(20, 5))
|
| 154 |
+
|
| 155 |
+
# Daily yield plot
|
| 156 |
+
df_gen.plot(x='DATE_TIME', y='DAILY_YIELD', color='navy', ax=ax[0])
|
| 157 |
+
ax[0].set_title('Daily Yield')
|
| 158 |
+
ax[0].set_ylabel('kW', color='navy', fontsize=17)
|
| 159 |
+
|
| 160 |
+
# AC & DC power plot
|
| 161 |
+
df_gen.set_index('time').drop('DATE_TIME', axis=1)[['AC_POWER', 'DC_POWER']].plot(style='o', ax=ax[1])
|
| 162 |
+
ax[1].set_title('AC Power & DC Power During Day Hours')
|
| 163 |
+
|
| 164 |
+
# Display the plots in Streamlit
|
| 165 |
+
st.pyplot(fig)
|
| 166 |
+
|
| 167 |
+
st.subheader("Generation Data Analysis")
|
| 168 |
+
|
| 169 |
+
# Create subplots
|
| 170 |
+
fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(15, 10))
|
| 171 |
+
|
| 172 |
+
# Plot Daily and Total Yield
|
| 173 |
+
gen_data.plot(x='DATE_TIME', y=['DAILY_YIELD', 'TOTAL_YIELD'], ax=ax[0], title="Daily and Total Yield (Generation Data)")
|
| 174 |
+
|
| 175 |
+
# Plot AC Power & DC Power
|
| 176 |
+
gen_data.plot(x='DATE_TIME', y=['AC_POWER', 'DC_POWER'], ax=ax[1], title="AC Power & DC Power (Generation Data)")
|
| 177 |
+
|
| 178 |
+
# Display the plots in Streamlit
|
| 179 |
+
st.pyplot(fig)
|
| 180 |
+
|
| 181 |
+
st.subheader("Daily and Total Yield Analysis")
|
| 182 |
+
|
| 183 |
+
# Create a copy and extract the date
|
| 184 |
+
daily_gen = df_gen.copy()
|
| 185 |
+
daily_gen['date'] = daily_gen['DATE_TIME'].dt.date
|
| 186 |
+
|
| 187 |
+
# Group by 'date' and sum only the numerical columns
|
| 188 |
+
daily_gen = daily_gen.groupby('date').sum(numeric_only=True)
|
| 189 |
+
|
| 190 |
+
# Create subplots
|
| 191 |
+
fig, ax = plt.subplots(ncols=2, dpi=100, figsize=(20, 5))
|
| 192 |
+
|
| 193 |
+
# Plot Daily Yield
|
| 194 |
+
daily_gen['DAILY_YIELD'].plot(ax=ax[0], color='navy')
|
| 195 |
+
ax[0].set_title('Daily Yield')
|
| 196 |
+
ax[0].set_ylabel('kW', color='navy', fontsize=17)
|
| 197 |
+
|
| 198 |
+
# Plot Total Yield as a bar chart
|
| 199 |
+
daily_gen['TOTAL_YIELD'].plot(kind='bar', ax=ax[1], color='navy')
|
| 200 |
+
ax[1].set_title('Total Yield')
|
| 201 |
+
|
| 202 |
+
# Adjust x-axis labels
|
| 203 |
+
fig.autofmt_xdate(rotation=45)
|
| 204 |
+
|
| 205 |
+
# Display the plots in Streamlit
|
| 206 |
+
st.pyplot(fig)
|
| 207 |
+
|
| 208 |
+
st.subheader("Weather Sensor Data Analysis")
|
| 209 |
+
|
| 210 |
+
# Group by 'DATE_TIME' and sum
|
| 211 |
+
df_sens = sens_1.groupby('DATE_TIME').sum().reset_index()
|
| 212 |
+
df_sens['time'] = df_sens['DATE_TIME'].dt.time
|
| 213 |
+
|
| 214 |
+
# Create subplots
|
| 215 |
+
fig, ax = plt.subplots(ncols=2, nrows=1, dpi=100, figsize=(20, 5))
|
| 216 |
+
|
| 217 |
+
# Irradiation plot
|
| 218 |
+
df_sens.plot(x='time', y='IRRADIATION', ax=ax[0], style='o')
|
| 219 |
+
ax[0].set_title('Irradiation during day hours')
|
| 220 |
+
ax[0].set_ylabel('W/m²', color='navy', fontsize=17)
|
| 221 |
+
|
| 222 |
+
# Ambient and Module Temperature plot
|
| 223 |
+
df_sens.set_index('DATE_TIME').drop('time', axis=1)[['AMBIENT_TEMPERATURE', 'MODULE_TEMPERATURE']].plot(ax=ax[1])
|
| 224 |
+
ax[1].set_title('Ambient and Module Temperature')
|
| 225 |
+
ax[1].set_ylabel('°C', color='navy', fontsize=17)
|
| 226 |
+
|
| 227 |
+
# Display the plots in Streamlit
|
| 228 |
+
st.pyplot(fig)
|
| 229 |
+
|
| 230 |
+
st.subheader("DC to AC Power Conversion Efficiency")
|
| 231 |
+
|
| 232 |
+
# Create a copy of the data
|
| 233 |
+
loss = gen_1.copy()
|
| 234 |
+
|
| 235 |
+
# Create a new 'day' column containing only the date part from 'DATE_TIME'
|
| 236 |
+
loss['day'] = loss['DATE_TIME'].dt.date
|
| 237 |
+
|
| 238 |
+
# Drop the 'DATE_TIME' column to prevent summing over datetime values
|
| 239 |
+
loss = loss.drop(columns=['DATE_TIME'])
|
| 240 |
+
|
| 241 |
+
# Group by 'day' and sum only numeric columns
|
| 242 |
+
loss = loss.groupby('day').sum()
|
| 243 |
+
|
| 244 |
+
# Calculate the percentage of DC power converted to AC power
|
| 245 |
+
loss['losses'] = (loss['AC_POWER'] / loss['DC_POWER']) * 100
|
| 246 |
+
|
| 247 |
+
# Plot the losses
|
| 248 |
+
fig, ax = plt.subplots(figsize=(17, 5))
|
| 249 |
+
loss['losses'].plot(style='o--', ax=ax, label='Real Power')
|
| 250 |
+
|
| 251 |
+
# Plot styling
|
| 252 |
+
ax.set_title('% of DC Power Converted to AC Power', size=17)
|
| 253 |
+
ax.set_ylabel('DC Power Converted (%)', fontsize=14, color='red')
|
| 254 |
+
ax.axhline(loss['losses'].mean(), linestyle='--', color='gray', label='Mean')
|
| 255 |
+
ax.legend()
|
| 256 |
+
|
| 257 |
+
# Display the plot in Streamlit
|
| 258 |
+
st.pyplot(fig)
|
| 259 |
+
|
| 260 |
+
st.subheader("DC Power During the Day for All Sources")
|
| 261 |
+
|
| 262 |
+
# Create a copy of the data
|
| 263 |
+
sources = gen_1.copy()
|
| 264 |
+
sources['time'] = sources['DATE_TIME'].dt.time
|
| 265 |
+
|
| 266 |
+
# Create the plot
|
| 267 |
+
fig, ax = plt.subplots(figsize=(20, 10))
|
| 268 |
+
sources.set_index('time').groupby('SOURCE_KEY')['DC_POWER'].plot(style='o', ax=ax, legend=True)
|
| 269 |
+
|
| 270 |
+
# Plot styling
|
| 271 |
+
ax.set_title('DC Power During the Day for All Sources', size=17)
|
| 272 |
+
ax.set_ylabel('DC POWER (kW)', color='navy', fontsize=17)
|
| 273 |
+
|
| 274 |
+
# Display the plot in Streamlit
|
| 275 |
+
st.pyplot(fig)
|
| 276 |
+
|
| 277 |
+
st.subheader("DC Power Distribution Across Sources")
|
| 278 |
+
|
| 279 |
+
# Create a copy of the data
|
| 280 |
+
dc_gen = gen_1.copy()
|
| 281 |
+
dc_gen['time'] = dc_gen['DATE_TIME'].dt.time
|
| 282 |
+
|
| 283 |
+
# Group by 'time' and 'SOURCE_KEY', then calculate the mean
|
| 284 |
+
dc_gen = dc_gen.groupby(['time', 'SOURCE_KEY'])['DC_POWER'].mean().unstack()
|
| 285 |
+
|
| 286 |
+
# Define the color palette
|
| 287 |
+
cmap = sns.color_palette("Spectral", n_colors=12)
|
| 288 |
+
|
| 289 |
+
# Create subplots
|
| 290 |
+
fig, ax = plt.subplots(ncols=2, nrows=1, dpi=100, figsize=(20, 6))
|
| 291 |
+
|
| 292 |
+
# Plot the first 11 sources
|
| 293 |
+
dc_gen.iloc[:, 0:11].plot(ax=ax[0], color=cmap)
|
| 294 |
+
ax[0].set_title('First 11 Sources')
|
| 295 |
+
ax[0].set_ylabel('DC POWER (kW)', fontsize=17, color='navy')
|
| 296 |
+
|
| 297 |
+
# Plot the last 11 sources
|
| 298 |
+
dc_gen.iloc[:, 11:22].plot(ax=ax[1], color=cmap)
|
| 299 |
+
ax[1].set_title('Last 11 Sources')
|
| 300 |
+
|
| 301 |
+
# Display the plot in Streamlit
|
| 302 |
+
st.pyplot(fig)
|
| 303 |
+
|
| 304 |
+
st.subheader("Weather Data Analysis")
|
| 305 |
+
|
| 306 |
+
# Create subplots
|
| 307 |
+
fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(15, 10))
|
| 308 |
+
|
| 309 |
+
# Plot Irradiation
|
| 310 |
+
weather_data.plot(x='DATE_TIME', y='IRRADIATION', ax=ax[0], title="Irradiation (Weather Data)")
|
| 311 |
+
|
| 312 |
+
# Plot Ambient & Module Temperature
|
| 313 |
+
weather_data.plot(x='DATE_TIME', y=['AMBIENT_TEMPERATURE', 'MODULE_TEMPERATURE'], ax=ax[1], title="Ambient & Module Temperature (Weather Data)")
|
| 314 |
+
|
| 315 |
+
# Display the plot in Streamlit
|
| 316 |
+
st.pyplot(fig)
|
| 317 |
+
|
| 318 |
+
st.subheader("DC Power Converted with 2% Loss Assumption")
|
| 319 |
+
|
| 320 |
+
# Calculate DC power after conversion loss
|
| 321 |
+
gen_data['DC_POWER_CONVERTED'] = gen_data['DC_POWER'] * 0.98 # Assume 2% loss in conversion
|
| 322 |
+
|
| 323 |
+
# Create the plot
|
| 324 |
+
fig, ax = plt.subplots(figsize=(15, 5))
|
| 325 |
+
gen_data.plot(x='DATE_TIME', y='DC_POWER_CONVERTED', ax=ax, title="DC Power Converted")
|
| 326 |
+
|
| 327 |
+
# Display the plot in Streamlit
|
| 328 |
+
st.pyplot(fig)
|
| 329 |
+
|
| 330 |
+
st.subheader("DC Power Generated During Day Hours")
|
| 331 |
+
|
| 332 |
+
# Filter data for day hours (6 AM to 6 PM)
|
| 333 |
+
day_data_gen = gen_data[(gen_data['DATE_TIME'].dt.hour >= 6) & (gen_data['DATE_TIME'].dt.hour <= 18)]
|
| 334 |
+
|
| 335 |
+
# Create the plot
|
| 336 |
+
fig, ax = plt.subplots(figsize=(15, 5))
|
| 337 |
+
day_data_gen.plot(x='DATE_TIME', y='DC_POWER', ax=ax, title="DC Power Generated During Day Hours")
|
| 338 |
+
|
| 339 |
+
# Display the plot in Streamlit
|
| 340 |
+
st.pyplot(fig)
|
| 341 |
+
|
| 342 |
+
st.subheader("Prepare Data for Time-Based Analysis")
|
| 343 |
+
|
| 344 |
+
# Copy generation data and extract time and date
|
| 345 |
+
temp1_gen = gen_1.copy()
|
| 346 |
+
temp1_gen['time'] = temp1_gen['DATE_TIME'].dt.time
|
| 347 |
+
temp1_gen['day'] = temp1_gen['DATE_TIME'].dt.date
|
| 348 |
+
|
| 349 |
+
# Copy sensor data and extract time and date
|
| 350 |
+
temp1_sens = sens_1.copy()
|
| 351 |
+
temp1_sens['time'] = temp1_sens['DATE_TIME'].dt.time
|
| 352 |
+
temp1_sens['day'] = temp1_sens['DATE_TIME'].dt.date
|
| 353 |
+
|
| 354 |
+
# Compute mean DC power grouped by time and day
|
| 355 |
+
cols = temp1_gen.groupby(['time', 'day'])['DC_POWER'].mean().unstack()
|
| 356 |
+
|
| 357 |
+
st.write("Data prepared successfully!")
|
| 358 |
+
|
| 359 |
+
st.subheader("Time-Based DC Power and Daily Yield Analysis")
|
| 360 |
+
|
| 361 |
+
# Create subplots for DC_POWER and DAILY_YIELD
|
| 362 |
+
fig, ax = plt.subplots(nrows=17, ncols=2, sharex=True, figsize=(20, 30))
|
| 363 |
+
|
| 364 |
+
# Plot DC Power
|
| 365 |
+
dc_power_plot = temp1_gen.groupby(['time', 'day'])['DC_POWER'].mean().unstack().plot(
|
| 366 |
+
sharex=True, subplots=True, layout=(17, 2), figsize=(20, 30), ax=ax
|
| 367 |
+
)
|
| 368 |
+
|
| 369 |
+
# Plot Daily Yield
|
| 370 |
+
daily_yield_plot = temp1_gen.groupby(['time', 'day'])['DAILY_YIELD'].mean().unstack().plot(
|
| 371 |
+
sharex=True, subplots=True, layout=(17, 2), figsize=(20, 20), style='-.', ax=ax
|
| 372 |
+
)
|
| 373 |
+
|
| 374 |
+
# Add titles and legends
|
| 375 |
+
i = 0
|
| 376 |
+
for a in range(len(ax)):
|
| 377 |
+
for b in range(len(ax[a])):
|
| 378 |
+
ax[a, b].set_title(cols.columns[i], size=15)
|
| 379 |
+
ax[a, b].legend(['DC_POWER', 'DAILY_YIELD'])
|
| 380 |
+
i += 1
|
| 381 |
+
|
| 382 |
+
plt.tight_layout()
|
| 383 |
+
|
| 384 |
+
# Display the plot in Streamlit
|
| 385 |
+
st.pyplot(fig)
|
| 386 |
+
|
| 387 |
+
st.subheader("Temperature Analysis Over Time")
|
| 388 |
+
|
| 389 |
+
# Create subplots for MODULE_TEMPERATURE and AMBIENT_TEMPERATURE
|
| 390 |
+
fig, ax = plt.subplots(nrows=17, ncols=2, sharex=True, figsize=(20, 30))
|
| 391 |
+
|
| 392 |
+
# Plot Module Temperature
|
| 393 |
+
module_temp_plot = temp1_sens.groupby(['time', 'day'])['MODULE_TEMPERATURE'].mean().unstack().plot(
|
| 394 |
+
subplots=True, layout=(17, 2), figsize=(20, 30), ax=ax
|
| 395 |
+
)
|
| 396 |
+
|
| 397 |
+
# Plot Ambient Temperature
|
| 398 |
+
ambient_temp_plot = temp1_sens.groupby(['time', 'day'])['AMBIENT_TEMPERATURE'].mean().unstack().plot(
|
| 399 |
+
subplots=True, layout=(17, 2), figsize=(20, 40), style='-.', ax=ax
|
| 400 |
+
)
|
| 401 |
+
|
| 402 |
+
# Add titles, legends, and threshold line
|
| 403 |
+
i = 0
|
| 404 |
+
for a in range(len(ax)):
|
| 405 |
+
for b in range(len(ax[a])):
|
| 406 |
+
ax[a, b].axhline(50, color='r', linestyle='--', label='Threshold (50°C)')
|
| 407 |
+
ax[a, b].set_title(cols.columns[i], size=15)
|
| 408 |
+
ax[a, b].legend(['Module Temperature', 'Ambient Temperature', 'Threshold'])
|
| 409 |
+
i += 1
|
| 410 |
+
|
| 411 |
+
plt.tight_layout()
|
| 412 |
+
|
| 413 |
+
# Display the plot in Streamlit
|
| 414 |
+
st.pyplot(fig)
|
| 415 |
+
|
| 416 |
+
st.subheader("Worst Performing Source Analysis")
|
| 417 |
+
|
| 418 |
+
# Filter the worst-performing source
|
| 419 |
+
worst_source = gen_1[gen_1['SOURCE_KEY'] == 'bvBOhCH3iADSZry'].copy()
|
| 420 |
+
worst_source['time'] = worst_source['DATE_TIME'].dt.time
|
| 421 |
+
worst_source['day'] = worst_source['DATE_TIME'].dt.date
|
| 422 |
+
|
| 423 |
+
# Create subplots
|
| 424 |
+
fig, ax = plt.subplots(nrows=17, ncols=2, sharex=True, figsize=(20, 30))
|
| 425 |
+
|
| 426 |
+
# Plot DC Power for worst source
|
| 427 |
+
dc_power_plot = worst_source.groupby(['time', 'day'])['DC_POWER'].mean().unstack().plot(
|
| 428 |
+
subplots=True, layout=(17, 2), figsize=(20, 30), ax=ax
|
| 429 |
+
)
|
| 430 |
+
|
| 431 |
+
# Plot Daily Yield for worst source
|
| 432 |
+
daily_yield_plot = worst_source.groupby(['time', 'day'])['DAILY_YIELD'].mean().unstack().plot(
|
| 433 |
+
subplots=True, layout=(17, 2), figsize=(20, 30), ax=ax, style='-.'
|
| 434 |
+
)
|
| 435 |
+
|
| 436 |
+
# Add titles and legends
|
| 437 |
+
i = 0
|
| 438 |
+
for a in range(len(ax)):
|
| 439 |
+
for b in range(len(ax[a])):
|
| 440 |
+
ax[a, b].set_title(cols.columns[i], size=15)
|
| 441 |
+
ax[a, b].legend(['DC_POWER', 'DAILY_YIELD'])
|
| 442 |
+
i += 1
|
| 443 |
+
|
| 444 |
+
plt.tight_layout()
|
| 445 |
+
|
| 446 |
+
# Display the plot in Streamlit
|
| 447 |
+
st.pyplot(fig)
|
| 448 |
+
|
| 449 |
+
st.subheader("Inverter Performance Analysis")
|
| 450 |
+
|
| 451 |
+
# Calculate average DC power for each inverter
|
| 452 |
+
inverter_performance = gen_data.groupby('SOURCE_KEY')['DC_POWER'].mean().sort_values()
|
| 453 |
+
|
| 454 |
+
# Identify the underperforming inverter
|
| 455 |
+
underperforming_inverter = inverter_performance.idxmin()
|
| 456 |
+
|
| 457 |
+
# Display the result
|
| 458 |
+
st.write(f"**Underperforming Inverter:** {underperforming_inverter}")
|
| 459 |
+
|
| 460 |
+
# Plot inverter performance
|
| 461 |
+
fig, ax = plt.subplots(figsize=(12, 6))
|
| 462 |
+
inverter_performance.plot(kind='bar', ax=ax, color='navy')
|
| 463 |
+
ax.set_title("Average DC Power by Inverter")
|
| 464 |
+
ax.set_ylabel("DC Power (kW)")
|
| 465 |
+
ax.set_xlabel("Inverter (SOURCE_KEY)")
|
| 466 |
+
plt.xticks(rotation=90)
|
| 467 |
+
|
| 468 |
+
# Display the plot in Streamlit
|
| 469 |
+
st.pyplot(fig)
|
| 470 |
+
st.subheader("Module and Ambient Temperature (Weather Data)")
|
| 471 |
+
|
| 472 |
+
# Plot the temperature data
|
| 473 |
+
fig, ax = plt.subplots(figsize=(15, 5))
|
| 474 |
+
weather_data.plot(x='DATE_TIME', y=['AMBIENT_TEMPERATURE', 'MODULE_TEMPERATURE'], ax=ax, title="Module and Ambient Temperature (Weather Data)")
|
| 475 |
+
|
| 476 |
+
# Display the plot in Streamlit
|
| 477 |
+
st.pyplot(fig)
|
| 478 |
+
|
| 479 |
+
st.subheader("Inverter bvBOhCH3iADSZry Performance")
|
| 480 |
+
|
| 481 |
+
# Filter data for the specific inverter
|
| 482 |
+
inverter_data = gen_data[gen_data['SOURCE_KEY'] == 'bvBOhCH3iADSZry']
|
| 483 |
+
|
| 484 |
+
# Plot AC and DC power
|
| 485 |
+
fig, ax = plt.subplots(figsize=(15, 5))
|
| 486 |
+
inverter_data.plot(x='DATE_TIME', y=['AC_POWER', 'DC_POWER'], ax=ax, title="Inverter bvBOhCH3iADSZry")
|
| 487 |
+
|
| 488 |
+
# Display the plot in Streamlit
|
| 489 |
+
st.pyplot(fig)
|
| 490 |
+
|
| 491 |
+
|
| 492 |
+
# done
|
pages/linear_regression.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import pandas as pd
|
| 3 |
+
from sklearn.model_selection import train_test_split
|
| 4 |
+
from sklearn.linear_model import LinearRegression
|
| 5 |
+
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
| 6 |
+
|
| 7 |
+
st.title("Linear Regression for Solar Energy Prediction")
|
| 8 |
+
|
| 9 |
+
# File Upload for Generation Data
|
| 10 |
+
uploaded_gen = st.file_uploader("Upload Generation Data CSV", type=["csv"], key="lr_gen")
|
| 11 |
+
uploaded_weather = st.file_uploader("Upload Weather Sensor Data CSV", type=["csv"], key="lr_weather")
|
| 12 |
+
|
| 13 |
+
def load_data(file):
|
| 14 |
+
if file is not None:
|
| 15 |
+
return pd.read_csv(file)
|
| 16 |
+
return None
|
| 17 |
+
|
| 18 |
+
# Load Data Separately
|
| 19 |
+
gen_data = load_data(uploaded_gen)
|
| 20 |
+
weather_data = load_data(uploaded_weather)
|
| 21 |
+
|
| 22 |
+
# Default Data (if no file is uploaded)
|
| 23 |
+
default_gen_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Generation_Data.csv')
|
| 24 |
+
default_weather_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Weather_Sensor_Data.csv')
|
| 25 |
+
|
| 26 |
+
if gen_data is None:
|
| 27 |
+
gen_data = default_gen_data
|
| 28 |
+
if weather_data is None:
|
| 29 |
+
weather_data = default_weather_data
|
| 30 |
+
|
| 31 |
+
# Choose which dataset to use
|
| 32 |
+
dataset_choice = st.radio("Select dataset:", ("Generation Data", "Weather Data"))
|
| 33 |
+
|
| 34 |
+
if dataset_choice == "Generation Data":
|
| 35 |
+
df = gen_data
|
| 36 |
+
target_col = "DAILY_YIELD"
|
| 37 |
+
elif dataset_choice == "Weather Data":
|
| 38 |
+
df = weather_data
|
| 39 |
+
target_col = "MODULE_TEMPERATURE"
|
| 40 |
+
|
| 41 |
+
# Feature Selection
|
| 42 |
+
features = [col for col in df.columns if col not in ["DATE_TIME", target_col, "SOURCE_KEY"]]
|
| 43 |
+
st.write("Selected Features:", features)
|
| 44 |
+
|
| 45 |
+
X = df[features]
|
| 46 |
+
y = df[target_col]
|
| 47 |
+
|
| 48 |
+
# Train-Test Split
|
| 49 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 50 |
+
|
| 51 |
+
# Train Model
|
| 52 |
+
model = LinearRegression()
|
| 53 |
+
model.fit(X_train, y_train)
|
| 54 |
+
|
| 55 |
+
# Predictions
|
| 56 |
+
y_pred = model.predict(X_test)
|
| 57 |
+
|
| 58 |
+
# Performance Metrics
|
| 59 |
+
mae = mean_absolute_error(y_test, y_pred)
|
| 60 |
+
mse = mean_squared_error(y_test, y_pred)
|
| 61 |
+
|
| 62 |
+
# Display Results
|
| 63 |
+
st.write(f"**Mean Absolute Error:** {mae:.4f}")
|
| 64 |
+
st.write(f"**Mean Squared Error:** {mse:.4f}")
|
| 65 |
+
st.line_chart(pd.DataFrame({"Actual": y_test.values, "Predicted": y_pred}))
|
pages/lstm.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
import tensorflow as tf
|
| 5 |
+
from tensorflow.keras.models import Sequential
|
| 6 |
+
from tensorflow.keras.layers import LSTM, Dense
|
| 7 |
+
from sklearn.preprocessing import MinMaxScaler
|
| 8 |
+
from sklearn.model_selection import train_test_split
|
| 9 |
+
|
| 10 |
+
st.title("LSTM Model for Solar Energy Prediction")
|
| 11 |
+
|
| 12 |
+
# File Upload for Generation Data
|
| 13 |
+
uploaded_gen = st.file_uploader("Upload Generation Data CSV", type=["csv"], key="lstm_gen")
|
| 14 |
+
uploaded_weather = st.file_uploader("Upload Weather Sensor Data CSV", type=["csv"], key="lstm_weather")
|
| 15 |
+
|
| 16 |
+
def load_data(file):
|
| 17 |
+
if file is not None:
|
| 18 |
+
return pd.read_csv(file)
|
| 19 |
+
return None
|
| 20 |
+
|
| 21 |
+
# Load Data Separately
|
| 22 |
+
gen_data = load_data(uploaded_gen)
|
| 23 |
+
weather_data = load_data(uploaded_weather)
|
| 24 |
+
|
| 25 |
+
# Default Data (if no file is uploaded)
|
| 26 |
+
default_gen_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Generation_Data.csv')
|
| 27 |
+
default_weather_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Weather_Sensor_Data.csv')
|
| 28 |
+
|
| 29 |
+
if gen_data is None:
|
| 30 |
+
gen_data = default_gen_data
|
| 31 |
+
if weather_data is None:
|
| 32 |
+
weather_data = default_weather_data
|
| 33 |
+
|
| 34 |
+
# Choose which dataset to use
|
| 35 |
+
dataset_choice = st.radio("Select dataset:", ("Generation Data", "Weather Data"))
|
| 36 |
+
|
| 37 |
+
if dataset_choice == "Generation Data":
|
| 38 |
+
df = gen_data
|
| 39 |
+
target_col = "DAILY_YIELD"
|
| 40 |
+
elif dataset_choice == "Weather Data":
|
| 41 |
+
df = weather_data
|
| 42 |
+
target_col = "MODULE_TEMPERATURE"
|
| 43 |
+
|
| 44 |
+
# Feature Selection
|
| 45 |
+
features = [col for col in df.columns if col not in ["DATE_TIME", target_col, "SOURCE_KEY"]]
|
| 46 |
+
st.write("Selected Features:", features)
|
| 47 |
+
|
| 48 |
+
# Normalize Data
|
| 49 |
+
scaler = MinMaxScaler()
|
| 50 |
+
scaled_data = scaler.fit_transform(df[features + [target_col]])
|
| 51 |
+
|
| 52 |
+
# Create Sequences for LSTM
|
| 53 |
+
def create_sequences(data, seq_length):
|
| 54 |
+
X, y = [], []
|
| 55 |
+
for i in range(len(data) - seq_length):
|
| 56 |
+
X.append(data[i : i + seq_length, :-1]) # All features except target
|
| 57 |
+
y.append(data[i + seq_length, -1]) # Target value
|
| 58 |
+
return np.array(X), np.array(y)
|
| 59 |
+
|
| 60 |
+
seq_length = st.slider("Select Sequence Length", 1, 30, 10)
|
| 61 |
+
X, y = create_sequences(scaled_data, seq_length)
|
| 62 |
+
|
| 63 |
+
# Train-Test Split
|
| 64 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 65 |
+
|
| 66 |
+
# Define LSTM Model
|
| 67 |
+
model = Sequential([
|
| 68 |
+
LSTM(50, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])),
|
| 69 |
+
LSTM(50, return_sequences=False),
|
| 70 |
+
Dense(25),
|
| 71 |
+
Dense(1)
|
| 72 |
+
])
|
| 73 |
+
|
| 74 |
+
model.compile(optimizer='adam', loss='mse')
|
| 75 |
+
|
| 76 |
+
# Train Model
|
| 77 |
+
epochs = st.slider("Select Number of Epochs", 1, 100, 10)
|
| 78 |
+
progress_bar = st.progress(0)
|
| 79 |
+
history = model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=16, verbose=1, callbacks=[tf.keras.callbacks.LambdaCallback(on_epoch_end=lambda epoch, logs: progress_bar.progress((epoch+1)/epochs))])
|
| 80 |
+
|
| 81 |
+
# Predictions
|
| 82 |
+
y_pred = model.predict(X_test)
|
| 83 |
+
|
| 84 |
+
# Inverse Transform Predictions
|
| 85 |
+
y_test_actual = scaler.inverse_transform(np.hstack((X_test[:, -1, :], y_test.reshape(-1, 1))))[:, -1]
|
| 86 |
+
y_pred_actual = scaler.inverse_transform(np.hstack((X_test[:, -1, :], y_pred)))[:, -1]
|
| 87 |
+
|
| 88 |
+
# Display Results
|
| 89 |
+
st.write("LSTM Model Performance:")
|
| 90 |
+
st.line_chart(pd.DataFrame({"Actual": y_test_actual, "Predicted": y_pred_actual}))
|
pages/random_forest.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import pandas as pd
|
| 3 |
+
from sklearn.model_selection import train_test_split
|
| 4 |
+
from sklearn.ensemble import RandomForestRegressor
|
| 5 |
+
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
| 6 |
+
|
| 7 |
+
st.title("Random Forest for Solar Energy Prediction")
|
| 8 |
+
|
| 9 |
+
# File Upload for Generation Data
|
| 10 |
+
uploaded_gen = st.file_uploader("Upload Generation Data CSV", type=["csv"], key="rf_gen")
|
| 11 |
+
uploaded_weather = st.file_uploader("Upload Weather Sensor Data CSV", type=["csv"], key="rf_weather")
|
| 12 |
+
|
| 13 |
+
def load_data(file):
|
| 14 |
+
if file is not None:
|
| 15 |
+
return pd.read_csv(file)
|
| 16 |
+
return None
|
| 17 |
+
|
| 18 |
+
# Load Data Separately
|
| 19 |
+
gen_data = load_data(uploaded_gen)
|
| 20 |
+
weather_data = load_data(uploaded_weather)
|
| 21 |
+
|
| 22 |
+
# Default Data (if no file is uploaded)
|
| 23 |
+
default_gen_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Generation_Data.csv')
|
| 24 |
+
default_weather_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Weather_Sensor_Data.csv')
|
| 25 |
+
|
| 26 |
+
if gen_data is None:
|
| 27 |
+
gen_data = default_gen_data
|
| 28 |
+
if weather_data is None:
|
| 29 |
+
weather_data = default_weather_data
|
| 30 |
+
|
| 31 |
+
# Choose which dataset to use
|
| 32 |
+
dataset_choice = st.radio("Select dataset:", ("Generation Data", "Weather Data"))
|
| 33 |
+
|
| 34 |
+
if dataset_choice == "Generation Data":
|
| 35 |
+
df = gen_data
|
| 36 |
+
target_col = "DAILY_YIELD"
|
| 37 |
+
elif dataset_choice == "Weather Data":
|
| 38 |
+
df = weather_data
|
| 39 |
+
target_col = "MODULE_TEMPERATURE"
|
| 40 |
+
|
| 41 |
+
# Feature Selection
|
| 42 |
+
features = [col for col in df.columns if col not in ["DATE_TIME", target_col, "SOURCE_KEY"]]
|
| 43 |
+
st.write("Selected Features:", features)
|
| 44 |
+
|
| 45 |
+
X = df[features]
|
| 46 |
+
y = df[target_col]
|
| 47 |
+
|
| 48 |
+
# Train-Test Split
|
| 49 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 50 |
+
|
| 51 |
+
# Model Hyperparameters
|
| 52 |
+
n_estimators = st.slider("Select Number of Trees", 10, 500, 100)
|
| 53 |
+
|
| 54 |
+
# Train Model
|
| 55 |
+
model = RandomForestRegressor(n_estimators=n_estimators, random_state=42)
|
| 56 |
+
model.fit(X_train, y_train)
|
| 57 |
+
|
| 58 |
+
# Predictions
|
| 59 |
+
y_pred = model.predict(X_test)
|
| 60 |
+
|
| 61 |
+
# Performance Metrics
|
| 62 |
+
mae = mean_absolute_error(y_test, y_pred)
|
| 63 |
+
mse = mean_squared_error(y_test, y_pred)
|
| 64 |
+
|
| 65 |
+
# Display Results
|
| 66 |
+
st.write(f"**Mean Absolute Error:** {mae:.4f}")
|
| 67 |
+
st.write(f"**Mean Squared Error:** {mse:.4f}")
|
| 68 |
+
st.line_chart(pd.DataFrame({"Actual": y_test.values, "Predicted": y_pred}))
|
pages/xgboost.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import xgboost as xgb
|
| 4 |
+
from sklearn.model_selection import train_test_split
|
| 5 |
+
from sklearn.metrics import mean_absolute_error
|
| 6 |
+
|
| 7 |
+
st.title("XGBoost Model for Solar Energy Prediction")
|
| 8 |
+
|
| 9 |
+
# File Upload for Generation Data
|
| 10 |
+
uploaded_gen = st.file_uploader("Upload Generation Data CSV", type=["csv"], key="xgb_gen")
|
| 11 |
+
uploaded_weather = st.file_uploader("Upload Weather Sensor Data CSV", type=["csv"], key="xgb_weather")
|
| 12 |
+
|
| 13 |
+
def load_data(file):
|
| 14 |
+
if file is not None:
|
| 15 |
+
return pd.read_csv(file)
|
| 16 |
+
return None
|
| 17 |
+
|
| 18 |
+
# Load Data Separately
|
| 19 |
+
gen_data = load_data(uploaded_gen)
|
| 20 |
+
weather_data = load_data(uploaded_weather)
|
| 21 |
+
|
| 22 |
+
# Default Data (if no file is uploaded)
|
| 23 |
+
default_gen_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Generation_Data.csv')
|
| 24 |
+
default_weather_data = pd.read_csv('https://github.com/Sivatech24/Streamlit/raw/refs/heads/main/Plant_1_Weather_Sensor_Data.csv')
|
| 25 |
+
|
| 26 |
+
if gen_data is None:
|
| 27 |
+
gen_data = default_gen_data
|
| 28 |
+
if weather_data is None:
|
| 29 |
+
weather_data = default_weather_data
|
| 30 |
+
|
| 31 |
+
# Choose which dataset to use
|
| 32 |
+
dataset_choice = st.radio("Select dataset:", ("Generation Data", "Weather Data"))
|
| 33 |
+
|
| 34 |
+
if dataset_choice == "Generation Data":
|
| 35 |
+
df = gen_data
|
| 36 |
+
target_col = "DAILY_YIELD"
|
| 37 |
+
elif dataset_choice == "Weather Data":
|
| 38 |
+
df = weather_data
|
| 39 |
+
target_col = "MODULE_TEMPERATURE"
|
| 40 |
+
|
| 41 |
+
# Feature Selection
|
| 42 |
+
features = [col for col in df.columns if col not in ["DATE_TIME", target_col, "SOURCE_KEY"]]
|
| 43 |
+
st.write("Selected Features:", features)
|
| 44 |
+
|
| 45 |
+
X = df[features]
|
| 46 |
+
y = df[target_col]
|
| 47 |
+
|
| 48 |
+
# Train-Test Split
|
| 49 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 50 |
+
|
| 51 |
+
# Train Model
|
| 52 |
+
n_estimators = st.slider("Select Number of Estimators", 10, 500, 100)
|
| 53 |
+
model = xgb.XGBRegressor(n_estimators=n_estimators, random_state=42)
|
| 54 |
+
model.fit(X_train, y_train)
|
| 55 |
+
|
| 56 |
+
# Predictions
|
| 57 |
+
y_pred = model.predict(X_test)
|
| 58 |
+
|
| 59 |
+
# Display Results
|
| 60 |
+
st.write(f"Mean Absolute Error: {mean_absolute_error(y_test, y_pred):.4f}")
|
| 61 |
+
st.line_chart(pd.DataFrame({"Actual": y_test.values, "Predicted": y_pred}))
|