machine-learning Лабораторная работа

Лабораторная работа №6: Комплексный EDA и Feature Engineering

Лабораторная работа №6: Комплексный EDA и Feature Engineering

Цель: Научиться не просто “смотреть” на данные, а готовить их для моделей машинного обучения. Мы проведем очистку от выбросов, создадим новые сильные признаки (Feature Engineering) и преобразуем категориальные переменные в цифры.

Инструменты:

  • Python 3, Pandas, NumPy
  • Seaborn, Matplotlib
  • Датасет: Medical Cost Personal Datasets (Затраты на страховку).

Описание данных: Мы будем предсказывать charges (медицинские расходы). Признаки: age, sex, bmi (индекс массы тела), children, smoker, region.


Часть 1: Анализ и обработка выбросов (Outliers)

Выбросы могут исказить работу моделей (особенно линейных). Наша цель — найти их и аккуратно обработать.


Часть 2: Feature Engineering (Создание признаков)

Модели любят признаки, которые несут прямой физический смысл.

Задание 2.1: Категоризация (Binning)

Возраст — непрерывная величина. Иногда полезно разбить её на группы. Создайте колонку age_group на основе age:

  • 18-35: ‘Young’
  • 36-55: ‘Middle’
  • 56+: ‘Senior’

Используйте pd.cut.

# TODO: Создайте bins и labels
# bins = [17, 35, 55, 100]
# labels = ['Young', 'Middle', 'Senior']

# TODO: Примените pd.cut
# df['age_group'] = pd.cut(..., bins=bins, labels=labels)

# print(df['age_group'].value_counts())

Задание 2.2: Interaction Features (Взаимодействие)

В медицине известно: курение вредно. Но курение при ожирении (BMI > 30) — это смертельное комбо, которое резко повышает расходы.

Создайте признак obese_smoker (Ожирение + Курильщик):

  • Равен 1, если bmi > 30 И smoker == ‘yes’.
  • Равен 0 в остальных случаях.
# TODO: Создайте бинарный признак (можно использовать astype(int))
# df['obese_smoker'] = ...

# Проверим, как этот признак влияет на среднюю стоимость
# print(df.groupby('obese_smoker')['charges'].mean())

Часть 3: Трансформация целевой переменной

Посмотрите на распределение расходов (charges).

Проблема скошенных данных

Целевые переменные, связанные с деньгами, часто имеют длинный “хвост” вправо. Линейные модели с трудом предсказывают такие распределения, поэтому их нужно приводить к нормальному виду.

Задание 3.1: Log Transformation

  1. Постройте гистограмму charges. Вы увидите длинный “хвост” справа (Right Skewed). Модели такое не любят.
  2. Создайте колонку log_charges, применив натуральный логарифм: np.log1p (log(x+1)).
  3. Постройте гистограмму новой колонки. Она должна стать похожей на колокол.
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Исходное распределение
sns.histplot(df['charges'], ax=axes[0], kde=True)
axes[0].set_title('Original Charges')

# TODO: Примените логарифмирование
# df['log_charges'] = np.log1p(...)

# Логарифмированное распределение
# sns.histplot(df['log_charges'], ax=axes[1], kde=True)
# axes[1].set_title('Log Transformed Charges')

plt.show()

Часть 4: Кодирование (Encoding) и Корреляция

Чтобы увидеть полную картину, нужно превратить текст в цифры.

Задание 4.1: One-Hot Encoding

Преобразуйте категориальные переменные (sex, smoker, region, age_group) в числовой формат (One-Hot), используя pd.get_dummies.

  • Аргумент drop_first=True удаляет дублирующие столбцы (чтобы избежать мультиколлинеарности).
# Выбираем колонки для кодирования
categorical_cols = ['sex', 'smoker', 'region', 'age_group']

# TODO: Примените get_dummies
# df_encoded = pd.get_dummies(df, columns=categorical_cols, drop_first=True)

# print(df_encoded.head())

Задание 4.2: Финальная тепловая карта

Постройте Heatmap корреляций для df_encoded. Найдите топ-3 признака, которые сильнее всего коррелируют с charges.

plt.figure(figsize=(12, 10))

# TODO: Постройте heatmap для df_encoded
# corr = df_encoded.corr()
# sns.heatmap(corr, annot=True, fmt=".2f", cmap='coolwarm')

plt.show()

# Какой признак имеет самую высокую корреляцию с charges?
# Ответ напишите в комментарии.

🧠 Проверка знаний

Какая техника позволяет бороться с выбросами путем замены экстремальных значений на границу 'нормальности', не удаляя при этом всю строку из датасета?

Какой метод применяется к целевой переменной с сильным скосом вправо (Right Skewed), чтобы сделать её распределение более похожим на нормальное?