File size: 12,257 Bytes
d31d29b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.ensemble import RandomForestClassifier
import gradio as gr
import matplotlib.pyplot as plt
import seaborn as sns
from io import BytesIO
import requests

# Load and preprocess data
file_path = '/content/DSV Project Final Spreadsheet.csv'  
data = pd.read_csv(file_path)


# Convert string columns to numeric
for col in ['N', 'P', 'K']:
    data[col] = pd.to_numeric(data[col], errors='coerce')

# Encode categorical variables
le_soil = LabelEncoder()
le_season = LabelEncoder()
data['Soil Type'] = le_soil.fit_transform(data['Soil Type'])
data['Season'] = le_season.fit_transform(data['Season'])

# Features and target variables
features = ['N', 'P', 'K', 'temperature', 'humidity', 'ph', 'rainfall', 'Soil Moisture Level (%)', 'Soil Type', 'Season']
X = data[features]

# Encode target variables
le_crop = LabelEncoder()
le_fertilizer = LabelEncoder()
le_water_pump = LabelEncoder()
le_fire = LabelEncoder()

y_crop = le_crop.fit_transform(data['Crop Name'])
y_fertilizer = le_fertilizer.fit_transform(data['Fertilizer Recommendations'])
y_water_pump = le_water_pump.fit_transform(data['Water Pump Status (ON/OFF)'])
y_fire = le_fire.fit_transform(data['Fire Detection (YES/NO)'])

# Scale features
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Create models
crop_model = RandomForestClassifier(n_estimators=100, random_state=42)
crop_model.fit(X_scaled, y_crop)

fertilizer_model = RandomForestClassifier(n_estimators=100, random_state=42)
fertilizer_model.fit(X_scaled, y_fertilizer)

water_pump_model = RandomForestClassifier(n_estimators=100, random_state=42)
water_pump_model.fit(X_scaled, y_water_pump)

fire_model = RandomForestClassifier(n_estimators=100, random_state=42)
fire_model.fit(X_scaled, y_fire)

# Prediction function for the UI
def predict_crop(n, p, k, temperature, humidity, ph, rainfall, soil_moisture, soil_type, season):
    # Check if soil_type and season are within bounds
    if not (0 <= soil_type <= 4):
        return {"Error": "Please enter a valid Soil Type (0 -> Alluvial, 1 -> Black, 2 -> Clayey, 3 -> Laterite, 4 -> Sandy)"}
    
    if not (0 <= season <= 3):
        return {"Error": "Please enter a valid Season (0 -> Autumn, 1 -> Spring, 2 -> Summer, 3 -> Winter)"}

    # Create input array
    input_data = pd.DataFrame([[n, p, k, temperature, humidity, ph, rainfall, soil_moisture, soil_type, season]],
                              columns=features)
    input_scaled = scaler.transform(input_data)
    
    # Make predictions
    crop_pred = le_crop.inverse_transform(crop_model.predict(input_scaled))[0]
    fertilizer_pred = le_fertilizer.inverse_transform(fertilizer_model.predict(input_scaled))[0]
    water_pump_pred = le_water_pump.inverse_transform(water_pump_model.predict(input_scaled))[0]
    fire_pred = le_fire.inverse_transform(fire_model.predict(input_scaled))[0]
    
    return {
        "Recommended Crop": crop_pred,
        "Fertilizer Recommendation": fertilizer_pred,
        "Water Pump Status": water_pump_pred,
        "Fire Detection": fire_pred
    }

