pred_analytics/Lab3.ipynb
2025-01-13 14:42:39 +04:00

21 KiB
Raw Permalink Blame History

Лабораторная работа 3.

Определение бизнес и технических целей

  1. Прогнозирование цены автомобиля Бизнес-цель: Оптимизация ценовой политики. Техническая цель: Построение модели прогнозирования цены.

Конструирование признаков: Объем двигателя:

Извлечь числовую часть из столбца Engine volume (например, 3.5). Добавить бинарный признак: наличие турбонаддува (Turbo). Возраст автомобиля:

Вычислить возраст автомобиля как разницу между текущим годом и Prod. year. Привод (Drive wheels):

Закодировать тип привода (например, 4x4, Front, Rear) с помощью One-Hot Encoding. Категория автомобиля (Category):

Преобразовать категорию в числовые признаки с помощью One-Hot Encoding. Технические характеристики:

Нормализовать числовые параметры, такие как пробег (Mileage) и количество цилиндров (Cylinders). Состояние интерьера:

Закодировать признак наличия кожаного салона (Leather interior) как бинарный.

  1. Классификация популярности автомобиля Бизнес-цель: Изучение предпочтений клиентов. Техническая цель: Определение популярности автомобилей.

Конструирование признаков: Рейтинг безопасности:

Использовать количество подушек безопасности (Airbags) для создания индикатора безопасности автомобиля. Тип топлива:

Закодировать Fuel type как категориальный признак (например, Petrol, Diesel, Hybrid). Цвет автомобиля:

Создать признак редкости цвета на основе частоты его встречаемости в данных. Стоимость обслуживания:

Преобразовать Levy в числовой признак и обработать пропущенные значения (например, заменить на среднее/медианное значение). Сегмент рынка:

Объединить категории автомобилей (например, Jeep, Hatchback) в несколько сегментов (премиум, эконом, компакт). Особенности привода:

Создать бинарные признаки, указывающие на тип управления (Left wheel/Right-hand drive).

In [8]:
from sklearn.model_selection import train_test_split
import pandas as pd

data = pd.read_csv("car_price_prediction.csv")
# Preparing the data by removing unnecessary columns and handling categorical data
data_cleaned = data.copy()

# Converting "Levy" and "Mileage" to numeric (handling non-numeric values like '-')
data_cleaned["Levy"] = pd.to_numeric(data_cleaned["Levy"], errors="coerce")
data_cleaned["Mileage"] = (
    data_cleaned["Mileage"].str.replace(" km", "").str.replace(" ", "").astype(float)
)

# Dropping columns that are identifiers or too detailed for prediction (like ID, Model)
data_cleaned = data_cleaned.drop(["ID", "Model"], axis=1)

# Encoding categorical columns
categorical_cols = data_cleaned.select_dtypes(include="object").columns
data_encoded = pd.get_dummies(data_cleaned, columns=categorical_cols, drop_first=True)

# Splitting the data into features (X) and target (y)
X = data_encoded.drop("Price", axis=1)
y = data_encoded["Price"]

# Splitting into training, validation, and testing datasets
X_train, X_temp, y_train, y_temp = train_test_split(
    X, y, test_size=0.4, random_state=42
)  # 60% training data
X_val, X_test, y_val, y_test = train_test_split(
    X_temp, y_temp, test_size=0.5, random_state=42
)  # 20% validation, 20% testing

# Displaying the sizes of the datasets
X_train.shape, X_val.shape, X_test.shape, y_train.shape, y_val.shape, y_test.shape
Out[8]:
((11542, 215), (3847, 215), (3848, 215), (11542,), (3847,), (3848,))
In [14]:
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler, StandardScaler

# Копия исходного набора данных
features_data = data_cleaned.copy()

# --- 1. Унитарное кодирование категориальных признаков ---
# Кодирование категориальных переменных
categorical_columns = ["Drive wheels", "Category", "Fuel type", "Wheel"]
features_data = pd.get_dummies(
    features_data, columns=categorical_columns, drop_first=True
)

# --- 2. Дискретизация числовых признаков ---
# Пример: Дискретизация возраста автомобиля
current_year = 2025
features_data["Car age"] = current_year - features_data["Prod. year"]
features_data["Car age bins"] = pd.cut(
    features_data["Car age"],
    bins=[0, 5, 10, 20, 50],
    labels=["0-5", "6-10", "11-20", "21+"],
)

# Дискретизация пробега
features_data["Mileage bins"] = pd.qcut(
    features_data["Mileage"].fillna(0),
    q=4,
    labels=["Low", "Medium", "High", "Very High"],
)

