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

Введение в ML: Линейная Регрессия

Лабораторная работа №8: Линейная Регрессия

Цель: Построить первую регрессионную модель для предсказания стоимости жилья. Мы научимся интерпретировать веса модели (выясним, какой фактор важнее всего), диагностировать проблему мультиколлинеарности и правильно оценивать качество предсказания с помощью метрик RMSE и R2R^2.

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

  • sklearn.linear_model: Линейная регрессия.
  • sklearn.metrics: MAE, MSE, R2.
  • seaborn: Визуализация корреляций и весов.

Данные: California Housing. Набор данных содержит информацию о жилых районах Калифорнии (1990 г.).

  • Целевая переменная (target): Медианная стоимость дома (в единицах $100,000).
  • Признаки: Медианный доход (MedInc), Средний возраст домов, Среднее кол-во комнат и т.д.

Часть 1: Загрузка и Анализ корреляций

Прежде чем строить модель, нужно проверить данные на наличие мультиколлинеарности (когда признаки дублируют друг друга).

Проблема мультиколлинеарности

Линейная регрессия “сходит с ума” и выдает некорректные веса, если два признака имеют корреляцию близкую к 1 или -1. Именно поэтому анализ тепловой карты обязателен.

Задание 1.1: Тепловая карта

  1. Загрузите данные fetch_california_housing.
  2. Создайте DataFrame.
  3. Постройте тепловую карту корреляций (sns.heatmap) для всех признаков (без целевой переменной).
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import fetch_california_housing

# Загрузка
data = fetch_california_housing()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target, name='Price')

print(X.head())

# TODO: Постройте матрицу корреляций и Heatmap
# plt.figure(figsize=(10, 8))
# corr_matrix = ...
# sns.heatmap(..., annot=True, fmt=".2f", cmap='coolwarm')
# plt.show()

# Вопрос: Есть ли пара признаков с корреляцией выше 0.8?

Часть 2: Подготовка и Масштабирование

Для линейной модели критически важно привести все признаки к одному масштабу. Иначе признак “Население” (тысячи людей) “задавит” признак “Количество спален” (единицы).


Часть 3: Обучение и Интерпретация весов

Самое ценное свойство линейной регрессии — мы можем “заглянуть ей под капот” и понять логику принятия решений.

Задание 3.1: Обучение

  1. Обучите LinearRegression на масштабированных данных.
  2. Выведите свободный член (w0w_0, intercept_) и коэффициенты (w1...wnw_1...w_n, coef_).
from sklearn.linear_model import LinearRegression

# TODO: Обучение модели
# model = LinearRegression()
# model.fit(..., ...)

# print(f"Intercept (w0): {model.intercept_:.2f}")
# print(f"Coefficients (w): {model.coef_}")

Задание 3.2: Визуализация важности признаков

Цифры читать неудобно. Давайте построим Barplot весов:

  • Большой положительный столб: признак сильно повышает цену.
  • Большой отрицательный столб: признак сильно снижает цену.
  • Около нуля: признак не важен.
# Создаем DataFrame с именами признаков и их весами
feature_names = data.feature_names
weights = model.coef_

coeff_df = pd.DataFrame({
    'Feature': feature_names,
    'Weight': weights
})

# Сортируем по абсолютному значению веса для наглядности
coeff_df['Abs_Weight'] = coeff_df['Weight'].abs()
coeff_df = coeff_df.sort_values(by='Abs_Weight', ascending=False)

# TODO: Постройте barplot (x='Weight', y='Feature')
# plt.figure(figsize=(10, 6))
# sns.barplot(...)
# plt.title("Веса признаков в линейной модели")
# plt.axvline(x=0, color='black', linestyle='--') # Линия на нуле
# plt.show()

Анализ результата

Какой фактор сильнее всего влияет на цену? (Ожидаемо MedInc). А какой фактор неожиданно тянет цену вниз?


Часть 4: Оценка качества (Метрики)

Насколько сильно мы ошибаемся в долларах?

Задание 4.1: Расчет ошибок

  1. Сделайте предсказание для Test.
  2. Посчитайте метрики:
    • MAE (Средняя абсолютная ошибка).
    • MSE (Среднеквадратичная ошибка).
    • RMSE (Корень из MSE).
    • R2R^2 (Коэффициент детерминации).

Бизнес-интерпретация

Напоминание: Целевая переменная измеряется в **100,000.Тоестьошибка0.5означаетошибкув100,000**. То есть ошибка 0.5 означает ошибку в 50,000.

from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

# TODO: Предсказание
# y_pred = ...

# TODO: Расчет метрик
# mae = ...
# mse = ...
# rmse = ...
# r2 = ...

# print(f"MAE:  {mae:.4f}")
# print(f"MSE:  {mse:.4f}")
# print(f"RMSE: {rmse:.4f}")
# print(f"R2:   {r2:.4f}")

Часть 5: Анализ остатков (Residuals) - Проверка “вшивости”

Если модель хорошая, её ошибки (остатки) должны быть распределены случайно (нормальное распределение вокруг нуля). Если мы видим паттерн — модель что-то упустила (нужна нелинейная модель).

Задание 5.1: График остатков

Постройте Scatter plot:

  • Ось X: Предсказанные значения (y_pred).
  • Ось Y: Остатки (y_test - y_pred).
  • Проведите горизонтальную линию на уровне 0.
residuals = y_test - y_pred

# TODO: Постройте график остатков
# plt.figure(figsize=(10, 6))
# plt.scatter(..., ..., alpha=0.5)
# plt.axhline(y=0, color='r', linestyle='--')
# plt.xlabel('Predicted Price')
# plt.ylabel('Residuals (Error)')
# plt.title('Residuals Plot')
# plt.show()

# TODO: Постройте гистограмму распределения остатков (sns.histplot)
# ...

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

Почему перед обучением линейной регрессии необходимо проверять данные на мультиколлинеарность (например, с помощью матрицы корреляций)?

Что означает наличие явного неслучайного паттерна (например, дуги или наклона) на графике остатков (Residuals Plot) линейной регрессии?