Compare commits

..
2 Commits
Author SHA1 Message Date
Petrus d3f6732211 Merge branch 'main' of https://gitea.jany.se/Jany/MLPproject 2025-10-22 14:55:31 +02:00
Petrus 53d5116bbd Tried expanding hyperparameter tuning 2025-10-22 14:55:06 +02:00
3 changed files with 295 additions and 51 deletions

No files matched your search

+23 -25
View File
@@ -6,12 +6,12 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Creates a correlation matrix\n", "### Creates a correlation matrix\n",
"We should probably remove or combine some features" "This used to see if we should remove or combine some features"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"id": "557ed2b5", "id": "557ed2b5",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@@ -30,27 +30,25 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"<class 'pandas.core.frame.DataFrame'>\n", "<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 32561 entries, 0 to 32560\n", "Index: 30162 entries, 1 to 32560\n",
"Data columns (total 15 columns):\n", "Data columns (total 13 columns):\n",
" # Column Non-Null Count Dtype \n", " # Column Non-Null Count Dtype\n",
"--- ------ -------------- ----- \n", "--- ------ -------------- -----\n",
" 0 age 32561 non-null int64 \n", " 0 age 30162 non-null int64\n",
" 1 workclass 32561 non-null object\n", " 1 workclass 30162 non-null int64\n",
" 2 fnlwgt 32561 non-null int64 \n", " 2 education.num 30162 non-null int64\n",
" 3 education 32561 non-null object\n", " 3 marital.status 30162 non-null int64\n",
" 4 education.num 32561 non-null int64 \n", " 4 occupation 30162 non-null int64\n",
" 5 marital.status 32561 non-null object\n", " 5 relationship 30162 non-null int64\n",
" 6 occupation 32561 non-null object\n", " 6 race 30162 non-null int64\n",
" 7 relationship 32561 non-null object\n", " 7 sex 30162 non-null int64\n",
" 8 race 32561 non-null object\n", " 8 capital.gain 30162 non-null int64\n",
" 9 sex 32561 non-null object\n", " 9 capital.loss 30162 non-null int64\n",
" 10 capital.gain 32561 non-null int64 \n", " 10 hours.per.week 30162 non-null int64\n",
" 11 capital.loss 32561 non-null int64 \n", " 11 native.country 30162 non-null int64\n",
" 12 hours.per.week 32561 non-null int64 \n", " 12 income 30162 non-null int64\n",
" 13 native.country 32561 non-null object\n", "dtypes: int64(13)\n",
" 14 income 32561 non-null object\n", "memory usage: 3.2 MB\n"
"dtypes: int64(6), object(9)\n",
"memory usage: 3.7+ MB\n"
] ]
} }
], ],
@@ -91,8 +89,8 @@
"plt.show()\n", "plt.show()\n",
"\n", "\n",
"#df_encoded.head(10)\n", "#df_encoded.head(10)\n",
"df.info()\n", "df_encoded.info()\n",
"\n" "#df.head(20)\n"
] ]
}, },
{ {
+272 -26
View File
@@ -47,24 +47,25 @@
"weighted avg 0.81 0.81 0.81 6033\n", "weighted avg 0.81 0.81 0.81 6033\n",
"\n", "\n",
"<class 'pandas.core.frame.DataFrame'>\n", "<class 'pandas.core.frame.DataFrame'>\n",
"Index: 18096 entries, 13586 to 5836\n", "Index: 30162 entries, 1 to 32560\n",
"Data columns (total 12 columns):\n", "Data columns (total 13 columns):\n",
" # Column Non-Null Count Dtype\n", " # Column Non-Null Count Dtype\n",
"--- ------ -------------- -----\n", "--- ------ -------------- -----\n",
" 0 age 18096 non-null int64\n", " 0 age 30162 non-null int64\n",
" 1 workclass 18096 non-null int64\n", " 1 workclass 30162 non-null int64\n",
" 2 education.num 18096 non-null int64\n", " 2 education.num 30162 non-null int64\n",
" 3 marital.status 18096 non-null int64\n", " 3 marital.status 30162 non-null int64\n",
" 4 occupation 18096 non-null int64\n", " 4 occupation 30162 non-null int64\n",
" 5 relationship 18096 non-null int64\n", " 5 relationship 30162 non-null int64\n",
" 6 race 18096 non-null int64\n", " 6 race 30162 non-null int64\n",
" 7 sex 18096 non-null int64\n", " 7 sex 30162 non-null int64\n",
" 8 capital.gain 18096 non-null int64\n", " 8 capital.gain 30162 non-null int64\n",
" 9 capital.loss 18096 non-null int64\n", " 9 capital.loss 30162 non-null int64\n",
" 10 hours.per.week 18096 non-null int64\n", " 10 hours.per.week 30162 non-null int64\n",
" 11 native.country 18096 non-null int64\n", " 11 native.country 30162 non-null int64\n",
"dtypes: int64(12)\n", " 12 income 30162 non-null int64\n",
"memory usage: 1.8 MB\n" "dtypes: int64(13)\n",
"memory usage: 3.2 MB\n"
] ]
} }
], ],
@@ -72,7 +73,7 @@
"import pandas as pd\n", "import pandas as pd\n",
"import numpy as np\n", "import numpy as np\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"from sklearn.model_selection import train_test_split, RandomizedSearchCV\n", "from sklearn.model_selection import train_test_split, RandomizedSearchCV, KFold, StratifiedKFold, GridSearchCV\n",
"from sklearn.pipeline import Pipeline\n", "from sklearn.pipeline import Pipeline\n",
"from sklearn.tree import DecisionTreeClassifier, plot_tree\n", "from sklearn.tree import DecisionTreeClassifier, plot_tree\n",
"from sklearn.preprocessing import LabelEncoder\n", "from sklearn.preprocessing import LabelEncoder\n",
@@ -81,6 +82,7 @@
"from scipy.stats import randint\n", "from scipy.stats import randint\n",
"\n", "\n",
"\n", "\n",
"\n",
"# Load dataset\n", "# Load dataset\n",
"df = pd.read_csv('./Datasets/adult.csv', comment = '#')\n", "df = pd.read_csv('./Datasets/adult.csv', comment = '#')\n",
"\n", "\n",
@@ -146,7 +148,15 @@
"print(\"Classification Report:\")\n", "print(\"Classification Report:\")\n",
"print(classification_report(y_val, y_pred, target_names=[\"Poor\", \"Rich\"]))\n", "print(classification_report(y_val, y_pred, target_names=[\"Poor\", \"Rich\"]))\n",
"\n", "\n",
"X_train.info()" "df_encoded.info()"
]
},
{
"cell_type": "markdown",
"id": "bfaae28c",
"metadata": {},
"source": [
"### Hyperparameter tuning"
] ]
}, },
{ {
@@ -162,13 +172,15 @@
"Classification Report:\n", "Classification Report:\n",
" precision recall f1-score support\n", " precision recall f1-score support\n",
"\n", "\n",
" Poor 0.89 0.92 0.90 4524\n", " Poor 0.88 0.93 0.90 4524\n",
" Rich 0.73 0.65 0.68 1509\n", " Rich 0.75 0.62 0.68 1509\n",
"\n", "\n",
" accuracy 0.85 6033\n", " accuracy 0.85 6033\n",
" macro avg 0.81 0.78 0.79 6033\n", " macro avg 0.81 0.78 0.79 6033\n",
"weighted avg 0.85 0.85 0.85 6033\n", "weighted avg 0.85 0.85 0.85 6033\n",
"\n" "\n",
"Best max_depth: 12\n",
"Best min_samples_split: 18\n"
] ]
} }
], ],
@@ -176,36 +188,270 @@
"# Hyperparameters search space\n", "# Hyperparameters search space\n",
"param_dist = {\n", "param_dist = {\n",
" 'full_dt_classifier__max_depth': randint(3, 20),\n", " 'full_dt_classifier__max_depth': randint(3, 20),\n",
" 'full_dt_classifier__min_samples_split': randint(2, 10),\n", " 'full_dt_classifier__min_samples_split': randint(2, 20),\n",
" 'full_dt_classifier__min_samples_leaf': randint(1, 10),\n", " 'full_dt_classifier__min_samples_leaf': randint(1, 15),\n",
"}\n", "}\n",
"\n", "\n",
"# Ranodmized search for hyperparameter tuning\n", "# Ranodmized search for hyperparameter tuning\n",
"random_search = RandomizedSearchCV(\n", "random_search = RandomizedSearchCV(\n",
" estimator=model,\n", " estimator=model,\n",
" param_distributions=param_dist,\n", " param_distributions=param_dist,\n",
" n_iter = 50,\n", " n_iter = 300,\n",
" cv = 10,\n", " cv = 10,\n",
" scoring = 'r2',\n", " scoring = 'r2',\n",
" n_jobs = -1,\n", " n_jobs = -1,\n",
" random_state = 42\n", " random_state = 42\n",
")\n", ")\n",
"\n", "\n",
"#K_fold = KFold(n_splits=10, shuffle=True, random_state=42)\n",
"#cv = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)\n",
"#grid_search = GridSearchCV(model, param_grid, scoring='accuracy', cv=cv, n_jobs=-1)\n",
"\n",
"# Fit search\n", "# Fit search\n",
"random_search.fit(X_train, y_train)\n", "random_search.fit(X_train, y_train)\n",
"random_search.fit(X_train, y_train)\n",
"\n", "\n",
"# Best model training\n", "# Best model training\n",
"best_model = random_search.best_estimator_\n", "best_model = random_search.best_estimator_\n",
"y_pred_best = best_model.predict(X_val)\n", "y_pred_best = best_model.predict(X_val)\n",
"\n", "\n",
"print(\"Classification Report:\")\n", "print(\"Classification Report:\")\n",
"print(classification_report(y_val, y_pred_best, target_names=[\"Poor\", \"Rich\"]))" "print(classification_report(y_val, y_pred_best, target_names=[\"Poor\", \"Rich\"]))\n",
"\n",
"best_max_depth = best_model.named_steps['full_dt_classifier'].max_depth\n",
"best_min_samples_split = best_model.named_steps['full_dt_classifier'].min_samples_split\n",
"best_min_samples_leaf = best_model.named_steps['full_dt_classifier'].min_samples_leaf\n",
"\n",
"print(f'Best max_depth: {best_max_depth}')\n",
"print(f'Best min_samples_split: {best_min_samples_split}')\n"
]
},
{
"cell_type": "markdown",
"id": "a37f45b4",
"metadata": {},
"source": [
"### Classifier comparison\n",
"(This is taken from the ensemble lab)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e68b1ea9",
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import GridSearchCV, StratifiedKFold\n",
"import time\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.metrics import (accuracy_score, precision_score, \n",
" recall_score, f1_score, \n",
" confusion_matrix, ConfusionMatrixDisplay)\n",
"from sklearn.ensemble import (RandomForestClassifier, BaggingClassifier, \n",
" AdaBoostClassifier, GradientBoostingClassifier)\n",
"from xgboost import XGBClassifier # Requires installation of the package ; Not a native function in sklearn\n",
"from lightgbm import LGBMClassifier # Requires installation of the package; Not a native function in sklearn\n",
"from catboost import CatBoostClassifier # Requires installation of the package; Not a native function in sklearn\n",
"\n",
"class ClassifierComparisonOpt:\n",
" def __init__(self, X, y, test_size=0.3, use_bootstrap=True, random_state=42, cv_folds=10):\n",
" # Split data stratified by labels\n",
" X_train, X_test, y_train, y_test = train_test_split(\n",
" X, y, test_size=test_size, stratify=y, random_state=random_state)\n",
"\n",
" # Scale features\n",
" scaler = StandardScaler()\n",
" self.X_train = scaler.fit_transform(X_train)\n",
" self.X_test = scaler.transform(X_test)\n",
"\n",
" self.y_train = y_train\n",
" self.y_test = y_test\n",
" self.use_bootstrap = use_bootstrap\n",
" self.cv_folds = cv_folds\n",
" self.models = {}\n",
" self.results = {}\n",
" self.results_df = None\n",
"\n",
" # Define the classifiers and their hyperparameters\n",
" def get_models_with_params(self):\n",
" return {\n",
" 'Decision Tree': (DecisionTreeClassifier(random_state=42), {\n",
" 'max_depth': [None, 10, 11, 12, 13, 14, 15, 16],\n",
" 'min_samples_split': [3, 4, 5, 6, 7, 8, 9]\n",
" }),\n",
" 'Random Forest': (RandomForestClassifier(bootstrap=self.use_bootstrap, random_state=42), {\n",
" 'n_estimators': [50, 100, 200], # I currently don't know how to tune this\n",
" 'max_depth': [None, 10, 11, 12, 13, 14, 15, 16],\n",
" 'min_samples_split': [3, 4, 5, 6, 7, 8, 9]\n",
" }),\n",
" #'Bagging': (BaggingClassifier(bootstrap=self.use_bootstrap, random_state=42), {\n",
" # 'n_estimators': [50, 100, 200],\n",
" # 'max_samples': [0.5, 1.0],\n",
" # 'oob_score': [True, False],\n",
" #}),\n",
" # SAMME: Stagewise Additive Modeling using a Multi-class Exponential loss\n",
" #'AdaBoost': (AdaBoostClassifier(algorithm='SAMME', random_state=42), {\n",
" # 'n_estimators': [50, 100, 200],\n",
" # 'learning_rate': [0.01, 0.1, 0.2, 0.5, 1.0]\n",
" #}),\n",
" #'Gradient Boosting': (GradientBoostingClassifier(random_state=42), {\n",
" # 'n_estimators': [50, 100, 200],\n",
" # 'learning_rate': [0.01, 0.1, 0.2, 0.5, 1.0],\n",
" # 'max_depth': [3, 5, 10]\n",
" #}),\n",
" #'XGBoost': (XGBClassifier(eval_metric='mlogloss', random_state=42), {\n",
" # 'n_estimators': [50, 100, 200],\n",
" # 'learning_rate': [0.01, 0.1, 0.2, 0.5, 1.0],\n",
" # 'max_depth': [3, 5, 10]\n",
" #}),\n",
" #'LightGBM': (LGBMClassifier(random_state=42), {\n",
" # 'n_estimators': [50, 100, 200],\n",
" # 'learning_rate': [0.01, 0.1, 0.2, 0.5, 1.0],\n",
" # 'max_depth': [-1, 5, 10]\n",
" #}),\n",
" #'CatBoost': (CatBoostClassifier(verbose=0, random_state=42), {\n",
" # 'iterations': [50, 100, 200],\n",
" # 'learning_rate': [0.01, 0.1, 0.2, 0.5, 1.0],\n",
" # 'depth': [4, 6, 10]\n",
" #})\n",
" }\n",
"\n",
" def fit_models(self):\n",
" results_list = []\n",
" cv = StratifiedKFold(n_splits=self.cv_folds, shuffle=True, random_state=42)\n",
" models_with_params = self.get_models_with_params()\n",
"\n",
" for name, (model, param_grid) in models_with_params.items():\n",
" print(f\"Tuning {name} ...\")\n",
" \n",
" grid_search = GridSearchCV(model, param_grid, scoring='accuracy', cv=cv, n_jobs=-1)\n",
" \n",
" start_train = time.time()\n",
" grid_search.fit(self.X_train, self.y_train)\n",
" end_train = time.time()\n",
"\n",
" best_model = grid_search.best_estimator_\n",
" y_pred = best_model.predict(self.X_test)\n",
" end_pred = time.time()\n",
"\n",
" self.models[name] = {\n",
" 'model': best_model,\n",
" 'confusion_matrix': confusion_matrix(self.y_test, y_pred)\n",
" }\n",
"\n",
" metrics = {\n",
" 'Model': name,\n",
" 'Accuracy': accuracy_score(self.y_test, y_pred),\n",
" 'Precision': precision_score(self.y_test, y_pred, average='weighted', zero_division=0),\n",
" 'Recall': recall_score(self.y_test, y_pred, average='weighted'),\n",
" 'F1 Score': f1_score(self.y_test, y_pred, average='weighted'),\n",
" 'Best Params': grid_search.best_params_,\n",
" 'Training Time (s)': (end_train - start_train),\n",
" 'Prediction Time (s)': (end_pred - end_train),\n",
" 'Total Time (s)': (end_pred - start_train)\n",
" }\n",
"\n",
" results_list.append(metrics)\n",
"\n",
" self.results_df = pd.DataFrame(results_list)\n",
"\n",
" def print_summary(self):\n",
" print(\"\\n------ Results Sorted by Accuracy ------\")\n",
" print(self.results_df.sort_values(by='Accuracy', ascending=False).to_string(index=False))\n",
"\n",
" print(\"\\n------ Results Sorted by Total Time ------\")\n",
" print(self.results_df.sort_values(by='Total Time (s)', ascending=True).to_string(index=False))\n",
"\n",
" # Show feature importance for models that support it \n",
" def show_feature_importance(self):\n",
" importance = {}\n",
"\n",
" for name, result in self.models.items():\n",
" model = result['model']\n",
" if hasattr(model, 'feature_importances_'):\n",
" importance[name] = model.feature_importances_\n",
" elif hasattr(model, 'coef_'):\n",
" coef = model.coef_\n",
" if coef.ndim == 1:\n",
" importance[name] = np.abs(coef)\n",
" else:\n",
" importance[name] = np.mean(np.abs(coef), axis=0)\n",
" else:\n",
" print(f\"Feature importance not available for model {name}\")\n",
"\n",
" for name, imp in importance.items():\n",
" sorted_idx = np.argsort(imp)[::-1]\n",
" plt.figure()\n",
" plt.bar(range(len(imp)), imp[sorted_idx], align='center')\n",
" plt.xticks(range(len(imp)), sorted_idx)\n",
" plt.title(f\"Feature importance for {name}\")\n",
" plt.xlabel(\"Feature index\")\n",
" plt.ylabel(\"Importance score\")\n",
" plt.grid(True, linestyle='--', alpha=0.6)\n",
" plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "d6fd1fee",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tuning Decision Tree ...\n",
"Tuning Random Forest ...\n",
"\n",
"------ Results Sorted by Accuracy ------\n",
" Model Accuracy Precision Recall F1 Score Best Params Training Time (s) Prediction Time (s) Total Time (s)\n",
"Random Forest 0.857617 0.852147 0.857617 0.852588 {'max_depth': 16, 'min_samples_split': 5, 'n_estimators': 200} 303.932920 0.216372 304.149293\n",
"Decision Tree 0.846381 0.840787 0.846381 0.842219 {'max_depth': 10, 'min_samples_split': 9} 3.946769 0.001706 3.948475\n",
"\n",
"------ Results Sorted by Total Time ------\n",
" Model Accuracy Precision Recall F1 Score Best Params Training Time (s) Prediction Time (s) Total Time (s)\n",
"Decision Tree 0.846381 0.840787 0.846381 0.842219 {'max_depth': 10, 'min_samples_split': 9} 3.946769 0.001706 3.948475\n",
"Random Forest 0.857617 0.852147 0.857617 0.852588 {'max_depth': 16, 'min_samples_split': 5, 'n_estimators': 200} 303.932920 0.216372 304.149293\n"
]
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# ===== MAIN =====\n",
"# optimized classifiers and find their hyperparameters\n",
"clf_opt = ClassifierComparisonOpt(X_train, y_train)\n",
"clf_opt.fit_models()\n",
"clf_opt.print_summary()\n",
"\n",
"# Show feature importance for each model\n",
"clf_opt.show_feature_importance()"
] ]
} }
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": ".venv", "display_name": "Python 3",
"language": "python", "language": "python",
"name": "python3" "name": "python3"
}, },
BIN
View File
Binary file not shown.