房价预测BP神经网络实现:从Excel数据到可运行回归模型
简介这份资源面向机器学习入门者与需要完成回归预测实战的开发者围绕经典波士顿房价数据集用Python从零实现BP神经网络完成房价预测。压缩包共2个文件含1个py脚本与1个csv数据文件整体约8KB其中csv提供14维房屋特征与中位房价目标变量py脚本承载网络搭建与训练全流程。代码覆盖数据读取与预处理、输入层到输出层的结构定义、前向传播计算、以方差为损失函数的反向传播权重更新以及迭代训练与测试集评估等环节并预留新样本预测接口便于读者理解神经网络回归的完整链路。目前已有21735人学习下载适合希望脱离框架、亲手推导梯度与调参的读者对照实践也可作为课程作业与项目原型的参考实现。1. 房价预测的BP神经网络实现从一份 Excel 到能跑的回归模型很多人第一次接触房价预测的BP神经网络实现都是被一份 Excel 表格逼出来的几十列特征、几百到几千行样本领导或导师丢过来一句“用 Python 跑个预测”。真上手才发现难点根本不在“BP 神经网络”这四个字而在数据怎么清洗、特征怎么对齐、输出层怎么设计、归一化放在哪一步。房价预测本质是一个连续值回归问题不是分类所以最后一层不能用 softmax损失函数也不能用交叉熵这是新手最容易翻车的地方。这篇笔记面向两类人一类是刚学完反向传播公式、想找个真实场景练手的同学另一类是手头有房价数据、想快速搭一个能出结果的基线模型的工程师。我会用一份模拟的房价数据集把 BP 神经网络从数据预处理、网络搭建、训练调参到结果验证整条链路走一遍代码可以直接抄。中间会重点讲清楚几个参数为什么这么设以及我踩过的坑。整套方案不依赖任何特定平台本地 Python 环境就能复现。2. 房价预测的数据准备与特征工程先让数据能进网络BP 神经网络对输入数据的“脾气”很挑量纲不统一、缺失值不处理、类别特征不编码训练出来的模型要么不收敛要么收敛了但预测值离谱。所以在写网络之前得先把数据整理成网络能吃的格式。2.1 房价数据的典型字段与清洗思路一份常见的房价数据字段大致分三类数值型面积、房龄、楼层、房间数、类别型朝向、装修程度、是否有电梯、区域、以及目标值成交价或单价。数值型字段里面积和房龄的量纲差了几十倍直接喂进网络会让梯度更新被大数值特征主导小数值特征几乎不起作用。清洗顺序我一般这样排先去重再处理缺失值然后处理异常值最后做编码和归一化。缺失值处理要看缺失比例缺失超过 40% 的字段直接丢掉缺失较少的数值字段用中位数填充类别字段用众数填充。异常值用四分位距法IQR识别超出上下界的样本先标记不要急着删因为有些高价房是真实存在的删了反而让模型学不到高价区间。import pandas as pd import numpy as np # 读取模拟房价数据 df pd.read_csv(house_price_sim.csv) # 去重 df df.drop_duplicates() # 数值字段缺失用中位数填充 num_cols [area, age, floor, room_num, hall_num] for col in num_cols: df[col] df[col].fillna(df[col].median()) # 类别字段缺失用众数填充 cat_cols [orientation, decoration, has_elevator, region] for col in cat_cols: df[col] df[col].fillna(df[col].mode()[0]) # IQR 标记异常值先不删只打印数量 for col in [area, price]: q1 df[col].quantile(0.25) q3 df[col].quantile(0.75) iqr q3 - q1 low q1 - 1.5 * iqr high q3 1.5 * iqr outlier_count ((df[col] low) | (df[col] high)).sum() print(f{col} 异常值数量: {outlier_count})这段代码的逻辑是先保证没有重复样本再分类型填充缺失最后用 IQR 只做识别不做删除。参数上中位数比均值抗异常值众数适合类别字段。IQR 的 1.5 倍是常规阈值如果数据本身分布很偏可以放宽到 3 倍但要在日志里记下来。2.2 类别特征编码与数值归一化的先后顺序类别特征不能直接变成数字因为“朝向南”和“朝向北”之间没有大小关系。常见做法是独热编码One-Hot把每个类别变成一个 0/1 列。如果类别取值很多比如区域有几十个独热后维度会爆炸这时候可以用目标编码或嵌入但基线模型先用独热就够了。归一化必须放在训练集和测试集划分之后用训练集的均值和标准差去变换测试集否则测试集的信息会泄漏到训练过程里评估结果会虚高。这是很多人容易忽略的一步。from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 独热编码类别字段 df pd.get_dummies(df, columnscat_cols, drop_firstTrue) # 分离特征和目标 X df.drop(columns[price]) y df[price].values.reshape(-1, 1) # 先划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) # 归一化用训练集拟合测试集只做变换 scaler_X StandardScaler() X_train scaler_X.fit_transform(X_train) X_test scaler_X.transform(X_test) scaler_y StandardScaler() y_train scaler_y.fit_transform(y_train) y_test scaler_y.transform(y_test)这里对特征和目标都做了标准化。目标值标准化是为了让损失函数数值稳定训练完预测时再用scaler_y.inverse_transform还原成真实房价。drop_firstTrue是为了避免独热编码的共线性少一列不影响信息量。random_state42保证每次划分一致方便复现。提示归一化只对数值型特征做独热后的 0/1 列不需要再标准化否则会破坏稀疏性。3. 用 PyTorch 搭一个能收敛的 BP 回归网络数据准备好之后网络结构本身其实不复杂。房价预测的 BP 网络通常是全连接结构输入维度等于特征数中间若干隐藏层输出层一个神经元对应房价。真正决定能不能收敛的是隐藏层宽度、激活函数、学习率和损失函数这几个选择。3.1 网络层数、隐藏单元与激活函数的选择输入维度由特征数决定这个不用手动设。隐藏层我一般从两层起步每层 64 或 128 个神经元。层数不是越多越好房价数据样本量通常不大层数太深容易过拟合而且梯度在反向传播中会衰减。激活函数隐藏层用 ReLU它计算简单、不容易饱和输出层不能用 ReLU因为房价可能是任意实数输出层直接线性输出。损失函数用均方误差MSELoss这是回归任务的标准选择。优化器用 Adam学习率从 0.001 开始试。如果训练损失震荡降到 0.0005如果下降太慢升到 0.005但不要超过 0.01否则容易跳过最优解。import torch import torch.nn as nn class HousePriceBPNet(nn.Module): def __init__(self, input_dim): super().__init__() self.net nn.Sequential( nn.Linear(input_dim, 128), nn.ReLU(), nn.Linear(128, 64), nn.ReLU(), nn.Linear(64, 1) # 输出层线性不加激活 ) def forward(self, x): return self.net(x) input_dim X_train.shape[1] model HousePriceBPNet(input_dim) criterion nn.MSELoss() optimizer torch.optim.Adam(model.parameters(), lr0.001)网络定义里nn.Linear(64, 1)是输出层输出一个标量。nn.Sequential把层按顺序串起来前向传播自动执行。参数上128 和 64 是隐藏单元数如果特征数超过 200第一层可以加到 256如果样本少于 500第一层降到 64 更稳。3.2 训练循环、批次大小与早停策略训练循环要处理三件事把 numpy 数据转成 tensor、按批次喂数据、每个 epoch 记录训练和验证损失。批次大小一般设 32 或 64样本少就用 16。早停策略是防止过拟合的关键如果验证损失连续 20 个 epoch 不下降就停止训练并保留验证损失最低的模型参数。from torch.utils.data import TensorDataset, DataLoader # 转成 tensor X_train_t torch.tensor(X_train, dtypetorch.float32) y_train_t torch.tensor(y_train, dtypetorch.float32) X_test_t torch.tensor(X_test, dtypetorch.float32) y_test_t torch.tensor(y_test, dtypetorch.float32) train_ds TensorDataset(X_train_t, y_train_t) train_loader DataLoader(train_ds, batch_size32, shuffleTrue) best_val_loss float(inf) patience 20 wait 0 best_state None for epoch in range(500): model.train() for xb, yb in train_loader: pred model(xb) loss criterion(pred, yb) optimizer.zero_grad() loss.backward() optimizer.step() # 验证 model.eval() with torch.no_grad(): val_pred model(X_test_t) val_loss criterion(val_pred, y_test_t).item() if val_loss best_val_loss: best_val_loss val_loss best_state model.state_dict() wait 0 else: wait 1 if wait patience: print(f早停于 epoch {epoch}) break model.load_state_dict(best_state)训练循环里optimizer.zero_grad()必须在loss.backward()之前调用否则梯度会累加。model.train()和model.eval()切换训练和评估模式虽然这个网络没有 Dropout 和 BatchNorm但养成习惯没坏处。早停的patience20是经验值数据噪声大可以调到 30数据干净可以降到 10。3.3 预测结果反归一化与评估指标计算训练完的模型输出是标准化后的房价必须用scaler_y.inverse_transform还原。评估指标用 MAE、RMSE 和 R²。MAE 反映平均绝对误差RMSE 对大误差更敏感R² 反映模型解释了多少方差。三个指标一起看才能判断模型是整体偏差还是个别样本预测离谱。from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score model.eval() with torch.no_grad(): pred_scaled model(X_test_t).numpy() # 反归一化 pred_price scaler_y.inverse_transform(pred_scaled) true_price scaler_y.inverse_transform(y_test_t.numpy()) mae mean_absolute_error(true_price, pred_price) rmse np.sqrt(mean_squared_error(true_price, pred_price)) r2 r2_score(true_price, pred_price) print(fMAE: {mae:.2f}) print(fRMSE: {rmse:.2f}) print(fR2: {r2:.4f})反归一化这一步不能省否则算出来的 MAE 是标准化空间的没有业务意义。R² 在 0.8 以上说明模型对房价的解释力不错低于 0.6 就要回头检查特征工程或网络结构。如果 RMSE 远大于 MAE说明存在个别预测严重偏离的样本需要单独看这些样本的特征。4. 房价预测 BP 网络的避坑与排查清单这一章是我自己踩过的坑按“现象 → 原因 → 解决”整理。每一条都对应一个具体的失败场景照着排查能省不少时间。4.1 损失不下降或变成 NaN现象训练几个 epoch 后损失变成 NaN或者一直停在某个值不动。原因最常见的是学习率太大导致梯度爆炸其次是输入数据没有归一化数值大的特征把梯度带飞还有一种情况是目标值没有标准化MSELoss 算出来的数值过大。解决先把学习率降到 0.0001 试一轮如果还 NaN检查输入数据是否有 inf 或 nan。用np.isfinite(X_train).all()确认。目标值标准化一定要做这一步省不得。4.2 训练损失低但测试损失高现象训练集 MAE 很小测试集 MAE 是训练集的两三倍。原因过拟合。房价数据样本少、特征多的时候特别容易发生。网络把训练样本背下来了但没有学到泛化规律。解决先加早停再考虑减小网络宽度比如把 128 降到 64。还可以加 Dropout 层nn.Dropout(0.2)放在两个隐藏层之间。如果数据量允许做 K 折交叉验证比单次划分更可靠。4.3 预测值全部集中在一个窄区间现象不管输入什么特征模型输出的房价都差不多方差很小。原因网络欠拟合或者输出层被错误地加了激活函数。如果输出层用了 ReLU负值会被截断成 0如果用了 Sigmoid输出会被压缩到 0 到 1 之间。解决确认输出层是nn.Linear且后面没有激活函数。检查隐藏层宽度是否太小输入特征是否被归一化过度导致信息丢失。可以先把网络调宽一层看预测方差是否变大。4.4 类别特征独热后维度爆炸现象独热编码后特征数从几十变成几百训练变慢内存吃紧。原因某个类别字段取值太多比如区域字段有上百个不同值。解决对高基数类别字段改用目标编码用目标均值替换类别或者把低频类别合并成“其他”。目标编码要在训练集上计算再应用到测试集避免泄漏。合并阈值一般设 5%出现次数少于 5% 的类别归为一类。4.5 反归一化后房价出现负数现象预测出来的房价有负数明显不合理。原因目标值标准化后模型输出的是标准分数反归一化时如果scaler_y的均值太小或标准差太大极端预测值可能变成负数。解决在反归一化后加一个下限截断pred_price np.maximum(pred_price, 0)。但更根本的是检查模型是否欠拟合负数通常出现在模型没学好、预测值偏离均值很远的时候。5. 让房价预测 BP 网络更稳的几个进阶技巧基线模型跑通之后如果想把 R² 从 0.8 推到 0.9或者想让模型在不同数据集上更稳可以试几个进阶做法。这些不是必须的但在我自己的项目里确实有效。第一个技巧是特征交叉。房价和“面积 × 区域”这种组合特征关系很大单纯把面积和区域分开喂给网络网络需要自己学交互项样本少的时候学不好。手动构造几个交叉特征比如“面积/房间数”“房龄 × 装修程度”能明显提升效果。构造完记得重新做归一化。第二个技巧是学习率调度。固定学习率在后期容易在最优解附近震荡用torch.optim.lr_scheduler.ReduceLROnPlateau在验证损失不下降时自动降学习率比手动调更省心。scheduler torch.optim.lr_scheduler.ReduceLROnPlateau( optimizer, modemin, factor0.5, patience10 ) # 在验证损失计算后调用 scheduler.step(val_loss)factor0.5表示每次降一半patience10表示验证损失 10 个 epoch 不降才触发。这个调度器要和早停配合早停负责停调度器负责在停之前再抢救一下。第三个技巧是集成。训练 3 到 5 个不同随机种子的网络预测结果取平均。单个网络的方差会被平均掉MAE 通常能降 5% 到 10%。代价是训练时间翻倍但在房价这种样本量不大的场景里完全可接受。技巧预期收益代价特征交叉R² 提升 0.02 到 0.05需要领域知识构造学习率调度训练更稳后期不震荡多一个超参数多模型集成MAE 降 5% 到 10%训练时间成倍增加最后说一个验证方法不要只看一次划分的测试集结果。用 K 折交叉验证把数据分成 5 份轮流做测试集看 R² 的均值和标准差。如果标准差很大说明模型对数据划分敏感这时候集成和早停就更重要。我自己做房价预测时最大的教训是太早去调网络结构忽略了数据本身。后来发现把缺失值处理干净、把异常值单独分析、把类别编码做对比换激活函数、加层数有用得多。现在我的习惯是先把数据管线和评估指标搭好再动网络。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

