课程竞赛:加州 2020 年房价预测——从数据预处理到模型训练完整实战

一、前言

在学习完“实战 Kaggle 比赛:预测房价”之后,我发现自己对表格数据建模已经有了一个初步认识,但如果只停留在跟着案例跑代码,其实还不够。因为真正到了课程竞赛或者自己做项目时,我们往往面对的是另一个问题:

数据集不再是教材里刚刚好整理好的形式,而是需要我们自己分析、自己处理、自己建模。

“加州 2020 年房价预测”这一类课程竞赛题,和前面的 Kaggle 房价预测非常像,都是典型的回归任务,但它更适合拿来练手。因为在这个过程中,我们不仅要会写模型,还要真正理解:

  • 如何看懂表格数据

  • 如何判断哪些特征需要处理

  • 如何处理缺失值

  • 如何处理类别型特征

  • 如何选择评价指标

  • 如何从训练误差和验证误差判断模型状态

所以这篇文章,我就把“课程竞赛:加州 2020 年房价预测”整理成一篇完整实战笔记,按照 项目背景 → 问题分析 → 数据处理 → 模型构建 → 训练评估 → 总结反思 的顺序来讲。


二、题目本质:这是一个什么问题

“加州 2020 年房价预测”本质上是在做这样一件事:

根据房屋所在地区、人口、收入、房间数量、地理位置等信息,预测该地区或该房屋的价格。

这属于机器学习中的监督学习问题。

因为我们手里有一批历史样本,每个样本都包含:

  • 输入特征

  • 对应的真实房价标签

同时,这又是一个非常典型的回归问题,因为预测目标不是某一类,而是一个连续实数,比如:

  • 120000

  • 286500

  • 450000

  • 680000

所以整个任务可以理解为:

[
\text{房屋特征} \rightarrow \text{房价数值}
]


三、为什么房价预测经常被拿来做练习

房价预测几乎是机器学习和深度学习入门里最经典的表格任务之一,因为它有几个特别明显的特点。

1. 特征类型丰富

房价相关的数据通常会包含:

  • 数值特征:房间数、人口数、中位收入、房龄

  • 地理特征:经度、纬度

  • 类别特征:靠海情况、区域类别等

这让我们可以练到最常见的数据处理方法。

2. 数据比较贴近现实

和纯数学构造的数据不同,房价数据和现实联系很强,比较容易理解,也更方便分析特征和结果之间的关系。

3. 适合练完整流程

它既可以用线性回归做基线,也可以用神经网络做改进,非常适合练习:

  • 数据预处理

  • 特征工程

  • 模型搭建

  • 回归评价

  • 结果分析

所以这种题目非常适合作为课程竞赛、作业项目或者机器学习入门实战。


四、加州房价预测任务中可能用到的特征

在加州房价数据中,常见字段一般包括下面这些内容。

1. 地理位置相关

  • longitude:经度

  • latitude:纬度

这两个特征很重要,因为房价和地理位置高度相关。

2. 房屋结构相关

  • housing_median_age:房龄中位数

  • total_rooms:房间总数

  • total_bedrooms:卧室总数

  • households:住户数量

这些特征反映了房屋或区域住宅的基本情况。

3. 人口与经济相关

  • population:人口数

  • median_income:中位收入

通常来说,中位收入和房价往往有比较强的正相关关系。

4. 类别型特征

  • ocean_proximity:离海远近,比如:

    • <1H OCEAN

    • INLAND

    • NEAR BAY

    • NEAR OCEAN

这类字符串字段不能直接送进模型,需要进一步编码。

5. 目标值

  • median_house_value:房价中位数

这就是我们要预测的标签。


五、这类题目的难点到底在哪里

很多人一开始会觉得,房价预测这种任务,不就是“丢给模型训练一下”吗?

其实不是。真正的难点通常有以下几个。

1. 表格数据往往不干净

比如:

  • 存在缺失值

  • 数值范围差异大

  • 字段含义复杂

  • 类别特征无法直接使用

2. 模型不一定是最难的部分

在表格任务里,很多时候不是模型不够复杂,而是:

  • 特征没处理好

  • 数据没标准化

  • 缺失值处理不合理

  • 类别变量编码不统一

