File size: 5,482 Bytes
519e9a3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | import pandas as pd
import numpy as np
import gradio as gr
import joblib # For loading the model
import matplotlib.pyplot as plt
import io
from PIL import Image
# Load the scaler and model
scaler_path = "scaler.pkl"
model_path = "ebm_model.pkl"
# Load the pre-trained scaler and model
scaler = joblib.load(scaler_path)
ebm = joblib.load(model_path)
print("Loaded saved model and scaler.")
# 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 dynamic detailed report and 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']
# Generate dynamic, user-friendly text report based on contributions
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}).")
# Join lines into a single report
report = "\n".join(report_lines)
# 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, report
else:
return None, "No prediction has been made yet."
# Function to provide the PDF guide
def download_guide():
pdf_path = "Guide.pdf" # Path to the uploaded guide
return pdf_path
# 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 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()
|