CoolFace
Apppublic

Sompote/Dynamic.stability

sourceHugging Faceapache-2.0updated 2y agoView on Hugging Face
0likes
app.py92 linesDownload Raw Back to root
1import streamlit as st2import numpy as np3import torch4import shap5import matplotlib.pyplot as plt6import joblib7import pandas as pd8# Load scalers and model9@st.cache_resource10def load_resources():11    scaler_X = joblib.load("scaler_X_DS.joblib")12    scaler_y = joblib.load("scaler_y_DS.joblib")13    14    model = torch.jit.load("scripted_model_DS.pt")15    model.eval()16    17    return scaler_X, scaler_y, model18 19# Create a wrapper function for SHAP20def model_wrapper(X):21    with torch.no_grad():22        X_tensor = torch.tensor(X, dtype=torch.float32)23        output = model(X_tensor).numpy()24    return scaler_y.inverse_transform(output)25 26# Streamlit app27st.title("Dynamic Stability Predictor")28 29# Load resources30scaler_X, scaler_y, model = load_resources()31 32# Define feature names and default values33feature_names = [34    "25", "19", "12.5", "9.5", "4.75", "2.36", "1.18", "0.6", "0.3", "0.15", "0.075", "CA", "FA", "type"35]36default_values = [100, 100, 81.593, 68.395, 49.318, 29.283, 17.261, 14.257, 6.041, 3.000, 2.115, 0.600, 0.350, 1.0]37 38# Input features39st.sidebar.header("Input Features")40input_features = {}41for feature, default_value in zip(feature_names, default_values):42    if feature == "type":43        type_option = st.sidebar.selectbox(f"Enter {feature}", options=["1 - Limestone", "2 - Basalt"], index=0)44        input_features[feature] = 1.0 if type_option == "1 - Limestone" else 2.045    else:46        input_features[feature] = st.sidebar.number_input(f"Enter {feature}", value=default_value)47 48# Create input array49input_array = np.array([input_features[feature] for feature in feature_names]).reshape(1, -1)50input_scaled = scaler_X.transform(input_array)51 52# Make prediction53with torch.no_grad():54    prediction = model(torch.tensor(input_scaled, dtype=torch.float32)).numpy()55    prediction_unscaled = scaler_y.inverse_transform(prediction)56 57st.write(f"Predicted Dynamic Stability: {prediction_unscaled[0][0]:.2f} pass/mm")58 59# SHAP explanation60if st.button("Explain Prediction"):61    # Generate some random background data for SHAP62    background_data = np.random.randn(100, 14)  # 100 samples, 14 features63    background_data_scaled = scaler_X.transform(background_data)64    65    explainer = shap.KernelExplainer(model_wrapper, background_data_scaled)66    shap_values = explainer.shap_values(input_scaled)67    68    shap_values_single = shap_values[0].flatten()69    expected_value = explainer.expected_value[0]70    71    feature_values = [f"{x:.1f}" for x in input_array[0]]72    73    explanation = shap.Explanation(74        values=shap_values_single,75        base_values=expected_value,76        data=feature_values,77        feature_names=feature_names78    )79    80    fig, ax = plt.subplots(figsize=(10, 6))81    shap.plots.waterfall(explanation, show=False)82    st.pyplot(fig)83    84    st.write(f"Base value (unscaled): {([[expected_value]])[0][0]:.2f} pass/mm")85    st.write(f"Output value (unscaled): {prediction_unscaled[0][0]:.2f} pass/mm")86    87    st.write("\nFeature contributions (unscaled):")88    feature_contributions = pd.DataFrame({89        'Contribution': shap_values_single90    }, index=feature_names)91    feature_contributions['Contribution'] = feature_contributions['Contribution'].round(4)92    st.table(feature_contributions)