UE5风格化体积云实战:密度场、Beer-Lambert与云隙光柱一体化实现

UE5风格化体积云实战:密度场、Beer-Lambert与云隙光柱一体化实现

做风格化体积云,最怕的不是数学公式多,而是把写实那套物理参数全数堆上去之后,云既不风格化,运行还卡到没法看。这套链路我在 UE 5.7.4 工程里从密度场、Beer–Lambert 透射一直做到实时雾与云隙光柱,核心目标很简单&a…

2026/10/14 11:40:49 阅读更多 →
SpringBoot+Vue高校疫情防控管理系统毕设项目完整设计与实现

SpringBoot+Vue高校疫情防控管理系统毕设项目完整设计与实现

1. 项目定位:这套系统到底解决什么问题总有人拿着“SpringBootVue 高校疫情防控web系统管理平台源码【适合毕设/课设/学习】JavaMySQL”这个标题来问我,它到底能不能直接拿来当毕业设计、能不能跑通、要不要改代码。先说我的结论:这套系统选型…

2026/10/14 11:39:48 阅读更多 →
硬件选型笔记:国产 PCIe Gen2.1 交换芯片 IX6012@ACP,紧凑型工控与小型边缘采集 IO 扩展评估

硬件选型笔记:国产 PCIe Gen2.1 交换芯片 IX6012@ACP,紧凑型工控与小型边缘采集 IO 扩展评估