3. 回归任务更看重误差分析

和分类任务不同,回归任务不是看“对了几个”,而是看预测值和真实值差多少。
所以你必须真正理解评价指标。


六、完整实战流程梳理

如果让我把这个课程竞赛题整理成标准做法,我会把流程分成下面几步:

第一步:读取数据

先用 Pandas 把 CSV 文件读进来。

第二步:观察数据基本情况

看:

  • 数据维度

  • 字段类型

  • 是否有缺失值

  • 标签列是哪一列

第三步:区分数值特征和类别特征

因为它们的处理方法不一样。

第四步:做数据预处理

包括:

  • 缺失值填补

  • 数值标准化

  • 类别特征编码

第五步:划分训练集和验证集

不能只看训练误差,必须看泛化能力。

第六步:建立基线模型

可以先用线性回归或者单层网络。

第七步:训练并评估

根据损失变化和验证误差来判断效果。

第八步:调参和改进

比如:

  • 改学习率

  • 改 batch size

  • 加隐藏层

  • 加正则化


七、为什么要先做数据分析而不是直接建模

这一点特别重要。

在课程竞赛里,老师真正想看的,往往不只是你把模型跑出来,而是你有没有形成基本的数据分析意识。
所以拿到数据之后,不应该直接上模型,而应该先问自己:

  • 哪些特征是数值型?

  • 哪些特征是类别型?

  • 哪些列有缺失值?

  • 标签的分布大概是什么样?

  • 不同特征的尺度差异大不大?

因为这些问题会直接影响你后面的预处理方式。

举个简单例子:

  • 如果中位收入范围在 1 到 15

  • 房间总数范围在几百到几万

那么如果不标准化,模型训练时后者的影响可能会远大于前者。


八、数值特征的处理方法

数值特征通常是最先处理的一类。

1. 标准化

最常见的方法就是标准化:

也就是让数据变成均值接近 0、方差接近 1 的分布。

这样做的好处是:

  • 不同特征尺度更统一

  • 梯度下降更稳定

  • 模型更容易收敛

对于神经网络来说,这一步尤其重要。


2. 缺失值填补

数值特征如果有缺失值,一般常见做法是:

  • 用均值填补

  • 用中位数填补

  • 标准化后用 0 填补

如果你是先标准化再处理,那么用 0 填补通常比较自然,因为 0 在这时大致对应“平均水平”。


九、类别特征的处理方法

类别特征不能直接送入线性模型或普通神经网络,因为模型看不懂字符串。

例如:

  • INLAND

  • NEAR OCEAN

  • NEAR BAY

这些对我们来说是有意义的词,但对模型来说不是数值。

所以通常需要做 one-hot 编码

1. 什么是 one-hot 编码

假设 ocean_proximity 有三种取值:

  • A

  • B

  • C

那么编码后会变成三列:

  • 是否为 A

  • 是否为 B

  • 是否为 C

对应取值是 0 或 1。

2. 为什么不用随便编号

比如不能简单写成:

  • A = 1

  • B = 2

  • C = 3

因为这样会让模型误以为 C 比 B 大,B 比 A 大,但类别之间未必存在这种大小规律。

所以 one-hot 编码更合理。


十、为什么回归任务常常要看 RMSE 或 MAE

在分类问题中,我们常看准确率。
但在房价预测里,准确率根本不适用,因为输出是连续值。

所以回归任务通常会看下面几类指标。


十一、为什么先建立一个简单基线模型

这是做项目时非常重要的思维。

很多同学喜欢一上来就上复杂模型,但其实更好的做法是:

先做一个简单但能完整跑通的基线模型。

比如:

  • 线性回归

  • 单层全连接网络

  • 一个简单的 MLP

原因很简单:

1. 能先验证流程有没有问题

如果连最简单模型都跑不通,那说明问题可能出在:

  • 数据读取

  • 预处理

  • 标签构造

  • 损失函数设计

2. 方便后续比较

你后面再加隐藏层、换优化器、加正则化,才知道到底有没有提升。

3. 更适合课程竞赛展示

