基于BP神经网络的波士顿房价预测实战:从数据预处理到模型调优

1次阅读
没有评论

共计 2089 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

问题背景

在房价预测任务中,我们常常遇到以下数据挑战:

基于 BP 神经网络的波士顿房价预测实战:从数据预处理到模型调优

  • 特征尺度差异:如房间数量(单位:间)与房产税(单位:万美元)数值量级相差悬殊
  • 特征共线性:如 ’ 距离就业中心距离 ’ 和 ’ 高速公路可达性 ’ 可能存在相关性
  • 非线性关系:房价与特征间往往存在复杂非线性关联

传统线性回归模型难以捕捉这些复杂关系。比如当尝试用线性模型拟合波士顿房价数据时,R2 分数通常只能达到 0.6-0.7,这促使我们转向更强大的 BP 神经网络。

技术方案

网络结构选型

在对比不同网络结构后,我们选择多层感知机 (MLP) 是因为:

  • CNN 更适合处理网格化数据(如图像)
  • RNN/LSTM 对时序数据的优势在房价预测中不显著
  • MLP 的通用逼近特性适合处理结构化特征

三层架构设计

  1. 输入层:13 个神经元,对应数据集的特征维度(CRIM、ZN 等)
  2. 隐藏层
  3. 通过试验确定 128 个神经元(经验公式:输入特征数×2~10 倍)
  4. 使用 ReLU 激活函数加速收敛
  5. 输出层
  6. 1 个神经元输出预测价格
  7. 不使用激活函数(回归任务)

核心实现

数据预处理

from sklearn.preprocessing import StandardScaler
import torch
from torch.utils.data import TensorDataset, DataLoader

# 特征标准化(关键步骤)scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 转换为 PyTorch 张量
tensor_X = torch.FloatTensor(X_scaled)
tensor_y = torch.FloatTensor(y).reshape(-1,1)

# 创建 DataLoader
batch_size = 32
dataset = TensorDataset(tensor_X, tensor_y)
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

网络定义

import torch.nn as nn

class HousePricePredictor(nn.Module):
    def __init__(self, input_dim=13):
        super().__init__()
        self.fc1 = nn.Linear(input_dim, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 1)
        self.dropout = nn.Dropout(0.2)  # 防止过拟合

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.dropout(x)
        x = torch.relu(self.fc2(x))
        return self.fc3(x)

调优实践

学习率策略对比

  1. 固定学习率(0.01):
  2. 训练初期收敛快
  3. 后期在最优值附近震荡

  4. StepLR(每 30 个 epoch 衰减为 0.1 倍):

  5. 初始 lr=0.05
  6. 稳定收敛至更优解

Early Stopping 实现

from copy import deepcopy

best_loss = float('inf')
patience = 10
counter = 0
best_model = None

for epoch in range(100):
    model.train()
    for X_batch, y_batch in dataloader:
        # ... 训练代码...

    val_loss = validate(model)

    if val_loss < best_loss:
        best_loss = val_loss
        best_model = deepcopy(model)
        counter = 0
    else:
        counter += 1
        if counter >= patience:
            print(f'Early stopping at epoch {epoch}')
            break

激活函数对比

激活函数 验证集 R2 训练时间
ReLU 0.91 2m30s
Sigmoid 0.87 3m15s

生产建议

模型轻量化

  • PCA 降维:当特征数从 13 减至 8 时,R2 仅下降 0.02
  • 量化:FP32→INT8 使模型大小减少 75%

在线预测

# 保存 scaler 用于线上环境
import joblib
joblib.dump(scaler, 'scaler.pkl') 

# 预测时使用相同的 scaler
def predict(new_data):
    scaled_data = scaler.transform(new_data)
    return model(torch.FloatTensor(scaled_data))

监控指标

  • 设置 MAE 波动阈值:当连续 3 次预测 MAE > 0.5 时触发告警
  • 特征漂移检测:定期计算线上数据与训练数据的 KL 散度

总结与思考

通过系统的特征工程、网络结构设计和调优策略,我们成功将模型 R2 分数提升至 0.9+。完整的 PyTorch 实现代码已放在 GitHub 仓库(伪代码)。

最后一个开放性问题:如果要处理非结构化数据(如房屋照片),如何扩展当前模型?可以考虑:

  1. 使用 CNN 提取图像特征
  2. 将结构化特征与图像特征在全连接层前拼接
  3. 设计多任务学习框架

期待在评论区看到你的创新方案!

正文完
 0
评论(没有评论)