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('concrete.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('concrete.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 Concrete Test Analysis
",unsafe_allow_html=True)
st.markdown(" Your Online calculator of cement 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 tool allows you to explore and analyze cement slump test data, and apply a machine learning model to predict compressive strength based on your input data.
- **Home:** Overview of the project.
- **Dashboard:** Graphs of the project.
- **Analytics and Visualization:** 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)
st.markdown("
", unsafe_allow_html=True)
st.markdown(" Overview
", unsafe_allow_html=True)
col3, _, col4 = st.columns([3, 0.3, 3])
with col3:
st.write("""
The cement slump test is used to measure the consistency and workability of fresh concrete before it sets. It is a simple and widely-used test that provides a quick assessment of the quality of the concrete mix.
The main components measured in the test are:
- **Cement**: The primary binding material.
- **Slag**: A byproduct of steel production that can enhance concrete durability.
- **Ash**: A byproduct of coal combustion that can improve concrete workability.
- **Water**: Essential for the hydration process.
- **Superplasticizer**: Used to improve the workability without adding more water.
""")
with col4:
st.image("3.jpg", width=200, use_column_width=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown(" Project Goals
", unsafe_allow_html=True)
st.write("""
This project aims to:
1. **Analyze** the cement slump test dataset to understand the relationships between different components.
2. **Visualize** the data through various charts and plots for better insights.
3. **Predict** the compressive strength of cement using a machine learning model trained on the dataset.
""")
st.markdown("
", unsafe_allow_html=True)
st.markdown(" Key Features
", unsafe_allow_html=True)
st.write("""
- **Interactive Visualizations**: Explore the dataset through various plots and charts.
- **Machine Learning Predictions**: Input your data and get predictions for the compressive strength.
- **Detailed Analytics**: Gain insights into the dataset with detailed analytics and summary statistics.
""")
st.markdown("
", unsafe_allow_html=True)
st.markdown(" About Us
", unsafe_allow_html=True)
st.write("""
This application is developed by Hadama Oceane, aiming to provide an easy-to-use interface for cement slump test data analysis and prediction.
Feel free to reach out to us for any queries or feedback.
""")
st.markdown("
", unsafe_allow_html=True)
st.write("Contact us: oceanehadama@gmail.com")
st.markdown("
", unsafe_allow_html=True)
# # Image Gallery
# st.markdown(" Image Gallery of elements we needs
", unsafe_allow_html=True)
# col1, col2, col3 = st.columns(3)
# with col1:
# st.image("3.jpg", caption="Cement", use_column_width=True)
# st.image("2.jpg", caption="Slag", use_column_width=True)
# with col2:
# st.image("image.png", caption="Fly Ash", use_column_width=True)
# st.image("2.jpg", caption="Water", use_column_width=True)
# with col3:
# st.image("3.jpg", caption="Superplasticizer", use_column_width=True)
# st.image("1.png", caption="Coarse Aggregate", use_column_width=True)
# st.markdown("
", unsafe_allow_html=True)
# Dashboard page
if page == "Dashboard":
st.markdown("Dashboard
", 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('concrete.csv')
return data
# Load dataset
data = load_data()
# Metrics row
col4, space1, col5, space2, col6 = st.columns([3, 0.5, 3, 0.5, 3])
with col4:
st.metric(label="Total lines", value=1032)
with col5:
st.metric(label="Total Colunms", value=9)
with col6:
st.metric(label="Total parameters", value=8)
st.markdown("
", unsafe_allow_html=True)
# 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
# Define features and target
X = data.drop(columns=['strength'])
y = data['strength']
# 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)
# Create two columns for plots
col7, col8 = st.columns(2)
with col7:
# 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)
with col8:
with col8:
# Pie chart
st.subheader("Component Distribution Pie Chart")
fig_pie, ax_pie = plt.subplots()
labels = X.columns.tolist()
sizes = [data[label].sum() for label in labels if label in data.columns]
def autopct(pct):
total = sum(sizes)
val = int(round(pct*total/100.0))
return f'{pct:.1f}%\n({val:d})'
wedges, texts, autotexts = ax_pie.pie(sizes, labels=labels, autopct=autopct, startangle=140, colors=plt.cm.Paired.colors)
for text in texts:
text.set_color('grey')
for autotext in autotexts:
autotext.set_color('white')
ax_pie.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
fig_pie.patch.set_facecolor('none') # Remove background
st.pyplot(fig_pie)
st.markdown("
", unsafe_allow_html=True)
st.subheader("Concrete Data Distribution")
fig, ax = plt.subplots()
sns.histplot(data['cement'], bins=20, kde=True, color='blue', ax=ax)
ax.set_title('Distribution of Cement Data')
st.pyplot(fig)
# Analytics page
elif page == "Analytics":
st.title("Cement Data Analytics")
# Display dataset
st.subheader("Dataset")
st.write(data.head())
st.sidebar.markdown("## Customize Analytics")
plot_type = st.sidebar.radio("Select display", ["Summary", "Correlation Heatmap"])
if plot_type == 'Summary':
st.subheader('Cement Sumary')
st.dataframe(data.describe())
if plot_type == "Correlation Heatmap":
# Display correlation heatmap
st.subheader("Correlation Heatmap")
fig, ax = plt.subplots()
sns.heatmap(data.corr(), annot=True, cmap='coolwarm', ax=ax)
st.pyplot(fig)
# Visualization page
elif page == "Visualization":
st.title("Cement Data Analytics")
# Display dataset
st.subheader("Dataset")
st.write(data.head())
st.sidebar.markdown("## Customize Visualizations")
plot_type = st.sidebar.radio("Select Plot Type", ["Regplot","Scatterplot", "lineplot","Barplot","Pairplot"])
if plot_type == "Pairplot":
st.subheader("Pairplot")
fig = sns.pairplot(data)
st.pyplot(fig)
elif plot_type == "Regplot":
# Regplot Tab
st.subheader('Cement Data Regplot')
fig = plt.figure(figsize=(15, 5))
sns.regplot(data=data, x='water', y='cement')
st.pyplot(fig)
elif plot_type == "Scatterplot":
st.subheader('cement Data scatterplot')
fig = plt.figure(figsize=(15, 5))
sns.scatterplot(data=data, x='water', y='cement')
st.pyplot(fig)
elif plot_type == "lineplot":
st.subheader('cement Data lineplot')
fig = plt.figure(figsize=(15, 5))
sns.lineplot(data=data, x='water', y='cement')
st.pyplot(fig)
elif plot_type == "Barplot":
st.subheader('cement Data Barplot')
fig = plt.figure(figsize=(15, 5))
sns.barplot(data=data, x='water', y='cement')
st.pyplot(fig)
# Machine Learning page
elif page == "Machine Learning":
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)
ash = st.number_input("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)
superplastic = st.number_input("Superplastic", min_value=0.0, max_value=1000.0, value=10.0)
coarseagg = st.number_input("Coarseaggr.", min_value=0.0, max_value=1000.0, value=100.0)
fineagg = st.number_input("Fineaggr.", min_value=0.0, max_value=1000.0, value=100.0)
age = st.number_input("age", min_value=0.0, max_value=100.0, value=10.0)
# Make prediction
if st.button("Predict"):
features = np.array([[cement, slag, ash, water, superplastic, coarseagg, fineagg , age]])
prediction = regressor.predict(features)
st.write(f"Predicted 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 'strength' in data.columns:
data = data.drop(columns=['strength'])
model = pickle.load(open('concrete.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)
st.sidebar.markdown( '''
---
Created by Oceane 😊 ''')