本篇通过加州房价预测线性回归作业,复盘新手最容易踩的5个典型坑:回归任务误用分层抽样、评估指标传参错误、变量逻辑顺序颠倒、占位符未替换、特征标准化流程混乱。
犯错是最好的学习,这篇帮你把弯路走直。


💻 一、作业完整代码(修正后最终版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import pandas as pd
import numpy as np
import matplotlib

matplotlib.use('Agg') # 设置非交互式后端
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

print("=== 多元线性回归作业 ===")

# 1. 加载数据
housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = housing.target

print(f"样本数: {X.shape[0]}, 特征数: {X.shape[1]}")
print(f"房价范围: {y.min():.2f} - {y.max():.2f}")

# ======================
# 基础多元线性回归
# ======================
print("\n=== 基础多元线性回归 ===")

# 划分数据(回归任务不加 stratify!)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)

# 训练与预测
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# 评估(对比 y_test 和 y_pred)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"均方误差 MSE: {mse:.4f}")
print(f"R2 分数: {r2:.4f}")

# ======================
# 特征工程与改进
# ======================
print("\n=== 特征标准化后 ===")

# 标准化流程:先 fit_transform 全量数据,再切分
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分标准化后的数据
X_train_scaled, X_test_scaled, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.2, random_state=42
)

# 训练新模型
model_scaled = LinearRegression()
model_scaled.fit(X_train_scaled, y_train)
y_pred_scaled = model_scaled.predict(X_test_scaled)

# 评估
mse_scaled = mean_squared_error(y_test, y_pred_scaled)
r2_scaled = r2_score(y_test, y_pred_scaled)
print(f"标准化后 MSE: {mse_scaled:.4f}")
print(f"标准化后 R2: {r2_scaled:.4f}")

print("\n作业完成")

⚠️ 二、避坑指南:5 个典型错误复盘

错误编号错误类型错误代码报错 / 后果原因分析正确做法
1分层抽样误用train_test_split(..., stratify=y)ValueError: The least populated class...混淆分类与回归:回归的 y 是连续值,无法分层回归任务直接删除 stratify 参数
2评估指标传参错位mean_squared_error(X_test, y_pred)数值无意义或报错MSE 对比的是“真实值”与“预测值”永远是 (y_test, y_pred)
3变量未定义先切分再标准化NameError: name 'X_scaled' is not defined逻辑顺序错误:试图使用还未创建的变量fit_transform(X) 再切分 X_scaled
4占位符未替换model.predict(...)ValueError: Expected 2D array...草稿未清理:... 无法识别传入特征数据 model.predict(X_test)
5标准化流程误解先切分再分别标准化数据泄露或效果差必须先拟合全量数据分布遵循“先整体转换,后切分”原则

📌 三、核心概念解惑
问题一:怎么判断是分类还是回归?什么时候用 stratify=y?

  1. 分类 vs 回归:一眼识别法

    判断维度回归 (Regression)分类 (Classification)
    目标变量 (y)连续的数值离散的类别 / 标签
    核心关键词预测“多少”、“大小”预测“是不是”、“哪一个”
    典型例子房价、气温、体重、销售额垃圾邮件、癌症检测、鸢尾花品种
    能否算平均值能(平均房价有意义)不能(平均类别无意义,只能算比例)
    本次作业✅ 预测房价(连续值)
  2. stratify=y 使用场景
    只能用在分类问题:且通常是数据不平衡时(如 95% 负样本,5% 正样本)
    作用:强制保证训练集和测试集的类别比例一致,避免少数类全被分到训练集
    回归绝对不能用:y 是连续值,计算机无法为每一个独特的数值 “分层”

问题二:函数括号里到底该放什么?
不用死记硬背!记住这套 “看后缀 + 查字典” 法则:

  1. 通用后缀法则
  2. 函数 / 方法后缀通常放什么核心逻辑例子
    .fit()(X_train, y_train)给模型看“习题和答案”让它学习model.fit(X_train, y_train)
    .predict()(X_test)只给“试卷”,让模型写答案(千万别给 y)model.predict(X_test)
    _score / _error(y_test, y_pred)拿“标准答案”和“模型答案”对分accuracy_score(y_test, y_pred)
    train_test_split(X, y)切分原始的全量数据train_test_split(X, y, …)
  3. PyCharm 终极绝招
    鼠标悬停或按 Ctrl+Q (Win) / Ctrl+J (Mac):查看函数签名
    看到 y_true 就填真实值,看到 X 就填特征,基本不会错

📚 学习心得
1.这次作业最大的收获不是跑通了线性回归,而是建立了严谨的机器学习代码逻辑:
2.先判断任务类型:拿到数据先看 y,决定是分类还是回归,这决定了后续所有代码
3.注意数据流动顺序:先处理数据,再切分,最后训练,逻辑不能乱
4.不要害怕报错:报错信息是最好的老师,仔细看报错内容,通常能直接定位问题
5.不要死记硬背:学会用 PyCharm 的参数提示和官方文档,这比背代码重要得多