# Visualization function
def visualize_predictions(n, p, k, temperature, humidity, ph, rainfall, soil_moisture, soil_type, season, show_crop, show_fertilizer, show_water_pump, show_fire):
    input_data = pd.DataFrame([[n, p, k, temperature, humidity, ph, rainfall, soil_moisture, soil_type, season]],
                              columns=features)
    input_scaled = scaler.transform(input_data)
    
    # Predictions
    crop_pred = le_crop.inverse_transform(crop_model.predict(input_scaled))[0]
    fertilizer_pred = le_fertilizer.inverse_transform(fertilizer_model.predict(input_scaled))[0]
    water_pump_pred = le_water_pump.inverse_transform(water_pump_model.predict(input_scaled))[0]
    fire_pred = le_fire.inverse_transform(fire_model.predict(input_scaled))[0]

    # Plot
    fig, ax = plt.subplots()
    
    labels = []
    values = []
    
    if show_crop:
        labels.append("Recommended Crop")
        values.append(crop_pred)
    if show_fertilizer:
        labels.append("Fertilizer")
        values.append(fertilizer_pred)
    if show_water_pump:
        labels.append("Water Pump Status")
        values.append(water_pump_pred)
    if show_fire:
        labels.append("Fire Detection")
        values.append(fire_pred)
    
    ax.barh(labels, [1]*len(labels), color=['#4CAF50', '#FF9800', '#2196F3', '#F44336'])
    
    for i, v in enumerate(values):
        ax.text(1.05, i, str(v), color='black', fontweight='bold')

    ax.set_xlim(0, 1.5)
    
    plt.tight_layout()
    return fig

# Data Insight function
def data_insight(visualization_type, predicted_outcome, input1, input2, input3):
    plt.figure(figsize=(12, 10))
    
    if visualization_type == "Scatter Plot":
        if predicted_outcome == "Recommended Crop":
            target = data['Crop Name']
        elif predicted_outcome == "Fertilizer Recommendation":
            target = data['Fertilizer Recommendations']
        elif predicted_outcome == "Water Pump Status":
            target = data['Water Pump Status (ON/OFF)']
        else:
            target = data['Fire Detection (YES/NO)']
        
        plt.scatter(data[input1], data[input2], c=data[input3], cmap='viridis', alpha=0.6)
        plt.colorbar(label=input3)
        plt.xlabel(input1)
        plt.ylabel(input2)
        plt.title(f"Scatter Plot: {predicted_outcome}\n{input1} vs {input2}, color intensity: {input3}")
    
    elif visualization_type == "Correlation Plot":
        numeric_data = data[features + ['Soil Moisture Level (%)']]
        corr = numeric_data.corr()
        sns.heatmap(corr, annot=True, cmap="coolwarm", fmt=".2f")
        plt.title("Correlation Plot of Numeric Features")
    
    elif visualization_type == "Pair Plot":
        sns.pairplot(data[features], diag_kind="kde")
        plt.suptitle("Pair Plot of Input Features", y=1.02)
    
    elif visualization_type == "Box Plot":
        plt.figure(figsize=(15, 6))
        sns.boxplot(data=data[features])
        plt.title("Box Plot of Input Features")
        plt.xticks(rotation=45)
    
    elif visualization_type == "Violin Plot":
        plt.figure(figsize=(15, 6))
        sns.violinplot(data=data[features])
        plt.title("Violin Plot of Input Features")
        plt.xticks(rotation=45)
    
    plt.tight_layout()
    return plt

# Function to update input options based on predicted outcome
def update_input_options(predicted_outcome):
    if predicted_outcome == "Recommended Crop":
        return gr.update(choices=features, value=features[0]), gr.update(choices=features, value=features[1]), gr.update(choices=features, value=features[2])
    elif predicted_outcome == "Fertilizer Recommendation":
        options = ['N', 'P', 'K', 'ph']
        return gr.update(choices=options, value=options[0]), gr.update(choices=options, value=options[1]), gr.update(choices=options, value=options[2])
    elif predicted_outcome == "Water Pump Status":
        options = ['Soil Moisture Level (%)', 'temperature', 'humidity', 'Season']
        return gr.update(choices=options, value=options[0]), gr.update(choices=options, value=options[1]), gr.update(choices=options, value=options[2])
    else:  # Fire Detection
        options = ['temperature', 'humidity', 'Season']
        return gr.update(choices=options, value=options[0]), gr.update(choices=options, value=options[1]), gr.update(choices=options, value=options[2])

