import streamlit as st
from streamlit_option_menu import option_menu
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import pickle
import numpy as np
import base64
from streamlit_shap import st_shap
from streamlit_echarts import st_echarts
import shap
from sklearn.model_selection import train_test_split
import xgboost
import plotly.express as px
# Load the dataset
data = pd.read_csv('cement_slump.csv')
# Display the column names for inspection
# st.write("Column names in the dataset:")
# st.write(data.columns)
# Load the saved regression model
with open('cement.pkl', 'rb') as f:
regressor = pickle.load(f)
# Sidebar
st.sidebar.image('logo.png',width=250)
with st.sidebar:
selected = option_menu(
"Menu",
['Home', 'Dashboard', 'Analytics', 'Visualization', 'Machine Learning'],
icons=['house', 'speedometer2', 'boxes', 'graph-up-arrow', 'easel2'],
menu_icon="list",
default_index=0,
styles={
"container": {"padding": "5px", "background-color": "transparent", "font-weight": "bold"},
"icon": {"font-size": "17px"},
"nav-link": {"font-size": "15px", "text-align": "left", "margin": "5px", "padding": "10px", "--hover-color": "#9A9DA0"},
"nav-link-selected": {"background-color": "#B28E52"},
}
)
# Page content based on the selected option
page = selected
if page == 'Home':
# st.markdown("Welcome to the Home page")
st.markdown("
Welcome to Cement Slump Test Analysis
",unsafe_allow_html=True)
st.markdown(" Your Online calculator of cementy strengh
",unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
# Home page
if page == "Home":
st.markdown(" Introduction
",unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True) # Add space between the title and content
col1, _, col2 = st.columns([3, 0.3, 3])
with col1:
st.write("""
This application allows you to analyze cement slump test data and apply a machine learning model to predict the compressive strength.
- **Home:** Overview of the project.
- **Analytics:** Explore and visualize the dataset.
- **Machine Learning:** Make predictions using a pre-trained model.
""")
with col2:
st.image("image.png", width = 200, use_column_width=True)
# Dashboard page
# Dashboard page
if page == "Dashboard":
# st.markdown(" Summary
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True) # Add space between the title and content
# Function to load the dataset
@st.cache_data
def load_data():
data = pd.read_csv('cement_slump.csv')
return data
# Function to compute total slag
def sum_Slag():
data = load_data()
return data['slag'].sum()
# Function to compute total fly ash
def sum_Fly_ash():
data = load_data()
return data['Fly ash'].sum()
# Dashboard page
if page == "Dashboard":
st.markdown("
", unsafe_allow_html=True) # Add space between the title and content
@st.cache_data
def load_data():
data = pd.read_csv('cement_slump.csv')
return data
data = load_data()
left, middle, right = st.columns((0.5, 4, 0.5))
# First row
with middle:
col1, col2, col3 = st.columns(3)
with col2:
st.image('3.jpg', width=300) # Adjust the width to reduce the size
st.title("Walmart Dashboard")
col4, space1, col5, space2, col6 = st.columns([3, 0.5, 3, 0.5, 3])
with col4:
st.metric(label="Total Slag", value=sum_Slag(), delta="From 5010 To 2012")
with col5:
st.metric(label="Total Fly Ash", value=sum_Fly_ash(), delta="From 2010 To 2012")
with col6:
st.metric(label="Total Stores studied", value=45, delta="From 2010 To 2012")
st.title("SHAP in Streamlit")
# Function to train the model
@st.cache_data
def load_model(X, y):
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7)
d_train = xgboost.DMatrix(X_train, label=y_train)
d_test = xgboost.DMatrix(X_test, label=y_test)
params = {
"eta": 0.01,
"objective": "reg:squarederror",
"subsample": 0.5,
"base_score": np.mean(y_train),
"eval_metric": "rmse",
"n_jobs": -1,
}
model = xgboost.train(params, d_train, 100, evals=[(d_test, "test")], verbose_eval=10, early_stopping_rounds=20)
return model, X_test, y_test
# Load dataset
data = load_data()
# Define features and target
X = data.drop(columns=['Compressive Strength (28-day)(Mpa)'])
y = data['Compressive Strength (28-day)(Mpa)']
# Train the model
model, X_test, y_test = load_model(X, y)
# Compute SHAP values
explainer = shap.Explainer(model, X_test)
shap_values = explainer(X_test)
# SHAP summary plot
st.subheader("SHAP Summary Plot")
fig_summary, ax_summary = plt.subplots()
shap.summary_plot(shap_values, X_test, show=False)
st.pyplot(fig_summary)
# Pie chart
st.subheader("Pie Chart")
fig_pie, ax_pie = plt.subplots()
labels = X.columns.tolist()
sizes = [data[label].sum() for label in labels]
ax_pie.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)
ax_pie.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
st.pyplot(fig_pie)
# Analytics page
elif page == "Analytics":
st.title("Cement Data Analytics")
st.sidebar.markdown("## Customize Visualizations")
plot_type = st.sidebar.radio("Select Plot Type", ["Correlation Heatmap", "Pairplot"])
# Display dataset
st.subheader("Dataset")
st.write(data.head())
# Display correlation heatmap
st.subheader("Correlation Heatmap")
fig, ax = plt.subplots()
sns.heatmap(data.corr(), annot=True, cmap='coolwarm', ax=ax)
st.pyplot(fig)
# Display pairplot
st.subheader("Pairplot")
fig = sns.pairplot(data)
st.pyplot(fig)
# Analytics page
elif page == "Visualization":
left, middle, right = st.columns((0.5, 4, 0.5))
with middle:
tab1, tab2, tab3 = st.tabs(['Regplot', 'Barplot', 'Lineplot'])
# Regplot Tab
with tab1:
st.subheader('Cement Data Regplot')
fig = plt.figure(figsize=(15, 5))
sns.regplot(data=data, x='Water', y='Cement')
st.pyplot(fig)
# Barplot Tab
with tab2:
st.subheader('Cement Data Barplot')
option = {
"xAxis": {
"type": "category",
"data": data['Water'].tolist(), # Replace with actual column name for x-axis data
},
"yAxis": {
"type": "value"
},
"series": [{
"data": data['Cement'].tolist(), # Replace with actual column name for bar plot data
"type": "bar"
}]
}
st_echarts(
options=option,
height="400px",
)
# Lineplot Tab
with tab3:
st.subheader('Cement Data Line Plot')
option = {
"xAxis": {
"type": "category",
"data": data['Water'].tolist(), # Replace with actual column name for x-axis data
},
"yAxis": {
"type": "value"
},
"series": [{
"data": data['Cement'].tolist(), # Replace with actual column name for line plot data
"type": "line"
}]
}
st_echarts(
options=option,
height="400px",
)
# #Row A
# st.markdown('### Metrics')
# col1, col2, col3 = st.columns(3)
# # Nombre de diamants
# num_diamonds = len(data)
# col1.metric("Water", num_diamonds)
# # Prix moyen
# average_price = data['Water'].mean()
# col2.metric("Cement", f"${average_price:.2f}")
# # Carat moyen
# average_carat = data['Water'].mean()
# col3.metric("Cement", f"{average_carat:.2f}")
# # Row B
# c1, c2 = st.columns((7,3)) # Crée deux colonnes, une plus large que l'autre
# with c1:
# st.markdown('### Heatmap') # Affiche un titre pour la première colonne
# heatmap_fig = px.density_heatmap(data, x='Water', y='Cement', facet_col='SP', facet_col_wrap=2, color_continuous_scale='viridis') # Crée un heatmap avec Plotly Express, montrant la densité des diamants en fonction du poids en carats et du prix, avec des sous-graphiques pour chaque qualité de coupe
# st.plotly_chart(heatmap_fig, use_container_width=True) # Affiche le heatmap dans Streamlit avec une largeur adaptative
# with c2:
# st.markdown('### Donut chart') # Affiche un titre pour la deuxième colonne
# donut_fig = px.pie(data, names='Water', hole=0.5) # Crée un donut chart avec Plotly Express, montrant la répartition des diamants en fonction de leur clarté
# st.plotly_chart(donut_fig, use_container_width=True) # Affiche le donut chart dans Streamlit avec une largeur adaptative
# fig = plotly.tools.make_subplots(rows=rows, cols=1, vertical_spacing=0.5/rows)
# fig['layout'].update(height=1000)
# Machine Learning page
elif page == "Machine Learning":
# st.sidebar.markdown("## Data Upload")
# uploaded_file = st.sidebar.file_uploader("Choose a CSV file", type="csv")
# # If a file is uploaded, replace the dataset with the uploaded file
# if uploaded_file is not None:
# data = pd.read_csv(uploaded_file)
st.markdown(" Cement Strength Prediction
", unsafe_allow_html=True)
st.write("Use the form below to input features and get a prediction of the compressive strength.")
# Option du menu de navigation
selection = option_menu(
menu_title=None,
options=['User input', 'Upload csv'],
icons=['card-text', 'cloud-upload'],
default_index=0,
orientation='horizontal',
styles={
"container": {"padding": "5px", "background-color": "#333333", "font-weight": "bold"},
"icon": {"font-size": "17px"},
"nav-link": {"font-size": "15px", "text-align": "left", "margin": "5px", "padding": "10px", "--hover-color": "#9A9DA0"},
"nav-link-selected": {"background-color": "#B28E52"},
}
)
if selection == 'User input':
cement = st.number_input("Cement", min_value=0.0, max_value=1000.0, value=100.0)
slag = st.number_input("slag", min_value=0.0, max_value=1000.0, value=100.0)
fly_ash = st.number_input("Fly ash", min_value=0.0, max_value=1000.0, value=100.0)
water = st.number_input("Water", min_value=0.0, max_value=1000.0, value=100.0)
sp = st.number_input("SP", min_value=0.0, max_value=1000.0, value=10.0)
coarse_aggr = st.number_input("Coarse Aggr.", min_value=0.0, max_value=1000.0, value=100.0)
fine_aggr = st.number_input("Fine Aggr.", min_value=0.0, max_value=1000.0, value=100.0)
slump = st.number_input("SLUMP(cm)", min_value=0.0, max_value=100.0, value=10.0)
flow = st.number_input("FLOW(cm)", min_value=0.0, max_value=100.0, value=10.0)
# Make prediction
if st.button("Predict"):
features = np.array([[cement, slag, fly_ash, water, sp, coarse_aggr, fine_aggr , slump, flow]])
prediction = regressor.predict(features)
st.write(f"Predicted Compressive Strength: {prediction[0]:.2f}")
# Function to load data from an uploaded file
def load_data(file):
data = pd.read_csv(file)
return data
# Function to generate download link for a DataFrame
def filedownload(df):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode() # B64 encoding
href = f'Download CSV File'
return href
# Upload CSV section
if selection == "Upload csv":
st.write("### Upload your input CSV file")
uploaded_file = st.file_uploader('Choose a CSV file', type=["csv"])
if uploaded_file:
data = load_data(uploaded_file)
if st.checkbox('Load dataset'):
st.subheader('Loaded Dataset')
st.write(data)
if st.checkbox('Prediction'):
if 'Compressive Strength (28-day)(Mpa)' in data.columns:
data = data.drop(columns=['Compressive Strength (28-day)(Mpa)'])
model = pickle.load(open('cement.pkl', 'rb'))
prediction = model.predict(data)
pp = pd.DataFrame(prediction, columns=['Prediction'])
ndf = pd.concat([data, pp], axis=1)
st.write(ndf)
if st.button("Download"):
st.markdown(filedownload(ndf), unsafe_allow_html=True)
# if st.checkbox('Prediction'):
# model = pickle.load(open('cement.pkl', 'rb'))
# # Assuming the model is trained without the target column
# prediction = model.predict(data)
# pp = pd.DataFrame(prediction, columns=['Prediction'])
# ndf = pd.concat([data, pp], axis=1)
# st.write(ndf)
# if st.button("Download"):
# st.markdown(filedownload(ndf), unsafe_allow_html=True)
# if selection == "Upload csv":
# uploaded_file = st.file_uploader('Upload your input CSV file',type=["csv"])
# if uploaded_file:
# data = load_data(uploaded_file)
# if st.checkbox('Load dataset'):
# st.subheader('loaded dataset')
# st.write(data)
# elif st.checkbox('prediction'):
# model = pickle.load(open('model.pkl', 'rb'))
# #df.drop(['Outcome'],axis=1)
# prediction = model.predict(data)
# pp = pd.DataFrame(prediction,columns=['Prediction'])
# ndf = pd.concat([data,pp],axis=1)
# st.write(ndf)
# button = st.button("Download")
# if button:
# st.markdown(filedownload(ndf), unsafe_allow_html=True)
# # Make prediction
# if st.button("Predict"):
# features = np.array([[cement, slag, fly_ash, water, sp, coarse_aggr, fine_aggr , slump, flow]])
# prediction = regressor.predict(features)
# st.write(f"Predicted Compressive Strength: {prediction[0]:.2f}")
# About page
elif page == "About":
st.title("About This Project")
st.write("""
This project is developed to analyze and predict the compressive strength of cement based on its ingredients.
### Features:
- Data visualization to explore relationships between different ingredients.
- Machine learning model to predict compressive strength.
### Data Source:
- The dataset is a collection of cement ingredients and their corresponding properties.
### Model:
- The predictive model is trained using a regression algorithm.
""")
st.sidebar.markdown( '''
---
Created by Oceane 😊 ''')