说句实话房价预测这个题目已经被各路教程写烂了。但正因为写烂了它反而是学回归最好的切入点数据干净、目标清晰、结果能用常识验证。今天我想聊聊我用“多元线性回归”算法预测房价的完整过程并且故意选了两种完全不同的工具链来做对比一是几乎人人都装过的Excel二是数据分析标配的Jupyter Notebook配合scikit-learn。两条路走完你不仅能理解回归的底层原理还能在实际工作中判断什么时候用Excel足够什么时候必须上Python。这个项目能解决什么问题说直白点就是给你一堆房子的特征数据面积、房龄、卧室数量、周边配套……让你估算出一套房子大概值多少钱。它非常适合刚入门机器学习、想搞清楚“回归到底在算什么”的人也适合业务侧的同学——你不想写代码完全可以用Excel先跑一遍看看线性回归的输入输出长什么样。这篇文章会把我实际操作中的步骤、代码、参数设置全部摊开包括我踩过的坑尽量让不同基础的读者都能直接照着做。1. 先想明白多元线性回归在这个项目里到底解决什么问题1.1 从一元到多元房价预测为什么不能只看一个因素线性回归的入门版本通常是一元的也就是只有一个自变量比如“面积越大房价越高”。但真实世界的房价显然不是单一因素决定的同一套房面积大但临街噪声大价格可能不如面积小但安静的房子房龄新但地段差和房龄老但靠近学校结果也很难说。多元线性回归干的事情就是把这些因素全部塞进一个公式房价 w1×面积 w2×房龄 w3×卧室数 w4×距市中心距离 b这里的w1到w4叫做“回归系数”b是截距。模型训练的本质就是根据历史数据去找一组系数让预测出来的房价和真实房价之间的误差尽可能小。你可以把它理解为“调音量旋钮”每个特征有一个旋钮模型训练就是在自动转这些旋钮让最终输出的综合得分最贴近真实答案。1.2 为什么我坚持用Excel和sklearn两条线并行我见过不少初学者一上来就抱着Jupyter写代码跑通了却不知道每一步在干嘛。反过来也有业务同事只会用Excel做线性趋势线遇到多因素就抓瞎。所以我这个项目刻意让两条线并行Excel负责“眼见为实”回归分析工具包输出的决定系数R方、P值、系数表能让你直观看到每个特征对房价的影响程度而且不用写一行代码。sklearn负责“规模化落地”数据一多、特征一多Excel会明显卡顿且难以复现Python能解决。这两条线用的其实是同一套数学原理只是操作路径不同。先把Excel跑通再上手sklearn你对“回归系数”“误差评估”这些概念的体感会特别深因为你在两个工具里看到了完全一致的数字逻辑。1.3 核心思路拆解先业务理解再数据建模整个项目的流程我拆成了五步这五步在Excel和Python里都存在只是实现方式不同确定目标变量也就是你要预测的东西这里是房价。整理特征变量从业务角度和历史经验里挑出可能影响房价的因素。数据预处理清洗缺失值、处理异常值、确认数据类型。训练模型用历史数据拟合出系数。评估与解释看预测误差有多大系数符号是否符合直觉。这套流程就是所谓“数据驱动决策”的最小闭环。很多教程跳过了第1步和第2步直接导入自带数据集跑代码导致读者根本不清楚自己为什么要选这些特征。我建议你先从业务常识出发列特征再用数据去验证顺序别反了。2. 用Excel做房价预测不写一行代码也能跑回归2.1 准备数据先搭一个干净的数据表Excel路径我用了一个模拟的二十条房屋记录来做演示包括四类特征和最终房价。结构很简单每一行是一套房子每一列是一个属性指标。面积平方米房龄年卧室数间距市中心公里房价万元85528.5245110835.2378961223.83321323410.14107815212.6205这里要提醒一句特征列之间最好不要有缺失值否则Excel回归工具会直接报错或忽略整行。我建议你先用“筛选”功能检查一下有没有明显异常比如面积为0、房价为负这些脏数据先删掉或修正再进入回归流程。2.2 调出“数据分析工具库”很多人卡在第一步Excel本身不自带回归功能需要先加载“分析工具库”。具体操作是文件 → 选项 → 加载项 → 转到 → 勾选“分析工具库” → 确定。加载之后“数据”选项卡右侧会出现一个“数据分析”按钮点进去就能看到“回归”这一项。这一步我见过太多人卡住因为不同版本的Excel菜单位置略有差异尤其Mac版和Windows版路径不一样。如果你找不到“加载项”直接按快捷键AltF11打开VBA窗口再关掉有时候能强制刷新菜单这个土办法我实测有效。回归对话框里的设置非常直观Y值输入区域选房价那一列的数据区域。X值输入区域选四个特征列的数据区域。勾选“标志”表示第一行是列名千万别漏。置信度默认95%即可。然后点击确定Excel会在新工作表里生成一份回归分析报告。2.3 读懂Excel回归报告R方、P值和系数的坑这份报告看起来密密麻麻但核心只有三块第一块是“回归统计”里的R Square也就是决定系数R方表示模型能解释房价变异的百分比。0到1之间越接近1说明拟合越好。我这份模拟数据跑出来大概是0.89意思是面积、房龄这些因素能解释房价约89%的波动剩下11%是模型没抓住的因素。第二块是方差分析表里的“显著性F”相当于整体模型的P值。这个值如果小于0.05说明模型整体是有意义的至少有一个特征对房价有显著影响。第三块是下方的“系数”列。每个特征对应一个回归系数Excel会自动给出标准误差、t统计量、P-value。比如面积系数如果是2.1意味着保持其他条件不变时面积每增加1平方米房价平均上涨2.1万元。这里的P-value很重要它衡量这个特征的可靠性一般小于0.05就认为统计显著。这里有个很容易踩的坑如果你手动对比Excel和sklearn的结果可能会发现系数值不一样。原因多半是自变量量纲不同比如面积是几十到上百距市中心是几到十几回归系数会受到量纲影响但不改变因素的方向和显著性。这一点在后续对比Python结果时我会专门再说。2.4 Excel回归方法的局限什么时候必须换工具用Excel做一次简单回归确实很快但它有几个硬伤第一数据量大时极卡。我试过几千行、十几个特征Excel回归分析有时要等几十秒而且结果页无法自动刷新——你改了源数据报告不会跟着更新只能重新跑一遍。第二难以批量实验。如果你想比较“用5个特征”和“用8个特征”的模型效果Excel每次都要手动调整X区域并重跑繁琐且容易选错列。第三缺乏数据分割能力。Excel回归默认用全部数据来训练做完之后很难再拿一批新数据来验证模型的泛化能力而这恰恰是机器学习流程的核心环节。所以Excel适合快速验证思路、和不懂代码的同事沟通、或者教学演示一旦你要做特征筛选、模型调参、批量预测还是得换Python。下面进入正题。3. Jupytersklearn从数据清洗到模型评估的完整流程3.1 环境准备与数据集选择我在Jupyter里的首选不是波士顿房价数据集而是加州房价数据集。因为波士顿房价数据集已经被scikit-learn标记为“有伦理问题”并在新版本中移除了新手如果照旧教程跑会直接报错。加州房价数据集同样是回归问题的经典选择包含八个特征和一个目标值结构干净适合教学。环境方面我建议用Anaconda安装Python 3.9以上版本Jupyter会自动集成。核心依赖就三个pandas、numpy、scikit-learn。如果你不想装Anaconda也可以直接用pip安装pip install pandas numpy scikit-learn jupyter版本的坑我提醒一下scikit-learn 1.2以上的版本接口有些变化比如某些数据集返回的是Bunch对象而不是DataFrame后面代码我会兼容处理。3.2 加载数据并做探索性分析先在Jupyter里创建一个新的Notebook按下面的代码加载数据import pandas as pd from sklearn.datasets import fetch_california_housing housing fetch_california_housing(as_frameTrue) df housing.frame print(df.head())fetch_california_housing返回的对象包含data和target两个部分as_frameTrue直接转换成pandas的DataFrame方便后续操作。我第一次跑的时候忘记加这个参数结果拿到的是一个纯数组根本不知道每列叫什么处理起来很被动。然后看整体信息df.info() print(df.describe())df.info()会告诉你每列是否有缺失值、数据类型是什么。df.describe()则给出每列的平均数、标准差、最小值、最大值、四分位数这些描述性统计能帮你快速发现异常值。比如AveOccup这一列正常家庭平均入住人数也就3到5但如果最大值是几百说明数据里混入了异常点后面要么删要么做处理。再画一个相关性矩阵直观判断哪些特征和房价关系大import matplotlib.pyplot as plt import seaborn as sns corr df.corr(numeric_onlyTrue) plt.figure(figsize(10, 8)) sns.heatmap(corr, annotTrue, cmapcoolwarm, fmt.2f) plt.show()你可能注意到我引入了seaborn这是pandas生态里画图最顺手的库。相关性矩阵中MedInc该街区收入中位数和房价的相关系数通常在0.68左右是所有特征中相关度最高的这符合现实逻辑收入高的区域房价普遍更高。这一步探索性分析的价值在于你还没建模就已经能预判哪个特征重要。3.3 划分训练集和测试集先别急着训练建模之前我习惯先把数据分出一部分作为“考试卷”模型训练时绝对不碰它最后才用这部分数据检验模型表现。这就是训练集测试集划分的意义如果不用新数据验证模型只是在“背答案”没法证明它有预测能力。from sklearn.model_selection import train_test_split X df.drop(MedHouseVal, axis1) y df[MedHouseVal] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 )test_size0.2表示取20%的数据作为测试集。random_state42在这里非常重要这个参数固定了随机数生成器保证每次运行划分结果一致。如果你不设这个值每次运行拿到的训练集都会不同模型的分数会上下浮动让人误以为模型不稳定。特征标准化和训练集划分的顺序也容易出错要先划分再标准化。如果先标准化全量数据再划分测试集的信息会提前泄露给训练过程得出的分数会虚高。3.4 特征标准化为什么要把数据拉到同一个量级加州房价数据的特征量级差异极大MedInc是几到十几Latitude是30到40AveRooms是4到8左右但如果换成其他项目有的特征是0到1有的却是几千。这种情况下回归系数会变得极难解释而且模型训练时数值计算不够稳定。解决办法是标准化让每个特征的平均值变成0标准差变成1。sklearn提供了现成的APIfrom sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)注意fit_transform和transform的区别训练集要用fit_transform它会计算均值、标准差并做变换测试集只能用transform直接用训练集算好的均值、标准差来变换绝不能用测试集自己fit否则就有数据泄漏的风险。标准化之后还有一个额外的好处你可以直接比较系数绝对值的大小来粗略判断特征重要程度。未经标准化的系数受量纲影响面积系数可能是几百距市中心系数可能是负十几没法直接比。标准化之后赔率就公平了。3.5 训练模型与核心评估指标R方、MAE、RMSEsklearn的线性回归模型使用起来非常简单但我还是建议把评估指标的代码一起写好因为只看R方会漏掉很多信息。from sklearn.linear_model import LinearRegression from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error model LinearRegression() model.fit(X_train_scaled, y_train) y_pred model.predict(X_test_scaled) r2 r2_score(y_test, y_pred) mae mean_absolute_error(y_test, y_pred) rmse mean_squared_error(y_test, y_pred, squaredFalse) print(fR2: {r2:.4f}) print(fMAE: {mae:.4f}) print(fRMSE: {rmse:.4f})R方才是我最终报告里的核心指标它衡量模型整体解释力。RMSE是均方根误差反映预测值和真实值之间的总体偏差规模。MAE是平均绝对误差更直观比如房价的中位数是2到3单位是十万美元MAE如果是0.5说明平均预测误差约为5万美元。RMSE对离群点更敏感如果RMSE明显大于MAE说明存在一些预测得特别离谱的样本。如果你用的是较新版本的scikit-learnmean_squared_error里已经没有squared参数了需要用root_mean_squared_error这个独立函数否则会报参数错误。这点我更新文章时才发现的坑新手很容易被旧教程坑到。第一次跑通之后你会发现这五个指标和Excel里的R方本质是一样的数学原理完全相通。从Excel到Python你并没有进入一个完全陌生的世界只是换了一套更趁手的工具箱。3.6 用模型预测一套新房子看系数也看直觉训练结束后我们可以把模型保存下来用于预测新的房屋价格。假设现在来了一套新房子的特征数据特征数值MedInc收入中位数5.6HouseAge房龄中位数25AveRooms平均房间数5.2AveBedrms平均卧室数1.1Population人口1200AveOccup平均入住人数2.8Latitude纬度34.2Longitude经度-118.5预测代码如下import numpy as np new_house np.array([[5.6, 25.0, 5.2, 1.1, 1200.0, 2.8, 34.2, -118.5]]) new_house_scaled scaler.transform(new_house) predicted_price model.predict(new_house_scaled)[0] print(f预测房价: {predicted_price:.3f}十万美元)这里有个非常关键的细节新样本的标准化必须用之前训练好的scaler.transform绝不能重新fit。因为模型学习的是标准化之后空间里的规律如果新样本用不同的均值方差标准化逻辑就全乱了。再查看训练得到的系数coef_df pd.DataFrame({ 特征: X.columns, 系数: model.coef_ }).sort_values(by系数, keyabs, ascendingFalse) print(coef_df) print(截距:, model.intercept_)输出结果中系数有正有负正系数表示特征值越大房价越高负系数相反。比如MedInc的系数如果是正数说明收入中位数高的区域房价高符合直觉Latitude和Longitude的系数如果明显为正或负说明地理位置对房价有结构化影响。我训练完的模型预测这套新房的价格约为1.8十万美元即18万美元。这个数字在一个房价中位数2到3的范围里属于偏低水平你会本能地觉得是不是漏了什么。这就对了——模型只是学的历史规律的近似真实世界还有大量特征没有进入模型比如学区、交通、周边设施、房屋朝向这些都会造成误差。4. 模型不能只看R方系数解释与诊断4.1 系数含义标准化前后的两种解读方式很多人跑完代码拿到系数就草草收场我觉得这是最可惜的。回归模型的系数是模型“说话”的方式不读懂系数等于白建模。标准化之前系数表示“该特征每增加1个单位房价平均变化多少。”比如未标准化的面积系数如果是2.1就意味着面积增加1平方米房价上涨约2.1万元。标准化之后系数含义变为“该特征每增加1个标准差房价变化多少个标准差”。这时候系数不再受单位影响可以直接比较大小来判断特征相对重要程度。实际报告中我更推荐同时展示两种模型的结果或者至少说明你用的是标准化后的结论。否则业务同事看了原始系数的几百上千会一头雾水但告诉他们“收入水平每提升一个标准差房价上涨0.5个标准差”他们反而能秒懂。4.2 多重共线性为什么有的系数看起来不合理线性回归有一个隐含假设特征之间不能高度相关。但真实房屋数据里面积和卧室数往往强相关收入水平和地理位置也常常相关。当两个特征互相牵扯时回归系数的估计就会变得不稳定甚至出现“面积系数为负”这种违反直觉的结果。所以我建议在建模前先看相关性矩阵然后可以用方差膨胀因子VIF检查。sklearn里没直接提供VIF但statsmodels库可以算from statsmodels.stats.outliers_influence import variance_inflation_factor import statsmodels.api as sm X_vif sm.add_constant(X_train_scaled) vif_data pd.DataFrame() vif_data[特征] X.columns vif_data[VIF] [variance_inflation_factor(X_vif.values, i1) for i in range(X.shape[1])] print(vif_data)VIF大于10通常认为存在严重多重共线性。遇到高VIF的特征我的处理思路是先看业务上哪个特征更核心保留那个舍弃次要的或者用岭回归、Lasso这类带惩罚的模型来稳定系数。房价预测项目里Latitude和Longitude经常VIF很高但业务上又很想要这种时候我会选择保留后面再观察残差是否异常。4.3 残差分析模型论断不能只看分数线R方高不等于模型完美。线性回归还要求残差真实值减预测值的分布没有明显模式。我习惯画一张残差图residuals y_test - y_pred plt.scatter(y_pred, residuals, alpha0.6) plt.axhline(y0, colorred, linestyle--) plt.xlabel(预测房价) plt.ylabel(残差) plt.show()理想情况下残差应该像一团随机分布的点没有漏斗形、弯曲形或者明显规律。如果残差图呈喇叭状也就是预测值越大误差越大说明可能存在异方差性如果残差随预测值呈现曲线关系说明数据中存在非线性特征模型可以考虑加多项式项或者改用树模型。我在这个项目里跑出来的残差图在低房价区间分布较集中高房价区间明显发散这合理——高房价房屋个体差异大模型难以捕捉全部信息。这种情况我不会强行去改模型但会在最终结论里注明“高房价区间的预测置信度较低”。5. 常见问题与踩坑速查表5.1 Excel路径的常见问题Excel回归时报错或者结果不符合预期大多是下面几个原因问题原因对策找不到“数据分析”按钮没有加载分析工具库按前文路径启用加载项回归报告全是#NUM或#REF数据区域有文本值或空值清理数据确保都是数字P值显示为0.0000只是小数位显示问题并非真正为0增加显示小数位数再判断特征列数太多导致结果错乱X区域选择了过多无关列尽量只放业务上明确相关的特征5.2 Python路径的常见问题代码运行过程中的报错我整理成速查表都是实际操作中高频出现的报错信息可能原因解决ValueError: Input contains NaN特征列有缺失值使用df.dropna()或填充均值NameError: name xxx is not defined变量名拼写不一致统一变量名按顺序运行单元格AttributeError: Bunch object has no attribute framefetch_california_housing未加as_frame参数按前文代码补上as_frameTruereshape错误预测单条数据时数组维度不对用np.array([[...]])构造二维数组mean_squared_error不识别squaredsklearn版本升级改用root_mean_squared_error或手动开方5.3 模型效果不理想时的排查顺序如果你的R方很低或者误差很大别急着换算法先按这个顺序查先查数据质量有没有异常值、缺失值、变量类型错误。再查特征选择你是不是把和目标变量无关的噪声特征也放进去了。接着查数据泄漏测试集信息有没有在训练前提前泄漏给模型。最后查模型假设线性关系不成立时可以考虑多项式特征或改用决策树。我在实际做这个项目时一开始没删异常样本里的极端高房价数据R方只有0.55。后来发现有一套房源明显是非住宅用途的异常记录删掉重训后R方直接升到0.75。所以遇到性能差先别怀疑模型多回去看看数据。6. 一点个人心得两个工具教会我的事再分享一个我工作里常用的套路先用Excel做一版最粗的回归把特征的显著性排序传给Python环境做精细调优。这样做的好处是Excel那一版报告可以直接拿去和不懂技术的同事沟通让他们直观看到“哪些因素对房价影响最大”而Python那一版则用于批量预测、交叉验证和后续模型迭代。两套工具不是互斥关系而是互补关系。我踩过不少次坑之后最大的体会是模型领域的名词再高大上也逃不过“拿数据说话”这个朴素道理。多元线性回归虽然没有深度学习那么炫但它解释性强、代码量少、结果稳定到今天依然是很多业务场景的首选基线模型。你把这套流程跑通了后续再去学岭回归、Lasso、决策树会发现所有套路都是相通的。如果你手头正好有一套房屋数据不管是Excel还是Python建议你先按文中的流程完整跑一遍把R方、系数、残差图都看一遍再回头查漏补缺。模型永远只是工具真正值钱的是你能解释清楚“为什么房价会被预测成这个数字”。
阅读完成 · 觉得有帮助?