File size: 6,382 Bytes
ce3c25e
 
 
 
 
 
 
e9dd810
 
 
 
 
ce3c25e
e9dd810
 
 
 
 
ce3c25e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f258992
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
import numpy as np
import pandas as pd
import gradio as gr
import joblib
import tensorflow as tf

# Load artifacts
model = tf.keras.models.load_model('model/my_model_low_build.keras')
scaler = joblib.load('model/scaler_minor_low_build.pkl')
soil_encoder = joblib.load('model/soil_encoder_low_build.pkl')
crop_encoder = joblib.load('model/crop_encoder_low_build.pkl')
fertilizer_encoder = joblib.load('model/fertilizer_encoder_low_build.pkl')

# model = tf.keras.models.load_model('model/my_model.keras')
# scaler = joblib.load('model/scaler.pkl')
# soil_encoder = joblib.load('model/soil_encoder.pkl')
# crop_encoder = joblib.load('model/crop_encoder.pkl')
# fertilizer_encoder = joblib.load('model/fertilizer_encoder.pkl')



# Crop requirements (same as before)
crop_requirements = {
    'cotton':    {'Nitrogen': (80, 120), 'Phosphorus': (40, 60),  'Potassium': (80, 120)},
    'orange':    {'Nitrogen': (120, 150), 'Phosphorus': (50, 70),  'Potassium': (150, 200)},
    'wheat':     {'Nitrogen': (100, 150), 'Phosphorus': (40, 60),  'Potassium': (40, 60)},
    'maize':     {'Nitrogen': (150, 200), 'Phosphorus': (50, 80),  'Potassium': (50, 80)},
    'rice':      {'Nitrogen': (80, 120),  'Phosphorus': (40, 60),  'Potassium': (60, 80)},
    'potato':    {'Nitrogen': (150, 200), 'Phosphorus': (60, 80),  'Potassium': (150, 200)},
    'tomato':    {'Nitrogen': (100, 150), 'Phosphorus': (50, 70),  'Potassium': (150, 200)},
    'carrot':    {'Nitrogen': (60, 100),  'Phosphorus': (30, 50),  'Potassium': (60, 80)},
    'cabbage':   {'Nitrogen': (150, 200), 'Phosphorus': (70, 100), 'Potassium': (150, 200)},
    'banana':    {'Nitrogen': (150, 200), 'Phosphorus': (70, 100), 'Potassium': (200, 250)},
    'onion':     {'Nitrogen': (80, 120),  'Phosphorus': (40, 60),  'Potassium': (80, 100)},
    'pepper':    {'Nitrogen': (100, 150), 'Phosphorus': (50, 70),  'Potassium': (150, 200)},
    'lettuce':   {'Nitrogen': (60, 100),  'Phosphorus': (30, 50),  'Potassium': (40, 60)},
    'sunflower': {'Nitrogen': (80, 120),  'Phosphorus': (40, 60),  'Potassium': (60, 80)},
    'soybean':   {'Nitrogen': (0, 20),    'Phosphorus': (40, 60),  'Potassium': (40, 60)},  # Legume: fixes its own N
    'tobacco':   {'Nitrogen': (120, 150), 'Phosphorus': (40, 60),  'Potassium': (60, 80)},
    'sugarcane': {'Nitrogen': (100, 150), 'Phosphorus': (40, 60),  'Potassium': (150, 200)},
    'peanut':    {'Nitrogen': (0, 20),    'Phosphorus': (40, 60),  'Potassium': (60, 80)},  # Legume: fixes N
    'coffee':    {'Nitrogen': (80, 120),  'Phosphorus': (40, 60),  'Potassium': (80, 120)},
    'tea':       {'Nitrogen': (100, 150), 'Phosphorus': (50, 70),  'Potassium': (100, 150)}
}


