Лабораторная работа №8: Линейная Регрессия
Цель: Построить первую регрессионную модель для предсказания стоимости жилья. Мы научимся интерпретировать веса модели (выясним, какой фактор важнее всего), диагностировать проблему мультиколлинеарности и правильно оценивать качество предсказания с помощью метрик RMSE и .
Инструменты:
sklearn.linear_model: Линейная регрессия.sklearn.metrics: MAE, MSE, R2.seaborn: Визуализация корреляций и весов.
Данные: California Housing. Набор данных содержит информацию о жилых районах Калифорнии (1990 г.).
- Целевая переменная (
target): Медианная стоимость дома (в единицах $100,000). - Признаки: Медианный доход (
MedInc), Средний возраст домов, Среднее кол-во комнат и т.д.
Часть 1: Загрузка и Анализ корреляций
Прежде чем строить модель, нужно проверить данные на наличие мультиколлинеарности (когда признаки дублируют друг друга).
Проблема мультиколлинеарности
Линейная регрессия “сходит с ума” и выдает некорректные веса, если два признака имеют корреляцию близкую к 1 или -1. Именно поэтому анализ тепловой карты обязателен.
Задание 1.1: Тепловая карта
- Загрузите данные
fetch_california_housing. - Создайте DataFrame.
- Постройте тепловую карту корреляций (
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: Обучение
- Обучите
LinearRegressionна масштабированных данных. - Выведите свободный член (,
intercept_) и коэффициенты (,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: Расчет ошибок
- Сделайте предсказание для Test.
- Посчитайте метрики:
- MAE (Средняя абсолютная ошибка).
- MSE (Среднеквадратичная ошибка).
- RMSE (Корень из MSE).
- (Коэффициент детерминации).
Бизнес-интерпретация
Напоминание: Целевая переменная измеряется в **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)
# ...