前言最近行业内 PCIe 相关讨论大多集中在 Gen4/Gen5 的高端 AI 服务器方案。但在工控、嵌入式采集、小型边缘终端项目里,很多硬件工程师遇到的痛点并不是带宽不够,而是主控原生 PCIe 通道数量有限,同时板卡空间紧张、整机功耗需要严格控制。这…

2026/10/14 11:39:48 阅读更多 →

最新新闻

AI学术速递系统搭建:从信息过载到精准筛选的工程实践

AI学术速递系统搭建:从信息过载到精准筛选的工程实践

1. 从“学术速递”这个动作说起:为什么信息筛选比信息获取更难每天早上刷一遍学术平台的新论文列表,这件事我坚持了快三年。最开始是手动刷,后来用订阅工具,再后来自己写脚本抓取。折腾一圈下来发现,真正的痛点从来不是…

2026/10/14 12:38:45 阅读更多 →
Cocos Creator 3.8.8安卓APK打包全流程指南

Cocos Creator 3.8.8安卓APK打包全流程指南

1. 项目概述作为一名使用Cocos Creator开发手游的独立开发者,我最近刚完成从3.7版本到3.8.8的升级,并完整走通了新版环境下的APK打包流程。相比之前版本,3.8.8在Android平台构建方面有几个值得注意的改动点,特别是对NDK版本和Grad…