# --- 3. «Ручной» синтез признаков ---
# Индикатор турбонаддува
features_data["Turbo"] = (
    features_data["Engine volume"].str.contains("Turbo").astype(int)
)  # Индикатор турбонаддува
features_data["Engine volume"] = features_data["Engine volume"].str.replace(
    " Turbo", ""
)  # Убираем текст 'Turbo'
features_data["Engine volume"] = features_data["Engine volume"].astype(
    float
)  # Преобразуем в float
# Рейтинг безопасности
features_data["Safety rating"] = (
    features_data["Airbags"] / features_data["Airbags"].max()
)

# Редкость цвета
color_frequency = features_data["Color"].value_counts(normalize=True)
features_data["Color rarity"] = features_data["Color"].map(color_frequency)

# --- 4. Масштабирование признаков ---
# Масштабирование числовых признаков с использованием нормализации (Min-Max Scaling)
scaler_minmax = MinMaxScaler()
numerical_features = ["Mileage", "Engine volume", "Cylinders", "Levy"]
features_data[numerical_features] = scaler_minmax.fit_transform(
    features_data[numerical_features]
)

# Стандартизация (Standard Scaling) для числовых признаков
scaler_standard = StandardScaler()
features_data[numerical_features] = scaler_standard.fit_transform(
    features_data[numerical_features]
)

# --- Удаление ненужных столбцов ---
columns_to_drop = ["Prod. year", "Color"]  # Удаление лишних столбцов
features_data = features_data.drop(columns=columns_to_drop)

# Просмотр итогового набора данных
features_data.head()
Out[14]:
Price Levy Manufacturer Leather interior Engine volume Mileage Cylinders Gear box type Doors Airbags ... Fuel type_LPG Fuel type_Petrol Fuel type_Plug-in Hybrid Wheel_Right-hand drive Car age Car age bins Mileage bins Turbo Safety rating Color rarity
0 13328 1.065632 LEXUS Yes 1.357980 -0.027813 1.180937 Automatic 04-May 12 ... False False False False 15 11-20 High 0 0.750 0.197120
1 16621 0.240688 CHEVROLET No 0.788363 -0.027689 1.180937 Tiptronic 04-May 8 ... False True False False 14 11-20 Very High 0 0.500 0.261631
2 8467 NaN HONDA No -1.148338 -0.027524 -0.485866 Variator 04-May 2 ... False True False True 19 11-20 Very High 0 0.125 0.261631
3 3607 -0.097084 FORD Yes 0.218745 -0.028165 -0.485866 Automatic 04-May 0 ... False False False False 14 11-20 High 0 0.000 0.233352
4 11726 -0.997809 HONDA Yes -1.148338 -0.029757 -0.485866 Automatic 04-May 4 ... False True False False 11 11-20 Medium 0 0.250 0.197120

5 rows × 35 columns

Оценка набора признаков по следующим критериям: предсказательная способность, скорость вычисления, надежность, корреляция и цельность.

Предсказательная способность:

  1. Код приводит к созданию большого числа новых признаков, что может повысить предсказательную способность модели, если эти признаки действительно значимы для задачи. Например, создание индикатора турбонаддува, рейтинга безопасности и редкости цвета может улучшить способность модели делать точные предсказания. Однако важно проверить, что эти признаки не приводят к переобучению.

  2. Скорость вычисления: Операции, такие как кодирование категориальных признаков, дискретизация и масштабирование, могут замедлить процесс при больших наборах данных. Особое внимание стоит уделить масштабированию, так как оно требует времени на преобразование значений, особенно если количество числовых признаков велико. Признаки, полученные в результате ручного синтеза, такие как "Turbo", могут быть быстрыми для вычислений, но создание новых бинарных признаков увеличивает размер данных, что может замедлить вычисления.

  3. Надежность: Признаки, созданные вручную, такие как "Turbo" и "Safety rating", могут быть более устойчивыми, так как они не зависят от структуры данных, а только от специфической логики. Однако, например, дискретизация и кодирование категориальных переменных могут изменить поведение модели при изменении данных (например, когда в новых данных появляются новые категории).

  4. Корреляция: Кодирование категориальных признаков создаст новые столбцы, и важно будет проверить корреляцию между этими новыми признаками, чтобы избежать избыточности. Признаки, такие как возраст автомобиля и пробег, могут быть взаимосвязаны, что может потребовать дополнительных шагов для уменьшения корреляции (например, PCA или исключение одного из признаков).

  5. Целостность: Код также не учитывает пропуски в данных (например, в столбцах "Mileage" или "Engine volume"). Эти пропуски могут повлиять на результат и должны быть обработаны до начала других этапов. Например, при дискретизации пробега (pd.qcut()) используется .fillna(0), что может быть не оптимальным способом заполнения пропусков, так как это может привести к искажению данных.