SIH-Crop-Yield-API / src /models.py
AshrafGalibSk's picture
Upload folder using huggingface_hub
bbd5f9c verified
Raw
History Blame Contribute Delete
3.31 kB
#!/usr/bin/env python3
"""
Model classes for crop yield prediction
"""
import pandas as pd
import numpy as np
from typing import Dict, Any, List
class DataPreprocessor:
"""Data preprocessing class that matches the trained model."""
def __init__(self):
self.label_encoders = {}
self.scaler = None
self.imputer = None
self.feature_names = None
def prepare_features(self, df):
"""Prepare features for prediction."""
data = df.copy()
# Feature engineering (same as training)
data['Area_Production_Ratio'] = data['Area'] / (data['Production'] + 1e-6)
data['Yield_Area_Interaction'] = data.get('Yield', 0) * data['Area']
data['Production_Per_Area'] = data['Production'] / (data['Area'] + 1e-6)
# Create season dummies
season_dummies = pd.get_dummies(data['Season'], prefix='Season')
expected_seasons = ['Season_Autumn', 'Season_Kharif', 'Season_Rabi',
'Season_Summer', 'Season_Total', 'Season_Whole Year', 'Season_Winter']
for season in expected_seasons:
if season not in season_dummies.columns:
season_dummies[season] = 0
data = pd.concat([data, season_dummies[expected_seasons]], axis=1)
# Handle categorical variables
categorical_cols = ['State', 'District', 'Crop']
for col in categorical_cols:
if col in data.columns and col in self.label_encoders:
unique_values = set(data[col].astype(str))
known_values = set(self.label_encoders[col].classes_)
new_values = unique_values - known_values
if new_values:
mode_value = self.label_encoders[col].classes_[0]
data[col] = data[col].astype(str).replace(list(new_values), mode_value)
data[f'{col}_encoded'] = self.label_encoders[col].transform(data[col].astype(str))
elif col in data.columns:
data[f'{col}_encoded'] = pd.Categorical(data[col].astype(str)).codes
# Select features
feature_cols = ['Crop_Year', 'Area', 'Production', 'Annual_Rainfall',
'Fertilizer', 'Pesticide', 'State_encoded', 'Crop_encoded',
'Area_Production_Ratio', 'Yield_Area_Interaction',
'Production_Per_Area'] + expected_seasons
if 'District_encoded' in data.columns:
feature_cols.append('District_encoded')
available_cols = [col for col in feature_cols if col in data.columns]
X = data[available_cols].copy()
return X, data
def transform(self, X):
"""Transform features using fitted preprocessors."""
if self.imputer is None or self.scaler is None:
raise ValueError("Preprocessor not fitted.")
X_imputed = pd.DataFrame(
self.imputer.transform(X),
columns=X.columns,
index=X.index
)
X_scaled = pd.DataFrame(
self.scaler.transform(X_imputed),
columns=X.columns,
index=X.index
)
return X_scaled