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

Лабораторная работа №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)

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

Задание 1.1:

  1. Загрузите датасет.
  2. Постройте Boxplot для колонки bmi. Видите точки за "усами"? Это выбросы.
  3. Постройте гистограмму распределения bmi.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
 
url = "[https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/insurance.csv](https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/insurance.csv)"
df = pd.read_csv(url)
 
# TODO: Постройте boxplot для 'bmi'
# plt.figure(figsize=(8, 4))
# sns.boxplot(...)
# plt.title("BMI Boxplot")
# plt.show()
 
# TODO: Постройте гистограмму (histplot/distplot) для 'bmi'
# ...

Часть 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), чтобы сделать её распределение более похожим на нормальное?

Следующий материалРаздел пройден