Машинное обучение - прогнозирование цен на дома

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

В машинном обучении,задачи регрессии, по сути, превращают это «основанное на опыте суждение» в вычислимую, пригодную для многократного использования и оцениваемую математическую модель.

В этой главе мы с нуля пройдём полный стандартный конвейер машинного обучения дляпрогнозирования цен на жильё: понимание данных → анализ признаков → обучение модели → оценка модели → оптимизация модели. Цель — не запомнить API, а понять, что делает каждый шаг и зачем он выполняется.


Часть 1: Подготовка проекта и настройка окружения

1.1 Используемые ключевые инструменты

  • NumPy: низкоуровневый инструмент численных вычислений, обеспечивающий эффективные операции с массивами.
  • Pandas: основной инструмент для анализа табличных данных, необходимый на ранних этапах машинного обучения.
  • Matplotlib / Seaborn: визуализация данных, используемая для понимания распределений данных и взаимосвязей.
  • Scikit-learn: набор инструментов машинного обучения, охватывающий наборы данных, модели и методы оценки.

1.2 Установка зависимостей

pip install numpy pandas matplotlib seaborn scikit-learn

Часть 2: Загрузка и понимание набора данных

Early tutorials often used the Boston Housing dataset, but it has been deprecated. Here we use the officially recommendedCalifornia Housingнабор данных, который имеет ту же концепцию, но более стандартизированные данные.

Пример: загрузка данных

import pandas as pd
from sklearn.datasets import fetch_california_housing

# Загрузить набор данных о ценах на жилье в Калифорнии
data = fetch_california_housing()

# Данные признаков (X)
df_features = pd.DataFrame(
    data.data,
    columns=data.feature_names
)

# Целевая переменная (y): медианная стоимость дома
df_target = pd.DataFrame(
    data.target,
    columns=['MedHouseVal']
)

print(df_features.head())
print(df_target.head())

Вывод:

   MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup  Latitude  Longitude
0  8.3252      41.0  6.984127   1.023810       322.0  2.555556     37.88    -122.23
1  8.3014      21.0  6.238137   0.971880      2401.0  2.109842     37.86    -122.22
2  7.2574      52.0  8.288136   1.073446       496.0  2.802260     37.85    -122.24
3  5.6431      52.0  5.817352   1.073059       558.0  2.547945     37.85    -122.25
4  3.8462      52.0  6.281853   1.081081       565.0  2.181467     37.85    -122.25
   MedHouseVal
0        4.526
1        3.585
2        3.521
3        3.413
4        3.422

На этом этапе вы должны четко понимать три вещи:

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

Часть 3: Разведочный анализ данных (EDA)

Прежде чем обучать модель, вы должны сначала ответить на один вопрос:Стоит ли учиться на этих данных?

3.1 Структура данных и проверка пропущенных значений

Пример: обзор данных

print("Размерность признаков:", df_features.shape)
print("Размерность целевой переменной:", df_target.shape)

print("\n"Типы данных и пропущенные значения:")
df_features.info()

print("\n"Статистика пропущенных значений:")
print(df_features.isnull().sum())

Заключение:

  • Достаточный размер выборки (около 20,000 записей)
  • Все признаки являются числовыми
  • Нет пропущенных значений, можно напрямую строить модель

3.2 Связь между отдельным признаком и ценой дома

Машинное обучение — не чёрный ящик; по крайней мере на вводном этапе вы должны знать, чему учится модель.

Пример: связь между количеством комнат и ценой дома

import matplotlib.pyplot as plt

plt.figure(figsize=(8, 6))
plt.scatter(df_features['AveRooms'], df_target['MedHouseVal'], alpha=0.4)
plt.xlabel('Среднее количество комнат')
plt.ylabel('Медианная стоимость дома')
plt.title('Количество комнат и цена дома')
plt.grid(True)
plt.show()

Интуитивный вывод: чем больше комнат, тем выше цена дома в целом, но наблюдается значительный разброс. Именно для этого и нужна регрессионная модель.

3.3 Анализ корреляции признаков

Пример: тепловая карта корреляции

import seaborn as sns

df_all = pd.concat([df_features, df_target], axis=1)
corr = df_all.corr()

plt.figure(figsize=(10, 8))
sns.heatmap(corr, cmap='coolwarm', center=0)
plt.title('Тепловая карта корреляции признаков')
plt.show()

Цель этого шага — не «выбрать модель», а подтвердить: действительно существует статистическая взаимосвязь, которую можно изучить.


Часть 4: Построение первой регрессионной модели

4.1 Разделение на обучающую и тестовую выборки

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

Пример: разделение набора данных

from sklearn.model_selection import train_test_split

X = df_features
y = df_target['MedHouseVal']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

print("Обучающая выборка:", X_train.shape)
print("Тестовая выборка:", X_test.shape)

4.2 Обучение модели линейной регрессии

Пример: обучение модели

from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train, y_train)

print("Свободный член:", model.intercept_)
print("Коэффициенты:")
for name, coef in zip(X.columns, model.coef_):
    print(f"{name}: {coef:.4f}")

Преимущество линейной регрессии:высокая интерпретируемость,подходит для понимания сути задач регрессии.


Часть 5: Прогнозирование и оценка модели

5.1 Сравнение результатов прогнозирования

Пример: прогнозы и истинные значения

y_pred = model.predict(X_test)

result = pd.DataFrame({
    "Actual": y_test.values,
    "Predicted": y_pred
})

print(result.head())

5.2 Количественная оценка модели с помощью метрик оценки

Пример: метрики оценки

from sklearn.metrics import mean_squared_error, r2_score

mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print("MSE:", mse)
print("R2:", r2)

Пояснение:

  • Чем меньше MSE, тем ниже ошибка предсказания
  • Чем ближе R² к 1, тем выше объяснительная способность модели

Часть 6: Оптимизация модели — стандартизация и гребневая регрессия

6.1 Зачем стандартизировать?

Огромные различия в масштабах признаков приводят к тому, что модель будет смещаться в сторону признаков с большими значениями.

Пример: стандартизация признаков

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

6.2 Использование гребневой регрессии для подавления переобучения

Пример: гребневая регрессия

from sklearn.linear_model import Ridge

ridge = Ridge(alpha=1.0)
ridge.fit(X_train_scaled, y_train)

y_pred_ridge = ridge.predict(X_test_scaled)

print("Ridge MSE:", mean_squared_error(y_test, y_pred_ridge))
print("Ridge R2:", r2_score(y_test, y_pred_ridge))

Часть 7: Полный обзор конвейера

Другие расширения