File size: 3,028 Bytes
68f3c54
 
 
 
1d63edc
277a4bf
 
 
1d63edc
a635a43
889c563
1d63edc
889c563
 
 
 
a635a43
68f3c54
 
 
 
 
1d63edc
68f3c54
 
 
1d63edc
ddfa7c6
2098307
ddfa7c6
1d63edc
fa2151f
1d63edc
 
 
 
fa2151f
 
5bb02d7
 
 
1d63edc
18ec578
fa2151f
 
18ec578
 
 
1d63edc
 
18ec578
 
 
1d63edc
9a57ce4
18ec578
1d63edc
18ec578
 
 
 
 
1d63edc
 
fa2151f
68f3c54
 
 
fa2151f
5bb02d7
1d63edc
 
68f3c54
1d63edc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68f3c54
 
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
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)