CoolFace
Apppublic

DanielEmeka/FormationEnergyPredictor

sourceHugging Faceupdated 1y agoView on Hugging Face
1likes
app.py119 linesDownload Raw Back to root
1import pandas as pd2import gradio as gr3from sklearn.pipeline import Pipeline4from sklearn.ensemble import GradientBoostingRegressor5from sklearn.preprocessing import OneHotEncoder, StandardScaler6from sklearn.impute import SimpleImputer7from sklearn.compose import ColumnTransformer8from sklearn.model_selection import train_test_split9from sklearn.metrics import r2_score10import matplotlib.pyplot as plt11 12# Load dataset13df = pd.read_csv("data.csv")14 15# Keep only top features16categorical = ["A site #1", "B site #1", "X site"]17numerical = [18    "Number of elements",19    "Density_AB_avg",20    "Ionization Energy (kJ/mol)_AB_avg",21    "Atomic Volume (cm³/mol)_AB_avg"22]23target = "formation_energy (eV/atom)"24 25# Drop NaNs and prepare26df = df.dropna(subset=[target])27df = df[categorical + numerical + [target]]28X = df[categorical + numerical]29y = df[target]30 31# Preprocessing and model32preprocessor = ColumnTransformer([33    ("cat", Pipeline([34        ("imputer", SimpleImputer(strategy="most_frequent")),35        ("onehot", OneHotEncoder(handle_unknown="ignore"))36    ]), categorical),37    ("num", Pipeline([38        ("imputer", SimpleImputer(strategy="mean")),39        ("scaler", StandardScaler())40    ]), numerical)41])42 43model = Pipeline([44    ("prep", preprocessor),45    ("reg", GradientBoostingRegressor(n_estimators=300, learning_rate=0.05, max_depth=5, random_state=42))46])47 48# Train model49X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.2)50model.fit(X_train, y_train)51r2 = r2_score(y_test, model.predict(X_test))52 53# Prediction + plot54def predict_and_plot(a1, b1, x, num_elem, density, ion_energy, atomic_vol):55    data = {56        "A site #1": a1,57        "B site #1": b1,58        "X site": x,59        "Number of elements": float(num_elem),60        "Density_AB_avg": float(density),61        "Ionization Energy (kJ/mol)_AB_avg": float(ion_energy),62        "Atomic Volume (cm³/mol)_AB_avg": float(atomic_vol)63    }64    df_input = pd.DataFrame([data])65    pred = model.predict(df_input)[0]66 67    # Stability logic68    if pred < -1.0:69        status = "🟢 Stable"70    elif -1.0 <= pred <= 0.5:71        status = "🟡 Metastable"72    else:73        status = "🔴 Unstable"74 75    # Plot76    fig, ax = plt.subplots()77    ax.barh(["Formation Energy"], [pred], color="green" if pred < -1 else "orange" if pred <= 0.5 else "red")78    ax.set_xlim(-3, 2)79    ax.set_xlabel("eV/atom")80    ax.set_title(f"Prediction: {round(pred, 4)} eV/atom — {status}")81    plt.tight_layout()82 83    return round(pred, 5), status, fig84 85# Inputs86inputs = [87    gr.Textbox(label="A site #1"),88    gr.Textbox(label="B site #1"),89    gr.Textbox(label="X site"),90    gr.Number(label="Number of elements", value=5),91    gr.Number(label="Density_AB_avg", value=5.5),92    gr.Number(label="Ionization Energy (kJ/mol)_AB_avg", value=700),93    gr.Number(label="Atomic Volume (cm³/mol)_AB_avg", value=10.0)94]95 96# Interface97demo = gr.Interface(98    fn=predict_and_plot,99    inputs=inputs,100    outputs=[101        gr.Number(label="Predicted Formation Energy (eV/atom)"),102        gr.Text(label="Stability Status"),103        gr.Plot(label="Stability Visualization")104    ],105    title="Formation Energy Predictor",106    description=(107        "🎯 This tool predicts the **formation energy** (eV/atom) of a compound "108        "based on elemental and physical properties.\n\n"109        "**Interpretation**:\n"110        "- 🟢 Low/Negative → Stable\n"111        "- 🟡 Close to Zero → Metastable\n"112        "- 🔴 Positive → Unstable\n\n"113        f"📈 Model trained with R² score: **{round(r2, 4)}**"114    )115)116 117if __name__ == "__main__":118    demo.launch()119