import pandas as pd import numpy as np import gradio as gr from xgboost import XGBRegressor from sklearn.preprocessing import LabelEncoder EXCEL_PATH = "microalgae_pot_experiment_corrected_doses.xlsx" MODEL_PATH = "EcoGrowAI_yield_model.json" df = pd.read_excel(EXCEL_PATH) # Encode categorical columns same as training for col in ["Crop", "Microalgae_Strain"]: le = LabelEncoder() df[col] = le.fit_transform(df[col]) drop_cols = ["Yield_g_per_pot", "Relative_Yield_%"] feature_cols = [c for c in df.columns if c not in drop_cols] model = XGBRegressor() model.load_model(MODEL_PATH) def make_row_label(i): return f"Row {i+1} (index={i})" def parse_index(label): return int(label.split("index=")[1].strip(")")) def on_row_select(row_label): idx = parse_index(row_label) row_df = df.iloc[[idx]][feature_cols] return "### Selected Row (Input Features)\n\n" + row_df.T.to_markdown() def on_predict(row_label): idx = parse_index(row_label) row = df.iloc[idx][feature_cols] X_row = row.astype(float).values.reshape(1, -1) # Prediction pred = model.predict(X_row)[0] pred_rounded = float(np.round(pred, 3)) # Ground truth actual = float(df.iloc[idx]["Yield_g_per_pot"]) # Error (always positive) error = abs(pred_rounded - actual) error_rounded = float(np.round(error, 3)) # Markdown display features_md = "### Input Features\n\n" + row.to_frame().to_markdown() result_md = ( f"### Results\n\n" f"**Predicted Yield (g per pot):** {pred_rounded}\n\n" f"**Actual Yield (Ground Truth):** {actual}\n\n" f"**Absolute Error:** {error_rounded}" ) return "✅ Prediction complete", features_md, result_md row_choices = [make_row_label(i) for i in range(len(df))] with gr.Blocks(css=""" body {background:#f5f7fa;color:#0b1220;font-family:Inter,sans-serif;} .gradio-container{max-width:1200px;margin:20px auto;} .card{background:white;padding:20px;border-radius:10px; box-shadow:0 4px 16px rgba(0,0,0,0.05);} """) as demo: with gr.Column(elem_classes="card"): gr.Markdown("# EcoGrowAI — Yield Prediction") gr.Markdown("Select any experimental row and predict **Yield (g per pot)** using the trained XGBoost model.") with gr.Row(): with gr.Column(scale=1): row_dropdown = gr.Dropdown( label="Select Row", choices=row_choices, value=row_choices[0], interactive=True ) row_info = gr.Markdown("No row selected yet.") predict_button = gr.Button("Predict", variant="primary") with gr.Column(scale=1): status = gr.Markdown("") features_md = gr.Markdown("") result_md = gr.Markdown("") row_dropdown.change(on_row_select, row_dropdown, row_info) predict_button.click(on_predict, row_dropdown, [status, features_md, result_md]) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)