Машинное обучение - прогнозирование цен на дома
При покупке дома люди обычно проводят комплексную оценку: расположение, площадь, возраст недвижимости, количество комнат, плотность населения, транспортные условия и т. д. Каждый фактор влияет на цену, но это влияние не является линейным или единичным; скорее, оно представляет собой результат накопления, компромиссов и конкуренции между факторами.
В машинном обучении,задачи регрессии, по сути, превращают это «основанное на опыте суждение» в вычислимую, пригодную для многократного использования и оцениваемую математическую модель.
В этой главе мы с нуля пройдём полный стандартный конвейер машинного обучения дляпрогнозирования цен на жильё: понимание данных → анализ признаков → обучение модели → оценка модели → оптимизация модели. Цель — не запомнить 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набор данных, который имеет ту же концепцию, но более стандартизированные данные.
Пример: загрузка данных
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_target.shape)
print("\n"Типы данных и пропущенные значения:")
df_features.info()
print("\n"Статистика пропущенных значений:")
print(df_features.isnull().sum())
Заключение:
- Достаточный размер выборки (около 20,000 записей)
- Все признаки являются числовыми
- Нет пропущенных значений, можно напрямую строить модель
3.2 Связь между отдельным признаком и ценой дома
Машинное обучение — не чёрный ящик; по крайней мере на вводном этапе вы должны знать, чему учится модель.
Пример: связь между количеством комнат и ценой дома
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 Анализ корреляции признаков
Пример: тепловая карта корреляции
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 Разделение на обучающую и тестовую выборки
Модель не может использовать одну и ту же выборку данных как для обучения, так и для тестирования; в противном случае результаты оценки не имеют смысла.
Пример: разделение набора данных
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 Обучение модели линейной регрессии
Пример: обучение модели
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 Сравнение результатов прогнозирования
Пример: прогнозы и истинные значения
result = pd.DataFrame({
"Actual": y_test.values,
"Predicted": y_pred
})
print(result.head())
5.2 Количественная оценка модели с помощью метрик оценки
Пример: метрики оценки
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 Зачем стандартизировать?
Огромные различия в масштабах признаков приводят к тому, что модель будет смещаться в сторону признаков с большими значениями.
Пример: стандартизация признаков
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
6.2 Использование гребневой регрессии для подавления переобучения
Пример: гребневая регрессия
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: Полный обзор конвейера
