pred_analytics/Lab3.ipynb

456 lines
21 KiB
Plaintext
Raw Permalink Normal View History

2025-01-13 14:42:39 +04:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Лабораторная работа 3."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Определение бизнес и технических целей\n",
"1. Прогнозирование цены автомобиля\n",
"Бизнес-цель: Оптимизация ценовой политики.\n",
"Техническая цель: Построение модели прогнозирования цены.\n",
"\n",
"Конструирование признаков:\n",
"Объем двигателя:\n",
"\n",
"Извлечь числовую часть из столбца Engine volume (например, 3.5).\n",
"Добавить бинарный признак: наличие турбонаддува (Turbo).\n",
"Возраст автомобиля:\n",
"\n",
"Вычислить возраст автомобиля как разницу между текущим годом и Prod. year.\n",
"Привод (Drive wheels):\n",
"\n",
"Закодировать тип привода (например, 4x4, Front, Rear) с помощью One-Hot Encoding.\n",
"Категория автомобиля (Category):\n",
"\n",
"Преобразовать категорию в числовые признаки с помощью One-Hot Encoding.\n",
"Технические характеристики:\n",
"\n",
"Нормализовать числовые параметры, такие как пробег (Mileage) и количество цилиндров (Cylinders).\n",
"Состояние интерьера:\n",
"\n",
"Закодировать признак наличия кожаного салона (Leather interior) как бинарный.\n",
"\n",
"2. Классификация популярности автомобиля\n",
"Бизнес-цель: Изучение предпочтений клиентов.\n",
"Техническая цель: Определение популярности автомобилей.\n",
"\n",
"Конструирование признаков:\n",
"Рейтинг безопасности:\n",
"\n",
"Использовать количество подушек безопасности (Airbags) для создания индикатора безопасности автомобиля.\n",
"Тип топлива:\n",
"\n",
"Закодировать Fuel type как категориальный признак (например, Petrol, Diesel, Hybrid).\n",
"Цвет автомобиля:\n",
"\n",
"Создать признак редкости цвета на основе частоты его встречаемости в данных.\n",
"Стоимость обслуживания:\n",
"\n",
"Преобразовать Levy в числовой признак и обработать пропущенные значения (например, заменить на среднее/медианное значение).\n",
"Сегмент рынка:\n",
"\n",
"Объединить категории автомобилей (например, Jeep, Hatchback) в несколько сегментов (премиум, эконом, компакт).\n",
"Особенности привода:\n",
"\n",
"Создать бинарные признаки, указывающие на тип управления (Left wheel/Right-hand drive)."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"((11542, 215), (3847, 215), (3848, 215), (11542,), (3847,), (3848,))"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"import pandas as pd\n",
"\n",
"data = pd.read_csv(\"car_price_prediction.csv\")\n",
"# Preparing the data by removing unnecessary columns and handling categorical data\n",
"data_cleaned = data.copy()\n",
"\n",
"# Converting \"Levy\" and \"Mileage\" to numeric (handling non-numeric values like '-')\n",
"data_cleaned[\"Levy\"] = pd.to_numeric(data_cleaned[\"Levy\"], errors=\"coerce\")\n",
"data_cleaned[\"Mileage\"] = (\n",
" data_cleaned[\"Mileage\"].str.replace(\" km\", \"\").str.replace(\" \", \"\").astype(float)\n",
")\n",
"\n",
"# Dropping columns that are identifiers or too detailed for prediction (like ID, Model)\n",
"data_cleaned = data_cleaned.drop([\"ID\", \"Model\"], axis=1)\n",
"\n",
"# Encoding categorical columns\n",
"categorical_cols = data_cleaned.select_dtypes(include=\"object\").columns\n",
"data_encoded = pd.get_dummies(data_cleaned, columns=categorical_cols, drop_first=True)\n",
"\n",
"# Splitting the data into features (X) and target (y)\n",
"X = data_encoded.drop(\"Price\", axis=1)\n",
"y = data_encoded[\"Price\"]\n",
"\n",
"# Splitting into training, validation, and testing datasets\n",
"X_train, X_temp, y_train, y_temp = train_test_split(\n",
" X, y, test_size=0.4, random_state=42\n",
") # 60% training data\n",
"X_val, X_test, y_val, y_test = train_test_split(\n",
" X_temp, y_temp, test_size=0.5, random_state=42\n",
") # 20% validation, 20% testing\n",
"\n",
"# Displaying the sizes of the datasets\n",
"X_train.shape, X_val.shape, X_test.shape, y_train.shape, y_val.shape, y_test.shape"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Price</th>\n",
" <th>Levy</th>\n",
" <th>Manufacturer</th>\n",
" <th>Leather interior</th>\n",
" <th>Engine volume</th>\n",
" <th>Mileage</th>\n",
" <th>Cylinders</th>\n",
" <th>Gear box type</th>\n",
" <th>Doors</th>\n",
" <th>Airbags</th>\n",
" <th>...</th>\n",
" <th>Fuel type_LPG</th>\n",
" <th>Fuel type_Petrol</th>\n",
" <th>Fuel type_Plug-in Hybrid</th>\n",
" <th>Wheel_Right-hand drive</th>\n",
" <th>Car age</th>\n",
" <th>Car age bins</th>\n",
" <th>Mileage bins</th>\n",
" <th>Turbo</th>\n",
" <th>Safety rating</th>\n",
" <th>Color rarity</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>13328</td>\n",
" <td>1.065632</td>\n",
" <td>LEXUS</td>\n",
" <td>Yes</td>\n",
" <td>1.357980</td>\n",
" <td>-0.027813</td>\n",
" <td>1.180937</td>\n",
" <td>Automatic</td>\n",
" <td>04-May</td>\n",
" <td>12</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>15</td>\n",
" <td>11-20</td>\n",
" <td>High</td>\n",
" <td>0</td>\n",
" <td>0.750</td>\n",
" <td>0.197120</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>16621</td>\n",
" <td>0.240688</td>\n",
" <td>CHEVROLET</td>\n",
" <td>No</td>\n",
" <td>0.788363</td>\n",
" <td>-0.027689</td>\n",
" <td>1.180937</td>\n",
" <td>Tiptronic</td>\n",
" <td>04-May</td>\n",
" <td>8</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>14</td>\n",
" <td>11-20</td>\n",
" <td>Very High</td>\n",
" <td>0</td>\n",
" <td>0.500</td>\n",
" <td>0.261631</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>8467</td>\n",
" <td>NaN</td>\n",
" <td>HONDA</td>\n",
" <td>No</td>\n",
" <td>-1.148338</td>\n",
" <td>-0.027524</td>\n",
" <td>-0.485866</td>\n",
" <td>Variator</td>\n",
" <td>04-May</td>\n",
" <td>2</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>19</td>\n",
" <td>11-20</td>\n",
" <td>Very High</td>\n",
" <td>0</td>\n",
" <td>0.125</td>\n",
" <td>0.261631</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>3607</td>\n",
" <td>-0.097084</td>\n",
" <td>FORD</td>\n",
" <td>Yes</td>\n",
" <td>0.218745</td>\n",
" <td>-0.028165</td>\n",
" <td>-0.485866</td>\n",
" <td>Automatic</td>\n",
" <td>04-May</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>14</td>\n",
" <td>11-20</td>\n",
" <td>High</td>\n",
" <td>0</td>\n",
" <td>0.000</td>\n",
" <td>0.233352</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>11726</td>\n",
" <td>-0.997809</td>\n",
" <td>HONDA</td>\n",
" <td>Yes</td>\n",
" <td>-1.148338</td>\n",
" <td>-0.029757</td>\n",
" <td>-0.485866</td>\n",
" <td>Automatic</td>\n",
" <td>04-May</td>\n",
" <td>4</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>11</td>\n",
" <td>11-20</td>\n",
" <td>Medium</td>\n",
" <td>0</td>\n",
" <td>0.250</td>\n",
" <td>0.197120</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 35 columns</p>\n",
"</div>"
],
"text/plain": [
" Price Levy Manufacturer Leather interior Engine volume Mileage \\\n",
"0 13328 1.065632 LEXUS Yes 1.357980 -0.027813 \n",
"1 16621 0.240688 CHEVROLET No 0.788363 -0.027689 \n",
"2 8467 NaN HONDA No -1.148338 -0.027524 \n",
"3 3607 -0.097084 FORD Yes 0.218745 -0.028165 \n",
"4 11726 -0.997809 HONDA Yes -1.148338 -0.029757 \n",
"\n",
" Cylinders Gear box type Doors Airbags ... Fuel type_LPG \\\n",
"0 1.180937 Automatic 04-May 12 ... False \n",
"1 1.180937 Tiptronic 04-May 8 ... False \n",
"2 -0.485866 Variator 04-May 2 ... False \n",
"3 -0.485866 Automatic 04-May 0 ... False \n",
"4 -0.485866 Automatic 04-May 4 ... False \n",
"\n",
" Fuel type_Petrol Fuel type_Plug-in Hybrid Wheel_Right-hand drive \\\n",
"0 False False False \n",
"1 True False False \n",
"2 True False True \n",
"3 False False False \n",
"4 True False False \n",
"\n",
" Car age Car age bins Mileage bins Turbo Safety rating Color rarity \n",
"0 15 11-20 High 0 0.750 0.197120 \n",
"1 14 11-20 Very High 0 0.500 0.261631 \n",
"2 19 11-20 Very High 0 0.125 0.261631 \n",
"3 14 11-20 High 0 0.000 0.233352 \n",
"4 11 11-20 Medium 0 0.250 0.197120 \n",
"\n",
"[5 rows x 35 columns]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"from sklearn.preprocessing import MinMaxScaler, StandardScaler\n",
"\n",
"# Копия исходного набора данных\n",
"features_data = data_cleaned.copy()\n",
"\n",
"# --- 1. Унитарное кодирование категориальных признаков ---\n",
"# Кодирование категориальных переменных\n",
"categorical_columns = [\"Drive wheels\", \"Category\", \"Fuel type\", \"Wheel\"]\n",
"features_data = pd.get_dummies(\n",
" features_data, columns=categorical_columns, drop_first=True\n",
")\n",
"\n",
"# --- 2. Дискретизация числовых признаков ---\n",
"# Пример: Дискретизация возраста автомобиля\n",
"current_year = 2025\n",
"features_data[\"Car age\"] = current_year - features_data[\"Prod. year\"]\n",
"features_data[\"Car age bins\"] = pd.cut(\n",
" features_data[\"Car age\"],\n",
" bins=[0, 5, 10, 20, 50],\n",
" labels=[\"0-5\", \"6-10\", \"11-20\", \"21+\"],\n",
")\n",
"\n",
"# Дискретизация пробега\n",
"features_data[\"Mileage bins\"] = pd.qcut(\n",
" features_data[\"Mileage\"].fillna(0),\n",
" q=4,\n",
" labels=[\"Low\", \"Medium\", \"High\", \"Very High\"],\n",
")\n",
"\n",
"# --- 3. «Ручной» синтез признаков ---\n",
"# Индикатор турбонаддува\n",
"features_data[\"Turbo\"] = (\n",
" features_data[\"Engine volume\"].str.contains(\"Turbo\").astype(int)\n",
") # Индикатор турбонаддува\n",
"features_data[\"Engine volume\"] = features_data[\"Engine volume\"].str.replace(\n",
" \" Turbo\", \"\"\n",
") # Убираем текст 'Turbo'\n",
"features_data[\"Engine volume\"] = features_data[\"Engine volume\"].astype(\n",
" float\n",
") # Преобразуем в float\n",
"# Рейтинг безопасности\n",
"features_data[\"Safety rating\"] = (\n",
" features_data[\"Airbags\"] / features_data[\"Airbags\"].max()\n",
")\n",
"\n",
"# Редкость цвета\n",
"color_frequency = features_data[\"Color\"].value_counts(normalize=True)\n",
"features_data[\"Color rarity\"] = features_data[\"Color\"].map(color_frequency)\n",
"\n",
"# --- 4. Масштабирование признаков ---\n",
"# Масштабирование числовых признаков с использованием нормализации (Min-Max Scaling)\n",
"scaler_minmax = MinMaxScaler()\n",
"numerical_features = [\"Mileage\", \"Engine volume\", \"Cylinders\", \"Levy\"]\n",
"features_data[numerical_features] = scaler_minmax.fit_transform(\n",
" features_data[numerical_features]\n",
")\n",
"\n",
"# Стандартизация (Standard Scaling) для числовых признаков\n",
"scaler_standard = StandardScaler()\n",
"features_data[numerical_features] = scaler_standard.fit_transform(\n",
" features_data[numerical_features]\n",
")\n",
"\n",
"# --- Удаление ненужных столбцов ---\n",
"columns_to_drop = [\"Prod. year\", \"Color\"] # Удаление лишних столбцов\n",
"features_data = features_data.drop(columns=columns_to_drop)\n",
"\n",
"# Просмотр итогового набора данных\n",
"features_data.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Оценка набора признаков по следующим критериям: предсказательная способность, скорость вычисления, надежность, корреляция и цельность.\n",
"\n",
" Предсказательная способность:\n",
"1. Код приводит к созданию большого числа новых признаков, что может повысить предсказательную способность модели, если эти признаки действительно значимы для задачи.\n",
"Например, создание индикатора турбонаддува, рейтинга безопасности и редкости цвета может улучшить способность модели делать точные предсказания.\n",
"Однако важно проверить, что эти признаки не приводят к переобучению.\n",
"\n",
"2. Скорость вычисления:\n",
"Операции, такие как кодирование категориальных признаков, дискретизация и масштабирование, могут замедлить процесс при больших наборах данных.\n",
"Особое внимание стоит уделить масштабированию, так как оно требует времени на преобразование значений, особенно если количество числовых признаков велико.\n",
"Признаки, полученные в результате ручного синтеза, такие как \"Turbo\", могут быть быстрыми для вычислений, но создание новых бинарных признаков увеличивает размер данных, что может замедлить вычисления.\n",
"\n",
"3. Надежность:\n",
"Признаки, созданные вручную, такие как \"Turbo\" и \"Safety rating\", могут быть более устойчивыми, так как они не зависят от структуры данных, а только от специфической логики.\n",
"Однако, например, дискретизация и кодирование категориальных переменных могут изменить поведение модели при изменении данных (например, когда в новых данных появляются новые категории).\n",
"\n",
"4. Корреляция:\n",
"Кодирование категориальных признаков создаст новые столбцы, и важно будет проверить корреляцию между этими новыми признаками, чтобы избежать избыточности.\n",
"Признаки, такие как возраст автомобиля и пробег, могут быть взаимосвязаны, что может потребовать дополнительных шагов для уменьшения корреляции (например, PCA или исключение одного из признаков).\n",
"\n",
"5. Целостность:\n",
"Код также не учитывает пропуски в данных (например, в столбцах \"Mileage\" или \"Engine volume\"). Эти пропуски могут повлиять на результат и должны быть обработаны до начала других этапов.\n",
"Например, при дискретизации пробега (pd.qcut()) используется .fillna(0), что может быть не оптимальным способом заполнения пропусков, так как это может привести к искажению данных."
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.12.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}