import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, roc_auc_score
from sklearn.preprocessing import StandardScaler, MinMaxScaler, LabelEncoder
from sklearn.ensemble import BaggingClassifier, AdaBoostClassifier
def main():
    df = pd.read_csv('C:/Users/Admin/Downloads/electric_vehicles.csv')
    target_col = 'drivetrain'
    df = df.dropna(subset=[target_col]).copy()
    numerical_features = [
        'top_speed_kmh', 
        'battery_capacity_kWh', 
        'torque_nm', 
        'efficiency', 
        'range_km', 
        'acceleration_0_100_s', 
        'fast_charging_power_kw_dc',
        'seats',
        'length_mm',
        'width_mm',
        'height_mm'
    ]
    feature_cols = []
    for col in numerical_features:
        if col in df.columns:
            df[col] = pd.to_numeric(df[col], errors='coerce')
            df[col] = df[col].fillna(df[col].median())
            feature_cols.append(col)
    # Encode categorical features if available (e.g., 'brand')
    if 'brand' in df.columns:
        df = pd.get_dummies(df, columns=['brand'], drop_first=True)
        # Add encoded brand columns to features list
        brand_cols = [c for c in df.columns if c.startswith('brand_')]
        feature_cols.extend(brand_cols)
    # Target Encoding (Convert categorical classes to numeric labels)
    label_enc = LabelEncoder()
    y = label_enc.fit_transform(df[target_col].astype(str))
    # Feature matrix (Ensure strictly numeric data types)
    X = df[feature_cols].select_dtypes(include=[np.number])
    # 3. Exploratory Data Analysis - Heatmap (FIXED: numeric_only=True)
    plt.figure(figsize=(12, 8))
    sns.heatmap(X.corr(numeric_only=True), annot=False, cmap='coolwarm')
    plt.title("EV Features Correlation Heatmap")
    plt.tight_layout()
    plt.show()
    # 4. Scaling
    standard_scaler = StandardScaler()
    minmax_scaler = MinMaxScaler()
    X_std = standard_scaler.fit_transform(X)
    X_mm = minmax_scaler.fit_transform(X)
    # 5. Train / Test Split
    X_train_std, X_test_std, y_train, y_test = train_test_split(
        X_std, y, test_size=0.2, random_state=69, stratify=y
    )
    # 6. Evaluation Function
    def evaluate_model(y_true, y_pred, y_prob):
        acc = accuracy_score(y_true, y_pred)
        cm = confusion_matrix(y_true, y_pred)
        # Weighted precision and recall for multiclass/binary
        prec = precision_score(y_true, y_pred, average='weighted', zero_division=0)
        sens = recall_score(y_true, y_pred, average='weighted', zero_division=0)
        # Standard Error of Accuracy
        se = np.sqrt((acc * (1 - acc)) / len(y_true))
        # Multiclass/binary AUC calculation (FIXED)
        try:
            n_classes = len(np.unique(y_true))
            if n_classes == 2:
                model_auc = roc_auc_score(y_true, y_prob[:, 1])
            else:
                model_auc = roc_auc_score(y_true, y_prob, multi_class='ovr', average='weighted')
        except Exception:
            model_auc = np.nan
        return {
            'Accuracy': acc,
            'Precision': prec,
            'Sensitivity': sens,
            'Std Error': se,
            'AUC': model_auc,
            'Confusion Matrix': cm
        }
    # 7. Model Initialization
    dt_bag = BaggingClassifier(
        estimator=DecisionTreeClassifier(random_state=69), 
        n_estimators=50, 
        random_state=69
    )
    nb_bag = BaggingClassifier(
        estimator=GaussianNB(), 
        n_estimators=50, 
        random_state=69
    )
    log_reg = LogisticRegression(max_iter=1000)
    dt_ada = AdaBoostClassifier(
        estimator=DecisionTreeClassifier(max_depth=1, random_state=69), 
        n_estimators=50, 
        random_state=69
    )
    # 8. Train Models
    dt_bag.fit(X_train_std, y_train)
    nb_bag.fit(X_train_std, y_train)
    log_reg.fit(X_train_std, y_train)
    dt_ada.fit(X_train_std, y_train)
    # 9. Predictions
    pred_dt_bag = dt_bag.predict(X_test_std)
    pred_nb_bag = nb_bag.predict(X_test_std)
    pred_log_reg = log_reg.predict(X_test_std)
    pred_dt_ada = dt_ada.predict(X_test_std)
    # 10. Results Compilation
    results = {
        'Bagging DT': evaluate_model(y_test, pred_dt_bag, dt_bag.predict_proba(X_test_std)),
        'Bagging NB': evaluate_model(y_test, pred_nb_bag, nb_bag.predict_proba(X_test_std)),
        'Logistic Regression': evaluate_model(y_test, pred_log_reg, log_reg.predict_proba(X_test_std)),
        'AdaBoost DT': evaluate_model(y_test, pred_dt_ada, dt_ada.predict_proba(X_test_std))
    }
    # Cross-Validation Score
    cv = KFold(n_splits=5, shuffle=True, random_state=69)
    dt_cv_std = np.mean(cross_val_score(dt_bag, X_std, y, cv=cv, scoring='accuracy'))
    # 11. Print Summary Table
    summary_df = pd.DataFrame(results).T.drop(columns=['Confusion Matrix'])
    print("\n" + "="*65)
    print("      EV DATASET MODEL EVALUATION SUMMARY (STANDARDIZED)")
    print("="*65)
    print(summary_df.round(4).to_string())
    print("-" * 65)
    print(f"Bagging DT 5-Fold Cross-Validation Accuracy: {dt_cv_std:.4f}")
    print("="*65 + "\n")
    # Display Confusion Matrices with Class Names
    print("--- Detailed Confusion Matrices ---")
    for name, res in results.items():
        print(f"\n{name} Confusion Matrix:")
        print(pd.DataFrame(res['Confusion Matrix'], index=label_enc.classes_, columns=label_enc.classes_))
if __name__ == '__main__':
    main()

[TABLE 1]
 |  |  |  |  |  |  |  |  | 
Missing Value | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
Correlation | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
Chi-square | ✅ | ✅ | ✅ | ❌  | ✅ | ✅ | ✅ | ✅ | ✅
Scaling | ✅ | ✅ | ✅ | ✅ | ❌  | ✅ | ✅ | ✅ | ✅
PCA | ✅ | ✅ | ✅ | ✅ | ✅ | ❌  | ✅   | ✅   | ✅  
Bagging | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌  | ❌  | ✅
Boosting | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌  | ✅
Bootstrap | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌  | ✅
Cross-Validation | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ 
 |  |  |  |  |  |  |  |  | 
Accuracy | 93% | 88.30% | 90.43% | 90.43% | 82.98 | 93.75 | 93% | 92% | 93%