from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, confusion_matrix, classification_report, mean_squared_error, mean_absolute_error from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor from sklearn.linear_model import LogisticRegression, LinearRegression from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor from sklearn.svm import SVC, SVR from xgboost import XGBClassifier, XGBRegressor from lightgbm import LGBMClassifier, LGBMRegressor from utils import preprocess_data import numpy as np import pandas as pd def run_automl(df, target_col): try: X, y, summary, problem_type = preprocess_data(df, target_col) except Exception as e: return {"error": f"Preprocessing failed: {str(e)}"} # ✅ Fix: Convert y to Pandas Series for .nunique() if pd.Series(y).nunique() <= 1: return {"error": "Target must have more than one unique value."} try: X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) except Exception as e: return {"error": f"Data splitting failed: {str(e)}"} if problem_type == "classification": models = { "Logistic Regression": LogisticRegression(max_iter=1000), "Random Forest": RandomForestClassifier(), "SVM": SVC(), "KNN": KNeighborsClassifier(), "XGBoost": XGBClassifier(use_label_encoder=False, eval_metric='mlogloss'), "LightGBM": LGBMClassifier() } else: models = { "Linear Regression": LinearRegression(), "Random Forest Regressor": RandomForestRegressor(), "SVR": SVR(), "KNN Regressor": KNeighborsRegressor(), "XGBoost Regressor": XGBRegressor(), "LightGBM Regressor": LGBMRegressor() } scores = {} best_model = None best_score = -999999 best_name = "" predictions = pd.DataFrame() for name, model in models.items(): try: model.fit(X_train, y_train) preds = model.predict(X_test) if problem_type == "classification": score = accuracy_score(y_test, preds) * 100 else: score = -mean_squared_error(y_test, preds) # Lower is better scores[name] = round(score, 2) if score > best_score: best_score = score best_model = model best_name = name predictions = pd.DataFrame({"Actual": y_test, "Predicted": preds}) except Exception as e: scores[name] = 0.0 print(f"⚠️ {name} failed: {e}") if best_model is None: return {"error": "No model trained successfully."} result = { "type": problem_type, "preprocessing": summary, "model_scores": scores, "best_model": best_name, "best_accuracy": round(-best_score if problem_type == "regression" else best_score, 2), "model_object": best_model, "predictions": predictions } if problem_type == "classification": preds = best_model.predict(X_test) result["confusion_matrix"] = confusion_matrix(y_test, preds).tolist() result["classification_report"] = classification_report(y_test, preds, output_dict=True) else: preds = best_model.predict(X_test) result["regression_report"] = { "RMSE": round(np.sqrt(mean_squared_error(y_test, preds)), 2), "MAE": round(mean_absolute_error(y_test, preds), 2) } return result