老师通常也喜欢看到你有“从基线到优化”的完整思路,而不是只给出一个黑箱结果。


十二、一个适合课程竞赛的基础模型思路

对于加州房价预测,最基础的建模方式可以这样设计:

方案一:线性回归基线

模型结构:

[
\hat{y} = Wx + b
]

优点:

  • 简单

  • 易于解释

  • 适合做 baseline

缺点:

  • 表达能力有限

  • 无法建模复杂非线性关系


方案二:简单多层感知机 MLP

例如:

  • 输入层

  • 一个隐藏层

  • ReLU 激活

  • 输出层

优点:

  • 能表达更复杂关系

  • 比线性模型更灵活

缺点:

  • 更容易过拟合

  • 对学习率、初始化更敏感

如果是课程竞赛,我一般会建议:

先做线性基线,再做一个简单 MLP 作为改进版。

这样报告写出来层次会更清楚。


十三、PyTorch 实战代码示例

下面给你一版适合 CSDN 的基础代码,假设数据文件名为 housing.csv
这份代码偏教学风格,便于你自己理解和改写。

import torch
from torch import nn
from torch.utils.data import DataLoader, TensorDataset
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

# 1. 读取数据
data = pd.read_csv("housing.csv")

# 2. one-hot 编码处理类别特征
data = pd.get_dummies(data, dummy_na=True)

# 3. 假设标签列为 median_house_value
features = data.drop("median_house_value", axis=1)
labels = data["median_house_value"]

# 4. 数值标准化
features = (features - features.mean()) / features.std()
features = features.fillna(0)

# 5. 划分训练集和验证集
X_train, X_valid, y_train, y_valid = train_test_split(
    features, labels, test_size=0.2, random_state=42
)

# 6. 转换为张量
X_train = torch.tensor(X_train.values, dtype=torch.float32)
X_valid = torch.tensor(X_valid.values, dtype=torch.float32)
y_train = torch.tensor(y_train.values.reshape(-1, 1), dtype=torch.float32)
y_valid = torch.tensor(y_valid.values.reshape(-1, 1), dtype=torch.float32)

# 7. 构建 DataLoader
batch_size = 64
train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

# 8. 定义模型
in_features = X_train.shape[1]
net = nn.Sequential(
    nn.Linear(in_features, 128),
    nn.ReLU(),
    nn.Linear(128, 1)
)

# 9. 损失函数和优化器
loss_fn = nn.MSELoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)

# 10. 评估函数:计算 RMSE
def rmse(net, X, y):
    with torch.no_grad():
        preds = net(X)
        mse = loss_fn(preds, y)
        return torch.sqrt(mse).item()

# 11. 开始训练
num_epochs = 100

for epoch in range(num_epochs):
    net.train()
    for X_batch, y_batch in train_loader:
        optimizer.zero_grad()
        preds = net(X_batch)
        loss = loss_fn(preds, y_batch)
        loss.backward()
        optimizer.step()

    if (epoch + 1) % 10 == 0:
        net.eval()
        train_rmse = rmse(net, X_train, y_train)
        valid_rmse = rmse(net, X_valid, y_valid)
        print(f"epoch {epoch+1}, train rmse {train_rmse:.4f}, valid rmse {valid_rmse:.4f}")

十四、这段代码在做什么

这段代码虽然不算复杂,但已经体现了一个表格回归项目的核心流程。

1. pd.read_csv()

读取原始数据。

2. pd.get_dummies()

对类别特征做 one-hot 编码。

3. 标准化

统一各个数值特征的尺度。

4. train_test_split()

划分训练集和验证集,用于评估泛化能力。

5. TensorDataset + DataLoader

构造小批量训练数据。

6. nn.Sequential

搭建一个简单的多层感知机。

7. MSELoss

用于回归任务。

8. Adam

常用优化器,收敛一般比较稳定。

9. RMSE

作为更直观的回归评价指标。


十五、如果效果不好,该怎么改

课程竞赛中,跑出结果只是第一步,后面更重要的是分析和改进。

如果模型效果不理想,可以从以下几个方向排查。

1. 数据预处理是否合理

