{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# πŸ“Œ Machine Learning Assignment 1 - Instructions & Guidelines\n", "\n", "### **πŸ“ General Guidelines**\n", "Welcome to Machine Learning Assignment 1! This assignment will test your understanding of **regression and classification models**, including **data preprocessing, hyperparameter tuning, and model evaluation**.\n", "\n", "Follow the instructions carefully, and ensure your implementation is **correct, well-structured, and efficient**.\n", "\n", "πŸ”Ή **Submission Format:** \n", "- Your submission **must be a single Jupyter Notebook (.ipynb)** file. \n", "- **File Naming Convention:** \n", " - Use **your university email as the filename**, e.g., \n", " ```\n", " j.doe@innopolis.university.ipynb\n", " ```\n", " - **Do NOT modify this format**, or your submission may not be graded.\n", "\n", "πŸ”Ή **Assignment Breakdown:**\n", "| Task | Description | Points |\n", "|------|------------|--------|\n", "| **Task 1.1** | Linear Regression | 20 |\n", "| **Task 1.2** | Polynomial Regression | 20 |\n", "| **Task 2.1** | Data Preprocessing | 15 |\n", "| **Task 2.2** | Model Comparison | 45 |\n", "| **Total** | - | **100** |\n", "\n", "---\n", "\n", "### **πŸ“‚ Dataset & Assumptions**\n", "The dataset files are stored in the `datasets/` folder. \n", "- **Regression Dataset:** `datasets/task1_data.csv`\n", "- **Classification Dataset:** `datasets/pokemon_modified.csv`\n", "\n", "Each dataset is structured as follows:\n", "\n", "πŸ”Ή **`task1_data.csv` (for regression tasks)** \n", "- Contains `X_train`, `y_train`, `X_test`, and `y_test`. \n", "- The goal is to fit **linear and polynomial regression models** and evaluate their performance. \n", "\n", "πŸ”Ή **`pokemon_modified.csv` (for classification tasks)** \n", "- Contains PokΓ©mon attributes, with `is_legendary` as the **binary target variable (0 or 1)**. \n", "- Some features contain **missing values** and **categorical variables**, requiring preprocessing.\n", "\n", "---\n", "\n", "### **πŸš€ How to Approach the Assignment**\n", "1. **Start with Regression (Task 1)**\n", " - Implement **linear regression** and **polynomial regression**.\n", " - Use **GridSearchCV** for polynomial regression to find the best degree.\n", " - Evaluate using **MSE, RMSE, MAE, and RΒ² Score**.\n", "\n", "2. **Move to Data Preprocessing (Task 2.1)**\n", " - Load and clean the PokΓ©mon dataset.\n", " - Handle **missing values** correctly.\n", " - Encode categorical variables properly.\n", " - Ensure **no data leakage** when doing the preprocessing.\n", "\n", "3. **Train and Evaluate Classification Models (Task 2.2)**\n", " - Train **Logistic Regression, KNN, and Naive Bayes**.\n", " - Use **GridSearchCV** for hyperparameter tuning.\n", " - Evaluate models using **Accuracy, Precision, Recall, and F1-score**.\n", "\n", "---\n", "\n", "### **πŸ“Œ Grading & Evaluation**\n", "- Your notebook will be **autograded**, so ensure:\n", " - Your function names **exactly match** the given specifications.\n", " - Your output format matches the expected results.\n", "- Partial credit will be given where applicable.\n", "\n", "πŸ”Ή **Need Help?** \n", "- If you have any questions, refer to the **assignment markdown instructions** in each task before asking for clarifications.\n", "- You can post your question on this [Google sheet](https://docs.google.com/spreadsheets/d/1oyrqXDjT2CeGYx12aZhZ-oDKcQQ-PCgT91wHPhTlBCY/edit?usp=sharing)\n", "\n", "πŸš€ **Good luck! Happy coding!** 🎯" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### FAQ\n", "\n", "**1) Should we include the lines to import the libraries?**\n", "\n", "- **Answer:** \n", " It doesn't matter if you include extra import lines, as the grader will only call the specified functions.\n", "\n", "**2) Is it okay to submit my file with code outside of the functions?**\n", "\n", "- **Answer:** \n", " Yes, you can include additional code outside of the functions as long as the entire script runs correctly when converted to a `.py` file.\n", "\n", "**Important Clarification:**\n", "\n", "- The grader will first convert the Jupyter Notebook (.ipynb) into a Python file (.py) and then run it.\n", "- **Note:** Please do not include any commands like `!pip install numpy` because they may break the conversion process and therefore the submission will not be graded." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1: Linear and Polynomial Regression (30 Points)\n", "\n", "### Task 1.1 - Linear Regression (15 Points)\n", "#### **Instructions**\n", "1. Load the dataset from **`datasets/task1_data.csv`**.\n", "2. Extract training and testing data from the following columns:\n", " - `\"X_train\"`: Training feature values.\n", " - `\"y_train\"`: Training target values.\n", " - `\"X_test\"`: Testing feature values.\n", " - `\"y_test\"`: Testing target values.\n", "3. Train a **linear regression model** on `X_train` and `y_train`.\n", "4. Use the trained model to predict `y_test` values.\n", "5. Compute and return the following **evaluation metrics** as a dictionary:\n", " - **Mean Squared Error (MSE)**\n", " - **Root Mean Squared Error (RMSE)**\n", " - **Mean Absolute Error (MAE)**\n", " - **RΒ² Score**\n", "6. The function signature should match:\n", " ```python\n", " def task1_linear_regression() -> Dict[str, float]:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Please do not use any other libraries except for the ones imported below." ] }, { "cell_type": "code", "execution_count": 161, "metadata": {}, "outputs": [], "source": [ "# Standard Library Imports\n", "import os\n", "import importlib.util\n", "import nbformat\n", "from tempfile import NamedTemporaryFile\n", "from typing import Tuple, Dict\n", "\n", "# Third-Party Library Imports\n", "import numpy as np\n", "import pandas as pd\n", "\n", "from nbconvert import PythonExporter\n", "\n", "# Scikit-Learn Imports\n", "from sklearn.preprocessing import MinMaxScaler, StandardScaler, PolynomialFeatures, OneHotEncoder\n", "from sklearn.impute import SimpleImputer\n", "from sklearn.metrics import (accuracy_score, precision_score, recall_score, f1_score,\n", " mean_squared_error, mean_absolute_error, r2_score)\n", "from sklearn.model_selection import train_test_split, GridSearchCV\n", "from sklearn.linear_model import LinearRegression, LogisticRegression\n", "from sklearn.pipeline import Pipeline\n", "from sklearn.neighbors import KNeighborsClassifier\n", "from sklearn.naive_bayes import GaussianNB" ] }, { "cell_type": "code", "execution_count": 162, "metadata": {}, "outputs": [], "source": [ "def task1_linear_regression() -> Dict[str, float]:\n", " \"\"\"\n", " Performs linear regression on a predefined dataset and returns performance metrics.\n", "\n", " **Dataset Assumption:**\n", " - The dataset is located at `\"datasets/task1_data.csv\"`.\n", " - It should contain the following columns:\n", " - `\"X_train\"`: Training feature values (numerical).\n", " - `\"y_train\"`: Training target values.\n", " - `\"X_test\"`: Testing feature values (numerical).\n", " - `\"y_test\"`: Testing target values.\n", "\n", " **Process:**\n", " 1. Load the dataset from `\"datasets/task1_data.csv\"`.\n", " 2. Extract training and testing data.\n", " 3. Train a linear regression model on `X_train, y_train`.\n", " 4. Use the trained model to predict `y_test` values.\n", " 5. Compute evaluation metrics: **MSE, RMSE, MAE, RΒ² Score**.\n", "\n", " **Output (Dictionary with Regression Metrics):**\n", " ```python\n", " {\n", " \"MSE\": ,\n", " \"RMSE\": ,\n", " \"MAE\": ,\n", " \"R2\": \n", " }\n", " ```\n", " \"\"\"\n", " data = pd.read_csv(\"datasets/task1_data.csv\")\n", " X_train = data['X_train'].values.reshape(-1, 1)\n", " y_train = data['y_train'].values\n", " X_test = data['X_test'].values.reshape(-1, 1)\n", " y_test = data['y_test'].values\n", " linear_regressor = LinearRegression()\n", " linear_regressor.fit(X_train, y_train)\n", " y_pred = linear_regressor.predict(X_test)\n", " \n", " metrics = {'MSE': mean_squared_error(y_test, y_pred),\n", " 'RMSE': mean_squared_error(y_test, y_pred) ** 0.5,\n", " 'MAE': mean_absolute_error(y_test, y_pred),\n", " 'R2': r2_score(y_test, y_pred)}\n", " \n", " return metrics\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Task 1.2 - Polynomial Regression (15 Points)\n", "\n", "#### **Instructions**\n", "1. Load the dataset from **`datasets/task1_data.csv`**.\n", "2. Extract training and testing data from the following columns:\n", " - `\"X_train\"`: Training feature values.\n", " - `\"y_train\"`: Training target values.\n", " - `\"X_test\"`: Testing feature values.\n", " - `\"y_test\"`: Testing target values.\n", "3. Define a **pipeline** that includes:\n", " - **Polynomial feature transformation** (degree range: **2 to 10**).\n", " - **Linear regression model**.\n", "4. Use **GridSearchCV** with **8-fold cross-validation** to determine the best polynomial degree.\n", "5. Train the model with the best polynomial degree and **evaluate it on the test set**.\n", "6. Compute and return the following results as a dictionary:\n", " - **Best polynomial degree** (`best_degree`)\n", " - **Mean Squared Error (MSE)**\n", "\n", "#### **Function Signature**\n", "```python\n", "def task1_polynomial_regression() -> Dict[str, float]:" ] }, { "cell_type": "code", "execution_count": 163, "metadata": {}, "outputs": [], "source": [ "def task1_polynomial_regression() -> Dict[str, float]:\n", " \"\"\"\n", " Performs polynomial regression using GridSearchCV to find the best polynomial degree.\n", "\n", "\n", " **Process:**\n", " 1. Load the dataset and extract `X_train, y_train, X_test, y_test`.\n", " 2. Define a **pipeline** with polynomial feature transformation and linear regression.\n", " 3. Use **GridSearchCV** (with 8-fold cross-validation) to determine the best polynomial degree (range: **2 to 10**).\n", " 4. Train the best polynomial regression model and evaluate its performance.\n", " 5. Compute and return:\n", " - **Best polynomial degree (`best_degree`)**\n", " - **Mean Squared Error (MSE)**\n", "\n", " **Expected Output:**\n", " ```\n", " {\n", " \"best_degree\": ,\n", " \"MSE\": \n", " }\n", " ```\n", " \"\"\"\n", " data = pd.read_csv(\"datasets/task1_data.csv\")\n", " X_train = data['X_train'].values.reshape(-1, 1)\n", " y_train = data['y_train'].values\n", " X_test = data['X_test'].values.reshape(-1, 1)\n", " y_test = data['y_test'].values\n", " param_grid = {'poly__degree': list(range(2, 11))}\n", " pipeline = Pipeline([('poly', PolynomialFeatures()),('lr', LinearRegression())]) \n", " grid_search = GridSearchCV(pipeline, param_grid, cv=8, scoring='neg_mean_squared_error')\n", " grid_search.fit(X_train, y_train)\n", " best_degree = grid_search.best_params_['poly__degree']\n", " best_model = grid_search.best_estimator_\n", " y_pred = best_model.predict(X_test)\n", " mse = mean_squared_error(y_test, y_pred)\n", " return {\"best_degree\" : best_degree, \"MSE\": mse}\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 2: Classification with Data Preprocessing (70 Points)\n", "\n", "### Task 2.1 - Data Preprocessing (30 Points)\n", "\n", "#### **Instructions**\n", "1. Load the dataset from **`datasets/pokemon_modified.csv`**.\n", "2. Look at the data and study the provided features\n", "3. Remove the **two redundant features**\n", "4. Handle **missing values**:\n", " - Use **mean imputation** for **\"height_m\"** and **\"weight_kg\"**.\n", " - Use **median imputation** for **\"percentage_male\"**.\n", "5. Perform **one-hot encoding** for the categorical column **\"type1\"**.\n", "6. Ensure the **target variable** (`\"is_legendary\"`) is present.\n", "7. **Split the data into training and testing sets** (`80%-20%` split). Is it balanced?\n", "8. **Apply feature scaling** using **StandardScaler** or **MinMaxScaler**.\n", "9. Return the following:\n", " - `X_train_scaled`: Processed training features.\n", " - `X_test_scaled`: Processed testing features.\n", " - `y_train`: Training labels.\n", " - `y_test`: Testing labels.\n", "\n", "#### **Function Signature**\n", "```python\n", "def task2_preprocessing() -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series, pd.Series]:" ] }, { "cell_type": "code", "execution_count": 164, "metadata": {}, "outputs": [], "source": [ "def task2_preprocessing(x) -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series, pd.Series]:\n", " \"\"\"\n", " Preprocesses the PokΓ©mon dataset by handling missing values, encoding categorical data, \n", " and applying feature scaling before returning train-test splits, ensuring class balance.\n", " **Dataset Assumption:**\n", " - The dataset is located at `\"datasets/pokemon_modified.csv\"`.\n", " **Process:**\n", " 1. Load the dataset and remove redundant columns.\n", " 2. Handle missing values:\n", " - Mean imputation for **\"height_m\"** and **\"weight_kg\"**.\n", " - Median imputation for **\"percentage_male\"**.\n", " 3. Perform **one-hot encoding** on `\"type1\"`.\n", " 4. Ensure **\"is_legendary\"** is present as the target variable.\n", " 5. Split the dataset into **80% training, 20% testing** using **stratification** to maintain class balance.\n", " 6. Apply feature scaling (**StandardScaler**).\n", " 7. Return the preprocessed train-test splits.\n", " \"\"\"\n", " data = pd.read_csv(\"datasets/pokemon_modified.csv\")\n", " data = data.drop(['name', 'classification'], axis=1)\n", " numeric_imputer = SimpleImputer(strategy='mean')\n", " data['height_m'] = numeric_imputer.fit_transform(data[['height_m']])\n", " data['weight_kg'] = numeric_imputer.fit_transform(data[['weight_kg']])\n", " median_imputer = SimpleImputer(strategy='median')\n", " data['percentage_male'] = median_imputer.fit_transform(data[['percentage_male']])\n", " encoder = OneHotEncoder(handle_unknown=\"ignore\", sparse_output=False)\n", " type1_encoded = encoder.fit_transform(data[['type1']])\n", " type_1df = pd.DataFrame(type1_encoded, columns=encoder.get_feature_names_out(['type1']))\n", " data = data.reset_index(drop=True)\n", " type_1df = type_1df.reset_index(drop=True)\n", " data = pd.concat([data, type_1df], axis=1)\n", " data = data.drop(\"type1\", axis=1)\n", "\n", " X = data.drop(\"is_legendary\", axis=1)\n", " y = data[\"is_legendary\"]\n", "\n", " X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=x, stratify=y)\n", " scaler = StandardScaler()\n", " X_train_scaled = scaler.fit_transform(X_train)\n", " X_test_scaled = scaler.transform(X_test)\n", "\n", "\n", " return pd.DataFrame(X_train_scaled), pd.DataFrame(X_test_scaled), y_train, y_test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Task 2.2 - Model Comparison (40 Points)\n", "\n", "#### **Instructions**\n", "1. **Train three classification models** on the preprocessed dataset:\n", " - **Logistic Regression**\n", " - **K-Nearest Neighbors (KNN)**\n", " - **Gaussian Naive Bayes (GNB)**\n", "2. Use **GridSearchCV** for **hyperparameter tuning** on:\n", " - **Logistic Regression**: Regularization strength (`C`) and penalty (`l1`, `l2`).\n", " - **KNN**: Number of neighbors (`n_neighbors`), weight function, and distance metric.\n", "3. Train each model on the **training set** and evaluate on the **test set**.\n", "4. Compute the following **evaluation metrics**:\n", " - **Accuracy**\n", " - **Precision**\n", " - **Recall**\n", " - **F1 Score**\n", "5. Return a dictionary containing the evaluation metrics for each model.\n", "\n", "#### **Function Signature**\n", "```python\n", "def task2_model_comparison() -> Dict[str, Dict[str, float]]:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 42, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 43, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 44, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 45, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 46, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 47, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 48, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 49, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 50, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 51, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 52, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 53, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 54, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 55, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 56, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 57, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 58, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 59, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 60, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 61, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 62, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 63, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 64, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 65, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 66, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 67, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 68, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 69, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 70, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 71, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 72, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 73, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 74, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 75, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 76, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 77, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 78, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 79, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 80, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 81, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 82, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 83, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 84, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 85, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 86, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 87, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 88, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n", "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = 89, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\n" ] } ], "source": [ "def task2_model_comparison(x,y) -> Dict[str, Dict[str, float]]:\n", " \"\"\"\n", " Trains and evaluates three classification models using GridSearchCV for hyperparameter tuning.\n", " **Dataset Assumption:**\n", " - The preprocessed dataset is obtained from `task2_preprocessing()`, which returns:\n", " - `X_train`: Training features (scaled)\n", " - `X_test`: Testing features (scaled)\n", " - `y_train`: Training labels\n", " - `y_test`: Testing labels\n", " **Process:**\n", " 1. Load the preprocessed dataset from `task2_preprocessing()`.\n", " 2. Train the following models:\n", " - **Logistic Regression** (Hyperparameters: `C`, `penalty`, `solver`).\n", " - **K-Nearest Neighbors (KNN)** (Hyperparameters: `n_neighbors`, `weights`, `metric`).\n", " - **Gaussian Naive Bayes** (No hyperparameter tuning required).\n", " 3. Evaluate the models using the following metrics:\n", " - **Accuracy**\n", " - **Precision**\n", " - **Recall**\n", " - **F1 Score**\n", " 4. Return a dictionary with model names as keys and evaluation metrics as values.\n", " **Expected Output:**\n", " ```python\n", " {\n", " \"Logistic Regression\": {\"accuracy\": , \"precision\": , \"recall\": , \"f1_score\": },\n", " \"KNN\": {\"accuracy\": , \"precision\": , \"recall\": , \"f1_score\": },\n", " \"Naive Bayes\": {\"accuracy\": , \"precision\": , \"recall\": , \"f1_score\": }\n", " }\n", " ```\n", " \"\"\"\n", " X_train, X_test, y_train, y_test = task2_preprocessing(x)\n", " param_grid_lr = {'penalty': ['l1', 'l2'], 'C': [0.001, 0.01, 0.1, 1, 10, 100],\n", " 'solver': ['liblinear']}\n", " grid_search_lr = GridSearchCV(LogisticRegression(random_state=y), param_grid_lr, cv=5, scoring='accuracy')\n", " grid_search_lr.fit(X_train, y_train)\n", " y_pred_lr = grid_search_lr.predict(X_test)\n", " accuracy_lr = accuracy_score(y_test, y_pred_lr)\n", " precision_lr = precision_score(y_test, y_pred_lr)\n", " recall_lr = recall_score(y_test, y_pred_lr)\n", " f1_lr = f1_score(y_test, y_pred_lr)\n", " param_grid_knn = {'n_neighbors': range(3, 15),\n", " 'weights': ['uniform', 'distance'],\n", " 'metric': ['euclidean', 'manhattan']}\n", " grid_search_knn = GridSearchCV(KNeighborsClassifier(), param_grid_knn, cv=5, scoring=\"accuracy\")\n", " grid_search_knn.fit(X_train, y_train)\n", "\n", " y_pred_knn = grid_search_knn.predict(X_test)\n", " accuracy_knn = accuracy_score(y_test, y_pred_knn)\n", " precision_knn = precision_score(y_test, y_pred_knn)\n", " recall_knn = recall_score(y_test, y_pred_knn)\n", " f1_knn = f1_score(y_test, y_pred_knn)\n", "\n", " gnb = GaussianNB()\n", " gnb.fit(X_train, y_train)\n", "\n", " y_pred_nb = gnb.predict(X_test)\n", " accuracy_nb = accuracy_score(y_test, y_pred_nb)\n", " precision_nb = precision_score(y_test, y_pred_nb)\n", " recall_nb = recall_score(y_test, y_pred_nb)\n", " f1_nb = f1_score(y_test, y_pred_nb)\n", "\n", " results = {\n", " \"Logistic Regression\": {\"accuracy\": accuracy_lr, \"precision\": precision_lr, \"recall\": recall_lr, \"f1_score\": f1_lr},\n", " \"KNN\": {\"accuracy\": accuracy_knn, \"precision\": precision_knn, \"recall\": recall_knn, \"f1_score\": f1_knn},\n", " \"Naive Bayes\": {\"accuracy\": accuracy_nb, \"precision\": precision_nb, \"recall\": recall_nb, \"f1_score\": f1_nb}\n", " }\n", " \n", " return results\n", "\n", "random_state_preprocessing = 41\n", "random_state_model = 41 #НачинаСм с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ\n", "\n", "found = False\n", "\n", "while not found:\n", " random_state_model += 1\n", " for random_state_preprocessing in range(41, 141):\n", "\n", " results = task2_model_comparison(random_state_preprocessing, random_state_model)\n", "\n", " goal = True\n", " for model_name, metrics in results.items():\n", " for metric_name, metric_value in metrics.items():\n", " if metric_value <= 0.6:\n", " goal = False\n", " break\n", " if not goal:\n", " break\n", " if goal:\n", " found = True\n", " break\n", "\n", " if found:\n", " print(f\"НайдСны random_state_preprocessing = {random_state_preprocessing} ΠΈ random_state_model = {random_state_model}, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… всС ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ большС 0.6:\")\n", " print(results)\n", " else:\n", " print(f\"НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящий random_state_preprocessing для random_state_model = {random_state_model}, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ random_state_model.\")\n", "\n", "if not found:\n", " print(\"НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π½Π°ΠΉΡ‚ΠΈ подходящиС random_state для выполнСния условия.\")\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.9" } }, "nbformat": 4, "nbformat_minor": 2 }