Spaces:
Sleeping
Sleeping
Download model_train.py from DakuSir/yieldpredictor: direct link, hf CLI and curl.
- Browser
- Download file 5.34 kB
-
https://huggingface.co/spaces/DakuSir/yieldpredictor/resolve/main/model_train.py
- Command line
-
hf download hf://spaces/DakuSir/yieldpredictor/model_train.py
-
curl -L -o model_train.py https://huggingface.co/spaces/DakuSir/yieldpredictor/resolve/main/model_train.py
5.34 kB
| """ | |
| model_train.py | |
| Generates synthetic Indian crop data, trains a Random Forest model, | |
| and saves model + encoders to disk. | |
| Run this once before starting app.py | |
| """ | |
| import numpy as np | |
| import pandas as pd | |
| from sklearn.ensemble import RandomForestRegressor | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.metrics import r2_score, mean_absolute_error | |
| from sklearn.preprocessing import LabelEncoder | |
| import joblib | |
| import os | |
| np.random.seed(42) | |
| N = 5000 | |
| # ββ Categorical options βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| CROPS = ["Wheat", "Rice", "Maize", "Soybean", "Cotton"] | |
| SOILS = ["Loamy", "Clayey", "Sandy", "Black", "Red"] | |
| SEASONS = ["Kharif", "Rabi", "Zaid"] | |
| DISEASE = ["None", "Mild", "Moderate", "Severe"] | |
| IRRIGATE = ["Rainfed", "Canal", "Drip", "Sprinkler"] | |
| # ββ Base yields (kg/acre) per crop ββββββββββββββββββββββββββββββββββββββββββββ | |
| BASE_YIELD = { | |
| "Wheat": 950, | |
| "Rice": 1100, | |
| "Maize": 800, | |
| "Soybean": 600, | |
| "Cotton": 500, | |
| } | |
| # ββ Synthetic data generation βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def generate_data(n=N): | |
| crop = np.random.choice(CROPS, n) | |
| soil = np.random.choice(SOILS, n) | |
| season = np.random.choice(SEASONS, n) | |
| disease = np.random.choice(DISEASE, n) | |
| irrigate = np.random.choice(IRRIGATE, n) | |
| rainfall = np.random.uniform(100, 1200, n) | |
| temperature = np.random.uniform(10, 45, n) | |
| fertilizer = np.random.uniform(0, 150, n) | |
| area = np.random.uniform(1, 50, n) | |
| # ββ Yield simulation ββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| base = np.array([BASE_YIELD[c] for c in crop], dtype=float) | |
| # rainfall: sweet-spot around 600 mm | |
| rain_factor = 1 - 0.0003 * (rainfall - 600) ** 2 / 1000 | |
| rain_factor = np.clip(rain_factor, 0.5, 1.1) | |
| # temperature: optimal ~28 Β°C | |
| temp_factor = 1 - 0.002 * (temperature - 28) ** 2 | |
| temp_factor = np.clip(temp_factor, 0.6, 1.1) | |
| # fertilizer: log benefit | |
| fert_factor = 1 + 0.003 * fertilizer - 0.00001 * fertilizer ** 2 | |
| fert_factor = np.clip(fert_factor, 0.8, 1.3) | |
| # disease penalty | |
| disease_penalty = {"None": 1.0, "Mild": 0.85, "Moderate": 0.65, "Severe": 0.40} | |
| dis_factor = np.array([disease_penalty[d] for d in disease]) | |
| # irrigation boost | |
| irr_boost = {"Rainfed": 1.0, "Canal": 1.1, "Drip": 1.2, "Sprinkler": 1.15} | |
| irr_factor = np.array([irr_boost[i] for i in irrigate]) | |
| # soil-crop compatibility bonus | |
| compat = { | |
| ("Wheat", "Loamy"): 1.1, ("Wheat", "Black"): 1.05, | |
| ("Rice", "Clayey"):1.15,("Rice", "Black"): 1.1, | |
| ("Maize", "Loamy"): 1.1, ("Soybean","Black"): 1.1, | |
| ("Cotton", "Black"): 1.2, ("Cotton", "Red"): 1.0, | |
| } | |
| soil_factor = np.array([compat.get((c, s), 1.0) for c, s in zip(crop, soil)]) | |
| yield_kg = (base | |
| * rain_factor | |
| * temp_factor | |
| * fert_factor | |
| * dis_factor | |
| * irr_factor | |
| * soil_factor | |
| + np.random.normal(0, 40, n)) # noise | |
| yield_kg = np.clip(yield_kg, 50, 2500) | |
| return pd.DataFrame({ | |
| "crop": crop, "soil": soil, "season": season, | |
| "disease": disease, "irrigation": irrigate, | |
| "rainfall": rainfall, "temperature": temperature, | |
| "fertilizer": fertilizer, "area": area, | |
| "yield_kg_per_acre": yield_kg, | |
| }) | |
| # ββ Encode + train ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def train(): | |
| print("Generating synthetic data...") | |
| df = generate_data() | |
| cat_cols = ["crop", "soil", "season", "disease", "irrigation"] | |
| encoders = {} | |
| for col in cat_cols: | |
| le = LabelEncoder() | |
| df[col + "_enc"] = le.fit_transform(df[col]) | |
| encoders[col] = le | |
| features = [c + "_enc" for c in cat_cols] + [ | |
| "rainfall", "temperature", "fertilizer", "area" | |
| ] | |
| X = df[features] | |
| y = df["yield_kg_per_acre"] | |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) | |
| print("Training Random Forest (200 trees)...") | |
| model = RandomForestRegressor( | |
| n_estimators=200, | |
| max_depth=12, | |
| min_samples_split=4, | |
| random_state=42, | |
| n_jobs=-1, | |
| ) | |
| model.fit(X_train, y_train) | |
| preds = model.predict(X_test) | |
| r2 = r2_score(y_test, preds) | |
| mae = mean_absolute_error(y_test, preds) | |
| print(f"\nβ RΒ² = {r2:.3f} MAE = {mae:.1f} kg/acre") | |
| os.makedirs("model", exist_ok=True) | |
| joblib.dump(model, "model/yield_model.pkl") | |
| joblib.dump(encoders, "model/encoders.pkl") | |
| joblib.dump(features, "model/features.pkl") | |
| print("Model saved β model/yield_model.pkl") | |
| return r2, mae | |
| if __name__ == "__main__": | |
| train() | |