先检查:

  • 有没有缺失值没处理

  • 类别编码是否正确

  • 标准化是否做了

  • 标签是否读取错了

2. 模型是否太简单

如果线性模型效果一般,可以尝试:

  • 加一层隐藏层

  • 增加隐藏单元

  • 使用更合适的激活函数

3. 是否过拟合

如果训练误差很低,验证误差很高,可能是过拟合。
可以尝试:

  • 减小模型规模

  • weight_decay

  • 加 Dropout

  • 增加数据量

4. 学习率是否合适

学习率太大,训练会震荡;
学习率太小,收敛会很慢。

5. 标签是否适合取对数

房价数据经常右偏明显,有时可以尝试对标签取对数后再训练,让分布更平稳。


十六、课程竞赛报告里可以怎么写“改进思路”

如果你后面要把这个题写成课程作业、实验报告或者答辩内容,可以这样组织。

1. 基线模型

先用线性回归或简单 MLP 建立最基础模型。

2. 数据预处理优化

对比不同缺失值处理和标准化方式。

3. 特征工程优化

例如:

  • 构造人均房间数

  • 构造人均卧室数

  • 构造每户平均人口数

这些组合特征往往比原始特征更有解释力。

4. 模型优化

尝试:

  • 更深一点的 MLP

  • 正则化

  • Dropout

  • 不同优化器

5. 验证方式优化

使用 K 折交叉验证,让结果更稳定。

这样你写出来的报告就不只是“我跑了个模型”,而是有了完整的实验思路。


十七、这一题真正锻炼了什么能力

我觉得“加州 2020 年房价预测”这类课程竞赛题,真正锻炼的能力主要有三种。

1. 数据理解能力

不是拿到数据就训练,而是先看字段、看分布、看缺失。

2. 结构化数据建模能力

学会针对表格数据设计处理流程,而不是只会图像任务。

3. 实验分析能力

不只是给出结果,还能解释:

  • 为什么这样处理

  • 为什么这样建模

  • 为什么误差会变大或变小

这恰恰是课程竞赛最看重的部分。


十八、我对这个题目的理解

学完这一类房价预测任务后,我最大的感受是:

以前总觉得机器学习比赛比的是“谁模型更高级”,但真正自己做下来才发现,很多时候比的其实是:

  • 谁更会处理数据

  • 谁更会分析特征

  • 谁更会构建合理的实验流程

尤其是这种表格数据任务,模型复杂度并不是唯一关键。
一个预处理扎实、验证合理、思路清晰的简单模型,往往比胡乱堆层数更有价值。

所以对初学者来说,这类课程竞赛题目非常适合拿来训练自己的项目感和实验感。


十九、结语

“课程竞赛:加州 2020 年房价预测”是一个非常适合机器学习入门和课程实战训练的题目。
它不像纯理论章节那样偏抽象,而是非常贴近真实项目流程。

通过这个题目,我们可以系统练到:

  • 表格数据读取

  • 缺失值处理

  • 数值特征标准化

  • 类别特征编码

  • 回归模型训练

  • 验证误差分析

  • 模型改进思路设计

如果你能把这一题真正做扎实,后面再做其他表格类竞赛或者课程项目时,就会顺很多。


二十、重点速记版

1. 这个任务是什么类型

监督学习中的回归任务。

2. 预测目标是什么

房价数值。

3. 数值特征怎么处理

标准化,必要时填补缺失值。

4. 类别特征怎么处理

one-hot 编码。

5. 常用评价指标是什么

RMSE、MSE、MAE。

6. 为什么先做基线模型

为了先跑通流程,并为后续优化提供对比基准。

7. 如果效果差怎么改

检查预处理、调整模型、加入正则化、修改学习率、优化特征工程。


以上就是我对“课程竞赛:加州 2020 年房价预测”这一题的学习整理。
这一题虽然表面上是一个普通的回归任务,但真正做下来之后,会发现它几乎把表格数据建模的核心流程都覆盖到了。

对于刚接触机器学习实战的同学来说,这类题目非常值得认真做一遍,因为它训练的并不只是代码能力,更是完整的数据分析和实验设计思维。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