import gradio as gr import pandas as pd import numpy as np from xgboost import XGBRegressor import joblib import os import logging # ----------------------------- # 1️⃣ File paths # ----------------------------- MODEL_PATH = "xgb_model_corn_final.json" SCALER_PATH = "minmax_scaler.pkl" EXCEL_PATH = "microalgae_pot_experiment_corrected_doses.xlsx" # Check files exist for path in [MODEL_PATH, SCALER_PATH, EXCEL_PATH]: if not os.path.exists(path): raise FileNotFoundError(f"File not found: {path}") # ----------------------------- # 2️⃣ Load model, scaler, and data # ----------------------------- xgb_model = XGBRegressor() xgb_model.load_model(MODEL_PATH) scaler = joblib.load(SCALER_PATH) df = pd.read_excel(EXCEL_PATH) # Only one strain exists strain_names = df['Microalgae_Strain'].unique().tolist() single_strain_value = 0 # training used LabelEncoder -> 0 # ----------------------------- # 3️⃣ Prediction function # ----------------------------- def predict_dose(crop, microalgae_strain, soil_n, soil_p, soil_k, soil_ec, soil_moisture, chlorophyll, shoot_length, root_length, yield_g, relative_yield, actual_dose): logs = [] # Capture all debug info # 1️⃣ Validate inputs required = [soil_n, soil_p, soil_k, soil_ec, soil_moisture, chlorophyll, shoot_length, root_length, yield_g, relative_yield] if any(v is None for v in required): logs.append("[DEBUG] Missing numeric inputs!") return "⚠️ Please fill all numeric input fields.", None, None, "\n".join(logs) logs.append("[DEBUG] All inputs received.") # 2️⃣ Encode strain strain_encoded = single_strain_value logs.append(f"[DEBUG] Using Microalgae_Strain encoded value: {strain_encoded}") # 3️⃣ Create DataFrame feature_cols = ['Soil_N_ppm','Soil_P_ppm','Soil_K_ppm','Soil_EC_dS_m', 'Soil_Moisture_%','Chlorophyll_SPAD','Shoot_Length_cm', 'Root_Length_cm','Yield_g_per_pot','Relative_Yield_%','Microalgae_Strain'] X_input_df = pd.DataFrame([[soil_n, soil_p, soil_k, soil_ec, soil_moisture, chlorophyll, shoot_length, root_length, yield_g, relative_yield, strain_encoded]], columns=feature_cols).astype(float) logs.append(f"[DEBUG] Input DataFrame:\n{X_input_df}") # 4️⃣ Scale X_input_scaled = scaler.transform(X_input_df) logs.append(f"[DEBUG] Scaled Input:\n{X_input_scaled}") # 5️⃣ Predict predicted_dose = xgb_model.predict(X_input_scaled)[0] logs.append(f"[DEBUG] Predicted dose (raw): {predicted_dose}") # 6️⃣ Compute error if actual_dose is not None: abs_error = abs(predicted_dose - actual_dose) logs.append(f"[DEBUG] Actual dose: {actual_dose}") logs.append(f"[DEBUG] Absolute Error: {abs_error}") return (f"🌱 **Predicted Dose:** {predicted_dose:.2f} g/pot", f"📏 **Actual Dose:** {actual_dose:.2f} g/pot", f"❌ **Absolute Error:** {abs_error:.2f} g/pot", "\n".join(logs)) else: logs.append("[DEBUG] Actual dose not provided.") return (f"🌱 **Predicted Dose:** {predicted_dose:.2f} g/pot", "📏 Actual Dose: Not provided", "❌ Absolute Error: N/A", "\n".join(logs)) # ----------------------------- # 4️⃣ Gradio Interface # ----------------------------- with gr.Blocks( theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime", neutral_hue="gray"), title="EcoGrowAI — Microalgae Dose Inference" ) as demo: gr.Markdown( """
Predict the optimal microalgae dose (g/pot) for Corn based on soil and growth parameters.