manavg23's picture
initial commit
9eada9c
# -*- coding: utf-8 -*-
"""yieldpredictionrandomforest.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1-bKSlitmr01NPLLG_ZrTBoZ-3hCHjwM6
"""
import gradio as gr
from PIL import Image
import pandas as pd
import numpy as np
import requests
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_percentage_error
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
# Load the dataset
crop_data = pd.read_csv('combined_data.csv')
# Convert district names to title case
crop_data['District'] = crop_data['District'].str.title()
# Function to fetch humidity and temperature from a weather API
def get_weather_data(district):
api_key = '2146dd5e46379bba1811371d760fbf18'
base_url = 'http://api.openweathermap.org/data/2.5/weather?'
# Build API request URL
complete_url = base_url + 'q=' + district + '&appid=' + api_key
# Send GET request to the API
response = requests.get(complete_url)
# Parse response data
if response.status_code == 200:
data = response.json()
# Extract humidity and temperature
humidity = data['main']['humidity']
temperature = data['main']['temp'] - 273.15 # Convert from Kelvin to Celsius
return humidity, temperature
else:
print("Failed to fetch weather data. Please try again later.")
return None, None
# Function to calculate average rainfall for a given state
def calculate_average_rainfall(state):
# Define ranges for average rainfall for each state (in cm)
state_rainfall_ranges = {
'Rajasthan': (5, 20),
'Manipur': (100, 300),
'Madhya Pradesh': (70, 150),
'Puducherry': (80, 200),
'Bihar': (80, 180),
'Andhra Pradesh': (80, 150),
'Chhattisgarh': (100, 200),
'Uttar Pradesh': (70, 150),
'Andaman and Nicobar Islands': (150, 300),
'Telangana': (70, 150),
'Karnataka': (70, 150),
'Gujarat': (40, 100),
'Dadra and Nagar Haveli': (100, 200),
'Meghalaya': (200, 400),
'Tamil Nadu': (70, 150),
'Maharashtra': (70, 150),
'Kerala': (200, 400),
'Assam': (200, 400),
'Goa': (200, 400),
'Mizoram': (200, 400),
'West Bengal': (200, 400),
'Jammu and Kashmir': (30, 80),
'Himachal Pradesh': (50, 120),
'Haryana': (40, 100),
'Odisha': (100, 200),
'Delhi': (30, 80),
'Nagaland': (200, 400),
'Tripura': (200, 400),
'Punjab': (30, 80),
'Uttarakhand': (100, 200),
'Arunachal Pradesh': (200, 400),
'Jharkhand': (100, 200),
'Chandigarh': (30, 80),
'Sikkim': (200, 400),
'Daman and Diu': (100, 200)
}
# Get the range for the given state
rainfall_range = state_rainfall_ranges.get(state)
if rainfall_range:
# Calculate average rainfall within the range for the state
average_rainfall = np.random.uniform(rainfall_range[0], rainfall_range[1])
return average_rainfall
else:
print(f"Average rainfall data not available for {state}.")
return None
def recommend_top_n_crops(state, district, soil_type, season, area, n=3):
# Fetch average rainfall for the given state
avg_rainfall = calculate_average_rainfall(state)
if avg_rainfall is not None:
# Fetch humidity and temperature for the given district
humidity, temperature = get_weather_data(district)
if humidity is not None and temperature is not None:
# Define ranges for N, P, and K based on soil type
soil_type_ranges = {
'Alluvial': {'N': (0.1, 0.9), 'P': (0.01, 0.05), 'K': (0.1, 0.8)},
'Red': {'N': (0.1, 0.3), 'P': (0.02, 0.06), 'K': (0.2, 0.3)},
'Loam': {'N': (0.1, 0.5), 'P': (0.01, 0.04), 'K': (0.1, 0.5)},
'Black': {'N': (0.1, 0.3), 'P': (0.02, 0.03), 'K': (0.1, 0.3)}
}
# Select random values for N, P, and K based on soil type
np.random.seed(42) # for reproducibility
random_n_range = soil_type_ranges[soil_type]['N']
random_p_range = soil_type_ranges[soil_type]['P']
random_k_range = soil_type_ranges[soil_type]['K']
random_n = np.random.uniform(random_n_range[0], random_n_range[1])
random_p = np.random.uniform(random_p_range[0], random_p_range[1])
random_k = np.random.uniform(random_k_range[0], random_k_range[1])
# Map input strings to their encoded values
state_encoded = state_encodings[state]
district_encoded = district_encodings[district]
soil_type_encoded = soil_type_encodings[soil_type]
season_encoded = season_type_encodings[season]
# Prepare input features for classification
input_features_classification = np.array([[state_encoded, district_encoded, soil_type_encoded, avg_rainfall, temperature, humidity, random_n, random_p, random_k, season_encoded, 0, 0, area]])
# Make prediction using the trained classification model
predicted_probs = model.predict_proba(input_features_classification)[0]
# Sort predicted probabilities and get top N indices
top_n_indices = np.argsort(predicted_probs)[::-1][:n]
# Get top N crop recommendations
top_n_crops = [crop_encodings_inverse[idx] for idx in top_n_indices]
crop_yield_predictions = {}
# Predict yield for the top N crops using the regression model
predicted_yields = []
for crop in top_n_crops:
print(crop)
crop_encoded = crop_encodings[crop]
# Prepare input features for regression
input_features_regression = np.array([[state_encoded, district_encoded, soil_type_encoded, crop_encoded, avg_rainfall, temperature, humidity, random_n, random_p, random_k, season_encoded, 0, area]])
# Predict yield
predicted_yield = regressor.predict(input_features_regression)[0]
predicted_yields.append(predicted_yield)
# Print top N recommended crops with their predicted yields
for i in range(n):
print(f'{top_n_crops[i]}: Expected Yield - {predicted_yields[i]}')
return top_n_crops[0],predicted_yields[0],top_n_crops[1],predicted_yields[1],top_n_crops[2],predicted_yields[2]
else:
print("Failed to fetch weather data. Please try again later.")
return None
else:
print("Failed to fetch average rainfall data. Please try again later.")
return None
label_encoder = LabelEncoder()
crop_data['State_Encoded'] = label_encoder.fit_transform(crop_data['State'])
crop_data['District_Encoded'] = label_encoder.fit_transform(crop_data['District'])
crop_data['Soil_Type_Encoded'] = label_encoder.fit_transform(crop_data['Soil Type'])
crop_data['Crop_Type_Encoded'] = label_encoder.fit_transform(crop_data['Crop'])
crop_data['Season_Encoded'] = label_encoder.fit_transform(crop_data['Season'])
# Create dictionaries to map original names to encoded labels
state_encodings = dict(zip(crop_data['State'], crop_data['State_Encoded']))
district_encodings = dict(zip(crop_data['District'], crop_data['District_Encoded']))
soil_type_encodings = dict(zip(crop_data['Soil Type'], crop_data['Soil_Type_Encoded']))
season_type_encodings = dict(zip(crop_data['Season'], crop_data['Season_Encoded']))
crop_encodings = dict(zip(crop_data['Crop'], crop_data['Crop_Type_Encoded']))
crop_encodings_inverse = dict(zip(crop_data['Crop_Type_Encoded'], crop_data['Crop']))
# Split data into features and target
X = crop_data[['State_Encoded', 'District_Encoded', 'Soil_Type_Encoded', 'Rainfall (cm)', 'Temperature (°C)', 'Humidity (%)', 'N', 'P', 'K', 'Season_Encoded', 'Production', 'Yield', 'Area']]
y = crop_data['Crop_Type_Encoded']
# Split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Train Random Forest model with fine-tuned hyperparameters
model = RandomForestClassifier(max_depth=30, min_samples_split=5, n_estimators=200, random_state=42)
model.fit(X_train, y_train)
# Test the model
test_accuracy = model.score(X_test, y_test)
print("Test Accuracy:", test_accuracy)
# Evaluate the model with additional measures
y_pred = model.predict(X_test)
conf_matrix = confusion_matrix(y_test, y_pred)
print("Confusion Matrix:")
print(conf_matrix)
print(classification_report(y_test, y_pred))
# Split data into features and target
a = crop_data[['State_Encoded', 'District_Encoded', 'Soil_Type_Encoded', 'Crop_Type_Encoded', 'Rainfall (cm)', 'Temperature (°C)', 'Humidity (%)', 'N', 'P', 'K', 'Season_Encoded', 'Production', 'Area']]
b = crop_data['Yield'] # Use 'Yield' as the target for regression
# Split data into train and test sets
a_train, a_test, b_train, b_test = train_test_split(a, b, test_size=0.2, random_state=42)
# Train Random Forest regressor with fine-tuned hyperparameters
regressor = RandomForestRegressor(max_depth=30, n_estimators=300, random_state=42)
regressor.fit(a_train, b_train)
# Test the regressor
test_score = regressor.score(a_test, b_test)
print("Test Score (R-squared):", test_score)
# Predict yield for the testing data
b_pred = regressor.predict(a_test)
# Evaluate the model
mse = mean_squared_error(b_test, b_pred)
print("Mean Squared Error:", mse)
# Example usage:
# state = 'Rajasthan'
# district = 'Kota'
# soil_type = 'Alluvial'
# season = 'Whole Year'
# Area=1
soilclassification = load_model('SoilModel.h5')
def preprocess_image(image):
# Convert Gradio Image object to numpy array
image_array = np.array(image)
# Resize the image to the required shape (256x256)
resized_image = np.array(Image.fromarray(image_array).resize((256, 256)))
# Normalize the image pixel values to be in the range [0, 1]
normalized_image = resized_image / 255.0
# Add batch dimension to the image (model expects input shape of (None, 256, 256, 3))
input_image = normalized_image[np.newaxis, ...]
return input_image
def finalfunc(soil_image, state_input, district_input, season_input, area_input):
preprocessed_image = preprocess_image(soil_image)
prediction = soilclassification.predict(preprocessed_image)
# Extracting the predicted soil type from the prediction result
predicted_soil_type = prediction.argmax(axis=1)[0]
finalsoiltype=""
if predicted_soil_type==0:
finalsoiltype="Alluvial"
elif predicted_soil_type==1:
finalsoiltype="Black"
elif predicted_soil_type==2:
finalsoiltype="Loam"
elif predicted_soil_type==3:
finalsoiltype= "Red"
return recommend_top_n_crops(state_input, district_input, finalsoiltype, season_input, area_input, n=3)
# top_3_crops = recommend_top_n_crops(state, district, soil_type, season,Area, n=3)
# print('Top 3 Recommended Crops:', top_3_crops)
# Input components
image_input = gr.Image(label="Image of Soil")
district_input = gr.Textbox(label="District")
state_input = gr.Textbox(label="State")
season_input = gr.Textbox(label="Season")
area_input = gr.Textbox(label="Area")
# # Output components
crop1_name = gr.Textbox(label="Crop 1 Name")
crop1_yield = gr.Textbox(label="Crop 1 Yield Percentage")
crop2_name = gr.Textbox(label="Crop 2 Name")
crop2_yield = gr.Textbox(label="Crop 2 Yield Percentage")
crop3_name = gr.Textbox(label="Crop 3 Name")
crop3_yield = gr.Textbox(label="Crop 3 Yield Percentage")
# Create Gradio interface
gr.Interface(
fn=finalfunc,
outputs=[crop1_name,crop1_yield,crop2_name,crop2_yield,crop3_name,crop3_yield],
inputs=[image_input,state_input,district_input ,season_input,area_input],
title="Crop Yield Prediction",
description="Predict crop yields based on an image of soil, district, state, and crop information."
).launch(share=True)