| import pandas as pd |
| import numpy as np |
| import gradio as gr |
| import joblib |
| import matplotlib.pyplot as plt |
| import io |
| from PIL import Image |
|
|
| |
| scaler_path = "scaler.pkl" |
| model_path = "ebm_model.pkl" |
|
|
| |
| scaler = joblib.load(scaler_path) |
| ebm = joblib.load(model_path) |
| print("Loaded saved model and scaler.") |
|
|
| |
| last_input_data_scaled = None |
|
|
| |
| 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] |
|
|
| |
| 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'] |
|
|
| |
| report_lines = [] |
| for name, contribution in zip(names, contributions): |
| abs_contribution = abs(contribution) |
| if contribution > 0: |
| if abs_contribution > 10: |
| report_lines.append(f"- {name.capitalize()} strongly contributes to concrete strength (+{contribution:.2f}).") |
| else: |
| report_lines.append(f"- {name.capitalize()} has a minor positive effect on concrete strength (+{contribution:.2f}).") |
| elif contribution < 0: |
| if abs_contribution > 10: |
| report_lines.append(f"- {name.capitalize()} significantly reduces concrete strength ({contribution:.2f}). Consider adjusting this component.") |
| else: |
| report_lines.append(f"- {name.capitalize()} has a slight negative effect on concrete strength ({contribution:.2f}).") |
|
|
| |
| report = "\n".join(report_lines) |
|
|
| |
| 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') |
|
|
| |
| buf = io.BytesIO() |
| plt.savefig(buf, format='png', bbox_inches='tight') |
| buf.seek(0) |
| plt.close() |
|
|
| |
| img = Image.open(buf) |
| img_array = np.array(img) |
| return img_array, report |
| else: |
| return None, "No prediction has been made yet." |
|
|
| |
| def download_guide(): |
| pdf_path = "Guide.pdf" |
| return pdf_path |
|
|
| |
| 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 Detailed Report' to see a breakdown of each feature's impact on the prediction. |
| - Click 'Download Guide' to learn about the concrete mix components and input guidelines. |
| """) |
|
|
| 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") |
|
|
| |
| download_btn = gr.Button("Download Guide") |
| predict_btn = gr.Button("Predict Concrete Strength") |
| explanation_btn = gr.Button("Show Detailed Report") |
| |
|
|
| guide_file = gr.File(label="Guide Download") |
|
|
| result = gr.Textbox(label="Predicted Concrete Strength") |
| local_image = gr.Image(label="Local Explanation", type="numpy") |
| explanation_text = gr.Textbox(label="Feature Impact Report") |
| |
|
|
| download_btn.click( |
| fn=download_guide, |
| inputs=[], |
| outputs=guide_file |
| ) |
|
|
| 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, explanation_text] |
| ) |
| |
|
|
| app.launch() |
|
|