hackathon_project / ml_model.py
zainab1234awan's picture
Upload 7 files
895617f verified
Raw
History Blame Contribute Delete
4.86 kB
"""
PHASE 3: ML Model Training
Goal: Predict environmental impact category (Low / Medium / High Impact)
Algorithm: RandomForestClassifier
HF Spaces compatible β€” uses BASE_DIR for all file paths.
"""
import os
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import classification_report, accuracy_score
import joblib
import warnings
warnings.filterwarnings("ignore")
# ── HF-safe absolute paths ──────────────────────────────────────────────────
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
MODEL_PATH = os.path.join(BASE_DIR, "models", "eco_classifier.pkl")
ENCODER_PATH = os.path.join(BASE_DIR, "models", "category_encoder.pkl")
LABEL_ENCODER_PATH= os.path.join(BASE_DIR, "models", "label_encoder.pkl")
DATA_PATH = os.path.join(BASE_DIR, "dataset", "products.csv")
# ────────────────────────────────────────────────────────────────────────────
def preprocess_data(df: pd.DataFrame):
df = df.copy()
cat_encoder = LabelEncoder()
df["category_encoded"] = cat_encoder.fit_transform(df["category"])
feature_cols = [
"category_encoded",
"deforestation_risk",
"pollution_level",
"biodiversity_impact",
]
X = df[feature_cols].values
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(df["eco_label"])
return X, y, cat_encoder, label_encoder, feature_cols
def train_model(data_path: str = DATA_PATH):
os.makedirs(os.path.join(BASE_DIR, "models"), exist_ok=True)
print("πŸ“‚ Loading dataset...")
df = pd.read_csv(data_path)
print(f" Dataset shape: {df.shape}")
print(f" Label distribution:\n{df['eco_label'].value_counts()}\n")
print("βš™οΈ Preprocessing data...")
X, y, cat_encoder, label_encoder, feature_cols = preprocess_data(df)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
print(f" Train: {len(X_train)} | Test: {len(X_test)}\n")
print("🌲 Training RandomForest model...")
model = RandomForestClassifier(
n_estimators=200,
max_depth=10,
min_samples_split=2,
random_state=42,
class_weight="balanced",
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(
y_test, y_pred,
target_names=label_encoder.classes_,
output_dict=True,
)
report_str = classification_report(y_test, y_pred, target_names=label_encoder.classes_)
print(f"βœ… Accuracy: {accuracy:.2%}\n{report_str}")
joblib.dump(model, MODEL_PATH)
joblib.dump(cat_encoder, ENCODER_PATH)
joblib.dump(label_encoder, LABEL_ENCODER_PATH)
print(f"πŸ’Ύ Saved β†’ {MODEL_PATH}")
return {
"accuracy": accuracy,
"report": report,
"feature_importances": dict(zip(feature_cols, model.feature_importances_)),
"classes": list(label_encoder.classes_),
}
def load_model():
if not os.path.exists(MODEL_PATH):
print("Model not found β€” training now...")
train_model()
model = joblib.load(MODEL_PATH)
cat_encoder = joblib.load(ENCODER_PATH)
label_encoder = joblib.load(LABEL_ENCODER_PATH)
return model, cat_encoder, label_encoder
def predict_impact(
category: str,
deforestation_risk: float,
pollution_level: float,
biodiversity_impact: float,
) -> dict:
model, cat_encoder, label_encoder = load_model()
known_cats = list(cat_encoder.classes_)
if category not in known_cats:
category = known_cats[0]
cat_encoded = cat_encoder.transform([category])[0]
X = np.array([[cat_encoded, deforestation_risk, pollution_level, biodiversity_impact]])
pred_idx = model.predict(X)[0]
proba = model.predict_proba(X)[0]
predicted_label = label_encoder.inverse_transform([pred_idx])[0]
confidence_dict = {
cls: round(float(p), 3)
for cls, p in zip(label_encoder.classes_, proba)
}
return {
"predicted_impact": predicted_label,
"confidence": round(float(proba[pred_idx]), 3),
"all_probabilities": confidence_dict,
"known_categories": known_cats,
}
if __name__ == "__main__":
print("=== EcoVision ML Model Training ===\n")
results = train_model()
print(f"\nFinal Accuracy: {results['accuracy']:.2%}")