import pandas as pd import numpy as np import gradio as gr from interpret.glassbox import ExplainableBoostingRegressor from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt import io from PIL import Image # Load and prepare the dataset data = pd.read_csv('concrete_data.csv') data.columns = data.columns.str.strip() # Strip any leading/trailing whitespace # Splitting the data into features and target feature_names = ['cement', 'blast_furnace_slag', 'fly_ash', 'water', 'superplasticizer', 'coarse_aggregate', 'fine_aggregate', 'age'] X = data[feature_names] y = data["concrete_compressive_strength"] # Scaling the data scaler = StandardScaler() X_scaled = scaler.fit_transform(X) X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42) # Initialize and train the EBM model ebm = ExplainableBoostingRegressor(feature_names=feature_names, interactions=0) ebm.fit(X_train, y_train) # Global variable to store the most recent input data for explanation last_input_data_scaled = None # Define prediction function def predict_strength(cement, blast_furnace_slag, fly_ash, water, superplasticizer, coarse_aggregate, fine_aggregate, age): global last_input_data_scaled input_data = pd.DataFrame({ 'cement': [cement], 'blast_furnace_slag': [blast_furnace_slag], 'fly_ash': [fly_ash], 'water': [water], 'superplasticizer': [superplasticizer], 'coarse_aggregate': [coarse_aggregate], 'fine_aggregate': [fine_aggregate], 'age': [age] }) last_input_data_scaled = scaler.transform(input_data) prediction = ebm.predict(last_input_data_scaled) return prediction[0] # Explanation function for enhanced visual def show_local_explanation(): if last_input_data_scaled is not None: local_exp = ebm.explain_local(last_input_data_scaled) contributions = local_exp.data(0)['scores'] names = local_exp.data(0)['names'] # Enhanced Plotting fig, ax = plt.subplots(figsize=(10, 6)) colors = ['red' if x < 0 else 'green' for x in contributions] ax.barh(names, contributions, color=colors) ax.set_xlabel('Contribution to Prediction') ax.set_title('Local Explanation for the Most Recent Prediction') # Save plot to a buffer buf = io.BytesIO() plt.savefig(buf, format='png', bbox_inches='tight') buf.seek(0) plt.close() # Load image for display img = Image.open(buf) img_array = np.array(img) return img_array else: return "No prediction has been made yet." # Gradio interface setup with introduction and instructions with gr.Blocks() as app: gr.Markdown("## Concrete Strength Prediction App") gr.Markdown(""" This app predicts the compressive strength of concrete based on its composition using the Explainable Boosting Machine (EBM). EBM is a transparent, interpretable machine learning model that combines the power of boosting techniques with interpretable models, making it easier to explain prediction outcomes. """) gr.Markdown("### Instructions") gr.Markdown(""" - Enter the composition of the concrete in the input fields. - Click 'Predict Concrete Strength' to see the predicted strength. - Click 'Show Local Explanation' to see the contribution of each feature to the prediction. """) with gr.Row(): cement = gr.Number(label="Cement") slag = gr.Number(label="Blast Furnace Slag") fly_ash = gr.Number(label="Fly Ash") water = gr.Number(label="Water") superplasticizer = gr.Number(label="Superplasticizer") coarse_agg = gr.Number(label="Coarse Aggregate") fine_agg = gr.Number(label="Fine Aggregate") age = gr.Number(label="Age") predict_btn = gr.Button("Predict Concrete Strength") explanation_btn = gr.Button("Show Local Explanation") result = gr.Textbox(label="Predicted Concrete Strength") local_image = gr.Image(label="Local Explanation", type="numpy") predict_btn.click( fn=predict_strength, inputs=[cement, slag, fly_ash, water, superplasticizer, coarse_agg, fine_agg, age], outputs=result ) explanation_btn.click( fn=show_local_explanation, inputs=[], outputs=local_image ) app.launch(debug=True)