波士顿房价预测是回归还是分类?多元 vs 多输出的区别

有人问:“波士顿房价预测(Boston Housing)是多分类问题吧?” 不是。这是回归问题(Regression)。顺带把三个常混的概念都拆一下——多元回归、多输出回归、多分类。

波士顿房价预测的本质

数据集大致:

CRIMRMLSTATPTRATIOMEDV(房价,单位万美元)
0.006326.5754.9815.324.0
0.027316.4219.1417.821.6
0.032376.9982.9418.733.4
  • 输入:13 个特征
  • 输出:MEDV = 房价,一个连续值(可以是 18.3、24.7、33.4…)

输出是连续数字 → 回归,不是分类。

什么时候会变成分类

自己把房价切段:

0 – 15  → "低价"
15 – 30 → "中价"
30+     → "高价"

这样任务就变成了三分类——但这已经不是原始 Boston Housing 任务了,是你人为改造的。原任务永远是回归。

三个概念区分

1. 多元回归(Multiple Regression)

多个输入特征 → 一个输出

波士顿房价就是这种:13 个特征 → 1 个房价。

import torch.nn as nn

model = nn.Sequential(
    nn.Linear(13, 64),
    nn.ReLU(),
    nn.Linear(64, 1),        # 输出 1 维
)
loss_fn = nn.MSELoss()

“多元”指的是输入的元数(features 多),不是输出多。

2. 多输出回归(Multi-output Regression)

多个输入 → 多个连续输出

例子:预测未来一栋房子的售价 + 出租金 + 涨幅百分比——3 个连续输出。

model = nn.Sequential(
    nn.Linear(13, 64),
    nn.ReLU(),
    nn.Linear(64, 3),        # 输出 3 维
)
loss_fn = nn.MSELoss()       # 依然是 MSE,输出是向量

3. 多分类(Multi-class Classification)

输入 → 多个类别中选一个

MNIST 手写数字识别是典型:

model = nn.Sequential(
    nn.Linear(784, 128),
    nn.ReLU(),
    nn.Linear(128, 10),        # 10 类
)
loss_fn = nn.CrossEntropyLoss()   # 内部含 softmax

标签是类别编号(整数 0-9),损失是 CrossEntropy。

4. 顺带:多标签分类(Multi-label Classification)

输入 → 多个类别可同时为真

例子:一张图片可能同时含”猫、狗、汽车”三个标签。

model = nn.Sequential(
    nn.Linear(784, 128),
    nn.ReLU(),
    nn.Linear(128, 3),
    nn.Sigmoid(),              # 每维独立 0-1
)
loss_fn = nn.BCELoss()         # 二元交叉熵

每维独立判 0 或 1。

四类对照表

任务类型输出个数输出类型最后一层损失例子
多元回归1连续Linear(_, 1)MSELossBoston Housing 房价
多输出回归K连续Linear(_, K)MSELoss同时预测房价 + 租金
二分类10/1Linear(_, 1)+SigmoidBCELoss垃圾邮件识别
多分类K类别编号Linear(_, K)CrossEntropyLossMNIST 数字识别
多标签分类KK 个 0/1Linear(_, K)+SigmoidBCELoss图片多标签

Boston Housing 数据集的争议

顺带一提——波士顿房价数据集本身有伦理问题。数据里有个特征 B(黑人人口相关变量)设计上带有种族偏见,2022 年 scikit-learn 明确 deprecated 了这个数据集:

# 老代码,会警告
from sklearn.datasets import load_boston

# 新推荐
from sklearn.datasets import fetch_california_housing

现在教学上一般用 California HousingAmes Housing 数据集替代——同样是回归任务,没有伦理争议、样本更多。

用 California Housing 的替代示例

from sklearn.datasets import fetch_california_housing
import torch, torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset

data = fetch_california_housing()
X = torch.tensor(data.data, dtype=torch.float32)
y = torch.tensor(data.target, dtype=torch.float32).unsqueeze(1)

loader = DataLoader(TensorDataset(X, y), batch_size=64, shuffle=True)

model = nn.Sequential(
    nn.Linear(8, 64),
    nn.ReLU(),
    nn.Linear(64, 32),
    nn.ReLU(),
    nn.Linear(32, 1),
)
optim = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.MSELoss()

for epoch in range(20):
    for x, target in loader:
        optim.zero_grad()
        pred = model(x)
        loss = loss_fn(pred, target)
        loss.backward()
        optim.step()
    print(f"epoch {epoch}: loss={loss.item():.4f}")

跑起来 20 轮 loss 会稳定下降——回归任务的经典流程。

一句话总结

波士顿房价 = 回归任务(输出连续价格),属于”多元回归”(多个输入 → 一个输出),不是”多输出回归”、也不是”多分类”。教学优先用 California Housing 数据集,避开原数据集的伦理争议。