# Create the Gradio UI
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 🌱 Smart Agriculture Prediction System")
    
    with gr.Row():
        with gr.Column():
            n = gr.Number(label="Nitrogen (N) [kg/ha]" ,info="Range: 0-100")
            p = gr.Number(label="Phosphorus (P) [kg/ha]" ,info="Range: 30-90")
            k = gr.Number(label="Potassium (K) [kg/ha]" ,info="Range: 15-85")
            temperature = gr.Number(label="Temperature [°C]",info="Range: 15-40")
        with gr.Column():
            humidity = gr.Number(label="Humidity [%]",info="Range: 10-85")
            ph = gr.Number(label="pH Level" ,info="Range: 4-9")
            rainfall = gr.Number(label="Rainfall [mm]",info="Range: 30-300")
            soil_moisture = gr.Number(label="Soil Moisture Level (%)",info="Range: 55-75")
    
    soil_type = gr.Number(label="Soil Type [0->Alluvial 1->Black 2->Clayey 3->Laterite 4->Sandy]")
    season = gr.Number(label="Season [0->Autumn 1->Spring 2->Summer 3->Winter]")
    
    analyze_btn = gr.Button("Predict", variant="primary")
    
    with gr.TabItem("Predictions"):
        prediction_output = gr.JSON()

    # Visualization options
    with gr.TabItem("Visualization"):
        show_crop = gr.Checkbox(label="Show Recommended Crop", value=True)
        show_fertilizer = gr.Checkbox(label="Show Fertilizer Recommendation", value=True)
        show_water_pump = gr.Checkbox(label="Show Water Pump Status", value=True)
        show_fire = gr.Checkbox(label="Show Fire Detection", value=True)
        
        visualize_btn = gr.Button("Visualize", variant="secondary")
        plot_output = gr.Plot()

    # Data Insight options
    with gr.TabItem("Data Insight"):
        visualization_type = gr.Radio(["Scatter Plot", "Correlation Plot", "Pair Plot", "Box Plot", "Violin Plot"], label="Visualization Type")
        predicted_outcome = gr.Radio(["Recommended Crop", "Fertilizer Recommendation", "Water Pump Status", "Fire Detection"], label="Predicted Outcome", visible=False)
        input1 = gr.Dropdown(choices=features, label="X-axis", visible=False)
        input2 = gr.Dropdown(choices=features, label="Y-axis", visible=False)
        input3 = gr.Dropdown(choices=features, label="Color intensity", visible=False)
        
        insight_btn = gr.Button("Generate Insight", variant="secondary")
        insight_plot = gr.Plot()

        def update_insight_inputs(viz_type):
            if viz_type == "Scatter Plot":
                return gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
            else:
                return gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)

        visualization_type.change(update_insight_inputs, inputs=[visualization_type], outputs=[predicted_outcome, input1, input2, input3])
        predicted_outcome.change(update_input_options, inputs=[predicted_outcome], outputs=[input1, input2, input3])

    # Adding examples to the UI
    gr.Examples(
        examples=[
            [90, 60, 50, 25, 65, 6.5, 200, 65, 1, 0],  # Example 1: Black soil, Autumn season
            [40, 45, 30, 30, 50, 7.0, 100, 70, 4, 2]   # Example 2: Sandy soil, Summer season
        ],
        inputs=[n, p, k, temperature, humidity, ph, rainfall, soil_moisture, soil_type, season],
        outputs=prediction_output,
        label="Try these examples"
    )

    analyze_btn.click(predict_crop, 
                      inputs=[n, p, k, temperature, humidity, ph, rainfall, soil_moisture, soil_type, season],
                      outputs=prediction_output)

    visualize_btn.click(visualize_predictions, 
                        inputs=[n, p, k, temperature, humidity, ph, rainfall, soil_moisture, soil_type, season, 
                                show_crop, show_fertilizer, show_water_pump, show_fire],
                        outputs=plot_output)

    insight_btn.click(data_insight,
                      inputs=[visualization_type, predicted_outcome, input1, input2, input3],
                      outputs=insight_plot)
    
    # Add Footer
    gr.HTML("""
        <div style='
            background-color: #333; 
            color: #f0f0f0; 
            border-radius: 8px; 
            padding: 20px; 
            margin-top: 40px;
            text-align: center; 
            font-size: 16px;
            font-family: "Helvetica", sans-serif;'>
            <strong>Created By Harsh Jain [23/IT/062] & Daksh Yadav [23/IT/048]</strong>
            <br>
            <span style='font-size: 14px; color: #b0b0b0;'>Smart Agriculture Prediction System</span>
        </div>
    """)

if __name__ == "__main__":
    demo.launch()