def crop_specific_recommendation(raw_input):
    recommendations = []
    crop = raw_input[5].lower()

    if crop in crop_requirements:
        ideal = crop_requirements[crop]
        n = raw_input[2]
        p = raw_input[3]
        k = raw_input[4]

        # Nitrogen check
        if n < ideal['Nitrogen'][0]:
            recommendations.append(f"Nitrogen is low for {crop} (current: {n}, ideal: {ideal['Nitrogen'][0]}-{ideal['Nitrogen'][1]})")
        elif n > ideal['Nitrogen'][1]:
            recommendations.append(f"Nitrogen is high for {crop} (current: {n}, ideal: {ideal['Nitrogen'][0]}-{ideal['Nitrogen'][1]})")

        # Phosphorus check
        if p < ideal['Phosphorus'][0]:
            recommendations.append(f"Phosphorus is low for {crop} (current: {p}, ideal: {ideal['Phosphorus'][0]}-{ideal['Phosphorus'][1]})")
        elif p > ideal['Phosphorus'][1]:
            recommendations.append(f"Phosphorus is high for {crop} (current: {p}, ideal: {ideal['Phosphorus'][0]}-{ideal['Phosphorus'][1]})")

        # Potassium check
        if k < ideal['Potassium'][0]:
            recommendations.append(f"Potassium is low for {crop} (current: {k}, ideal: {ideal['Potassium'][0]}-{ideal['Potassium'][1]})")
        elif k > ideal['Potassium'][1]:
            recommendations.append(f"Potassium is high for {crop} (current: {k}, ideal: {ideal['Potassium'][0]}-{ideal['Potassium'][1]})")
    else:
        recommendations.append(f"No specific recommendations available for {crop}")

    return "\n".join(recommendations) if recommendations else f"All nutrient levels are optimal for {crop}"


def predict_fertilizer(temperature, soil, nitrogen, phosphorus, potassium, crop):
    try:
        # Validate inputs
        crop = crop.lower()
        if soil not in soil_encoder.classes_:
            raise ValueError(f"Invalid soil type. Choose from {list(soil_encoder.classes_)}")
        if crop not in crop_encoder.classes_:
            raise ValueError(f"Invalid crop type. Choose from {list(crop_encoder.classes_)}")

        # Prepare input
        num_features = np.array([[temperature, nitrogen, phosphorus, potassium]])
        scaled_num = scaler.transform(num_features)
        encoded_soil = soil_encoder.transform([soil])[0]
        encoded_crop = crop_encoder.transform([crop])[0]

        model_input = np.array([[
            scaled_num[0][0],    # Temperature
            encoded_soil,        # Soil
            scaled_num[0][1],    # Nitrogen
            scaled_num[0][2],    # Phosphorus
            scaled_num[0][3],    # Potassium
            encoded_crop         # Crop
        ]])

        # Predict
        pred = model.predict(model_input)
        fertilizer = fertilizer_encoder.inverse_transform([np.argmax(pred)])[0]

        # Generate recommendations
        raw_input = [temperature, soil, nitrogen, phosphorus, potassium, crop]
        crop_advice = crop_specific_recommendation(raw_input)

        return fertilizer, crop_advice

    except Exception as e:
        return str(e), ""

# Create Gradio interface
inputs = [
    gr.Number(label="Temperature (°C)"),
    gr.Dropdown(label="Soil Type", choices=list(soil_encoder.classes_)),
    gr.Number(label="Nitrogen Level (kg/ha)"),
    gr.Number(label="Phosphorus Level (kg/ha)"),
    gr.Number(label="Potassium Level (kg/ha)"),
    gr.Dropdown(label="Crop Type", choices=list(crop_encoder.classes_))
]

outputs = [
    gr.Textbox(label="Recommended Fertilizer"),
    gr.Textbox(label="Crop Advice")
]

gr.Interface(
    fn=predict_fertilizer,
    inputs=inputs,
    outputs=outputs,
    title="Fertilizer Recommendation System",
    description="Predict optimal fertilizer based on soil and crop conditions"
).launch()