机器学习 - 房价预测
买房时,人通常会综合判断:地段、面积、房龄、房间数量、人口密度、交通条件等,每一个因素都在影响价格,但这种影响并不是线性的、单一的,而是叠加、权衡、博弈后的结果。
机器学习中的回归问题,本质就是把这种「经验判断」变成一个可计算、可复用、可评估的数学模型。
本章节将从零开始,完整走一遍房价预测的标准机器学习流程:数据理解 → 特征分析 → 模型训练 → 模型评估 → 模型优化。目标不是记 API,而是理解每一步在做什么、为什么要做。
第一部分:项目准备与环境搭建
1.1 使用到的核心工具
- NumPy:底层数值计算工具,提供高效数组运算。
- Pandas:表格型数据分析核心工具,机器学习前期必备。
- Matplotlib / Seaborn:数据可视化,用于理解数据分布与关系。
- Scikit-learn:机器学习工具箱,涵盖数据集、模型、评估方法。
1.2 安装依赖
pip install numpy pandas matplotlib seaborn scikit-learn
第二部分:加载并理解数据集
早期教程常使用 Boston Housing 数据集,但该数据集已被弃用。这里使用官方推荐的 California 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())
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是我们要预测的目标
第三部分:探索性数据分析(EDA)
在训练模型之前,必须先回答一个问题:数据值不值得学?
3.1 数据结构与缺失值检查
实例:数据概览
print("特征维度:", df_features.shape)
print("目标维度:", df_target.shape)
print("\n数据类型与缺失情况:")
df_features.info()
print("\n缺失值统计:")
print(df_features.isnull().sum())
print("目标维度:", df_target.shape)
print("\n数据类型与缺失情况:")
df_features.info()
print("\n缺失值统计:")
print(df_features.isnull().sum())
结论:
- 样本量充足(2 万条左右)
- 全部为数值型特征
- 无缺失值,可直接建模
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('Average Rooms')
plt.ylabel('Median House Value')
plt.title('Rooms vs House Price')
plt.grid(True)
plt.show()
plt.figure(figsize=(8, 6))
plt.scatter(df_features['AveRooms'], df_target['MedHouseVal'], alpha=0.4)
plt.xlabel('Average Rooms')
plt.ylabel('Median House Value')
plt.title('Rooms vs House Price')
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('Feature Correlation Heatmap')
plt.show()
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('Feature Correlation Heatmap')
plt.show()
这一步的目的不是"选模型",而是确认:确实存在可学习的统计关系。
第四部分:构建第一个回归模型
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)
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}")
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.1 预测结果对比
实例:预测与真实值
y_pred = model.predict(X_test)
result = pd.DataFrame({
"Actual": y_test.values,
"Predicted": y_pred
})
print(result.head())
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 = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print("MSE:", mse)
print("R2:", r2)
解释:
- MSE 越小,预测误差越低
- R² 越接近 1,模型解释能力越强
第六部分:模型优化 —— 标准化与岭回归
6.1 为什么要标准化
不同特征量纲差异巨大,会导致模型偏向数值大的特征。
实例:特征标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
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))
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))
第七部分:完整流程回顾

点我分享笔记