2026/10/14 12:38:45 阅读更多 →
本科生AI工具筛选指南:学术合规与高效组合

本科生AI工具筛选指南:学术合规与高效组合

1. 项目概述:本科生如何高效筛选AI工具 作为一名在高校实验室摸爬滚打多年的老学长,我见过太多本科生在AI工具选择上踩坑的案例。去年指导毕业设计时,有位学弟用了某款号称"一键生成论文"的工具,结果查重率直接飙到78%。…

2026/10/14 12:38:45 阅读更多 →
原生Servlet+MySQL打造财务系统:事务、分页与精度避坑实录

原生Servlet+MySQL打造财务系统:事务、分页与精度避坑实录

简介:一套面向Java EE课程设计、毕业设计及中小企业财务信息化初学者的完整项目资料包,围绕原生Servlet与MySQL技术栈,呈现企业财务管理系统从设计、开发到部署的全过程。资源共14个文件,压缩包约117.82MB,包含项目源码…

2026/10/14 12:38:45 阅读更多 →
Yozbon:用经济建模重构多智能体自治系统

Yozbon:用经济建模重构多智能体自治系统

1. 为什么“把AI智能体当经济主体”不是修辞,而是系统设计的底层转向“Yozbon”这个名字乍听像某个小众编程语言或加密项目代号,但当你看到它的副标题——“把 AI 智能体建模为‘经济主体’的开源多智能体自治系统”,第一反应很可能是&#x…

2026/10/14 12:38:45 阅读更多 →
无线电能传输SLSPC拓扑的Simulink建模与优化

无线电能传输SLSPC拓扑的Simulink建模与优化

1. 项目背景与核心价值无线电能传输(WPT)技术正在彻底改变传统供电模式,特别是在电动汽车、医疗植入设备、消费电子等领域展现出巨大潜力。这篇论文复现工作聚焦于SLSPC(Series-Loaded Series-Parallel Compensated)拓…

2026/10/14 12:37:44 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →