上海房价SPSS多元线性回归:数据清洗、共线性诊断与可复现流程
简介这是一份面向经济学、统计学专业学生及房地产研究初学者的SPSS实证分析资料以上海1999至2007年经济数据为样本围绕商品房平均售价、城镇人均可支配收入、城市人口密度与房地产开发投资额构建多元线性回归模型。内容涵盖模型设定、拟合度检验、方差分析F检验、变量显著性t检验并针对自变量间多重共线性问题通过相关系数矩阵诊断后改用逐步回归加以修正同时讨论房地产市场调控与发展规律等现实意义适合作为课程作业、论文写作或软件操作的参考范例。资源为单个PDF文档压缩包约88KB篇幅紧凑可直接查阅数据表格、回归结果与结论推导。目前已有2919人学习下载可帮助读者理清建模思路、掌握结果解读与共线性处理方法。1. 上海房价做多元线性回归为什么很多人最后卡在 SPSS 这一步网上流传的分析材料标题常常写成「上海房价影响因素 SPSS 多元线性回归分析 PDF」翻开来是一串截图相关系数矩阵、模型摘要、ANOVA 表、系数表末尾跟一句「面积和到地铁距离对单价影响显著」。真到自己动手把挂牌数据丢进 SPSS 点几下调整 R 方只有 0.29房龄的系数居然是正的VIF 一列里十几个变量全部超过 10。这时候大多数人的反应是回去改模型其实问题出在前面的口径和变量设定上。多元线性回归在 SPSS 里只有三四个对话框真正花时间的是样本怎么筛、变量怎么派生、输出里哪一列该信哪一列不该信。这篇文章按一条能复现的路径走先把挂牌数据整理成干净宽表做相关性分析摸清变量关系再进回归对话框逐项解读三张核心表最后处理共线性、异方差和异常值把结果固化成可重复运行的语法文件。每一段都给能直接抄的语法或代码也说明每个参数改动之后输出会怎么变。适合三类人会用 Excel 但对统计输出半懂的从业者需要交课程报告或论文的学生以及要给业务方解释「这个板块单价为什么是这个数」的房产数据岗。不需要先啃完计量经济学但得知道回归的假设条件被破坏时系数表会以什么方式骗人。2. 建模前的数据准备把上海二手房挂牌数据整理成 SPSS 能读的宽表回归跑不出好结果八成是数据阶段就埋了雷。挂牌数据的特点是字段脏、口径杂、异常值多同一个小区有人按建筑面积报有人按套内面积报地铁距离有的是直线距离、有的是步行距离还有明显把总价小数点写错一位的记录。这些如果不在导入 SPSS 之前处理掉后面所有诊断都是在给脏数据做体检。2.1 先定被解释变量总价还是单价最容易被忽略的一步是选因变量。如果拿总价做因变量同时把建筑面积放进自变量模型几乎是必然的面积系数接近该小区的平均单价调整 R 方轻松到 0.8但这只是同义反复没有任何解释力。常见做法是改用单价万元/㎡做被解释变量把面积降级为一个普通自变量或者对总价取对数用对数模型处理「大户型单位面积溢价递减」这种非线性关系。两种都能用区别在于解释方式单价模型的系数直接是「每增加一单位 X单价变动多少万元/㎡」对数模型要先取指数还原成百分比弹性。变量定义建议先列成一张表避免后面在 SPSS 里反复确认字段含义。变量名含义SPSS 测量尺度单位/取值unit_price挂牌单价标度万元/㎡area建筑面积标度㎡age房龄标度年metro_dist到最近地铁站距离标度kmrooms卧室数标度间floor_ratio楼层占比标度0~1elevator是否电梯房名义0否1是renov装修等级有序1 简装2 精装3 豪装ring环线位置名义1 内环2 中环3 外环4 郊环days挂牌天数标度天楼层不要用绝对楼层数。同一栋楼里 6 层在不同总层数下的含义完全不同用「所在楼层 / 总楼层」得到的占比更稳定也避免把 30 层塔楼的低区和中区混为一谈。2.2 清洗与派生单价异常值、房龄换算、距离口径清洗环节我一般放在 Python 里做SPSS 做数据变换的语法虽然也能写但批量处理脏字段还是 Pandas 顺手处理完导出 Excel 再进 SPSS。import pandas as pd # 读取挂牌明细只保留住宅用途的记录 df pd.read_excel(sh_listings.xlsx, sheet_nameraw) df df[df[用途] 住宅].copy() df df.drop_duplicates(subset[房源编号]) # 派生建模要用的核心变量 df[unit_price] df[总价_万元] / df[建筑面积] df[age] df[挂牌年份] - df[建成年份] df[metro_dist] df[地铁距离_米] / 1000 # 统一口径为公里 df[floor_ratio] df[所在楼层] / df[总楼层] df[elevator] (df[电梯] 有).astype(int) # 单价上下 1% 截尾防止录入错误把回归线整体带偏 lo, hi df[unit_price].quantile([0.01, 0.99]) df[unit_price] df[unit_price].clip(lo, hi) # 缺失处理连续变量用中位数填补分类变量单独留一档 for col in [age, metro_dist, floor_ratio]: df[col] df[col].fillna(df[col].median()) df.to_excel(sh_model.xlsx, indexFalse)这段代码里几个参数值得说明。quantile([0.01, 0.99])是上下 1% 的截尾阈值样本量在几千条时比较稳如果数据只有几百条改成 0.05 和 0.95 更保险否则会把真实的高价房源一起剪掉。clip只压缩极端值不删除样本保留记录数对后续自由度校验很重要。连续变量用中位数填补而不是均值是因为挂牌数据的房龄和地铁距离都是右偏分布均值受极端值拉高。地铁距离务必全表统一成一种口径直线距离和步行距离混用会让系数失去意义这一点在逻辑上比统计方法更关键。2.3 导入 SPSS 并核对变量视图的测量尺度在 SPSS 里走「文件 → 导入数据 → Excel」勾选「从第一行数据读取变量名称」。导入完成后不要直接点分析先切到变量视图逐个检查「测量」列0/1 的变量如 elevator设为「名义」否则 SPSS 会按连续变量处理系数解释成「从 0 变到 1 单价变动多少」虽然结果一样但输出里的行标签不直观。renov、ring 这类有序分类如果当作标度系数就直接是线性的需要确认这个线性假设成立不成立时改用回归对话框里的「分类」按钮生成哑变量更稳妥。因变量 unit_price 必须是「标度」如果是名义 SPSS 会拒绝计算。提示SPSS 在回归中遇到分类自变量时只有被放进「分类协变量」列表框才会自动生成哑变量直接拖进「自变量」框会当作数值强行线性拟合这是系数符号反号最常见的来源之一。2.4 用分拆文件先看分组描述统计正式回归之前先按环线或区域分组看一遍描述统计能提前发现「内环和外环的价格形成机制完全不同」这类问题。SPSS 的分拆文件功能就是干这个的语法如下。SORT CASES BY ring. SPLIT FILE LAYERED BY ring. DESCRIPTIVES VARIABLESunit_price area age metro_dist /STATISTICSMEAN STDDEV MIN MAX. SPLIT FILE OFF.SPLIT FILE LAYERED BY ring之后的每一个统计过程都会按 ring 分组分别输出SPLIT FILE OFF用来关掉分组。这个开关是 spss 数据分拆文件最容易踩的坑关掉之前跑回归系数表会按环线输出四份看起来像模型爆炸其实是分组在起作用。分类变量分组前必须先SORT CASES BY否则 SPSS 会提示未排序并按遇到顺序切分。分组描述统计能给出两个有用信号一是各组的单价标准差差异很大外环的离散度通常更高提示后面要检查异方差二是某些组里 metro_dist 的均值几乎没有变化说明这个变量在该组内缺乏信息全样本回归时它的系数可能主要由某一组驱动。3. SPSS 多元线性回归全流程从相关性分析到系数表逐项解读数据准备好之后剩下的就是顺序问题。很多人上来直接点「分析 → 回归 → 线性」跑完发现 R 方低又回头猜哪个变量不该放。正确的顺序是先做相关性分析摸清变量两两关系再决定进回归的变量和函数形式。3.1 先做 SPSS 相关性分析判断该不该直接进回归相关性分析能暴露三类问题自变量之间高度相关共线性前兆、自变量与因变量关系非线性、以及变量与因变量根本不相关。命令很短CORRELATIONS /VARIABLESunit_price area age metro_dist rooms days /PRINTTWOTAIL NOSIG /MISSINGPAIRWISE./VARIABLES里第一个变量会放在矩阵首行建议放因变量方便看。/MISSINGPAIRWISE表示成对剔除缺失比整列剔除保留更多样本但样本量会随变量对不同而变化做正式报告时通常改用LISTWISE保持一致。NOSIG是关掉显著性标记样本量大时几乎什么都显著标记反而干扰视线。观察到的情况含义处理方向两个自变量 |r| 0.8严重共线风险只留一个或合成一个指标自变量与因变量 |r| 0.1线性关系弱考虑非线性形式或剔除自变量与因变量 r 为负但业务上应为正口径错误或混杂先查量纲和样本范围相关系数大但回归系数不显著典型共线性表现查 VIF房龄和单价的关系往往不是线性的次新房价格高老公房因为总价低、配套成熟反而单价不低中间年份最低。这种倒 U 形在相关系数上看不出来r 可能接近 0但回归里加一个age_sq age ** 2就能捕捉。相关系数接近 0 不等于该变量没用这是 spss 相关性分析最需要留心的边界。3.2 回归对话框的四个必调设置在 SPSS 里走「分析 → 回归 → 线性」主对话框把 unit_price 放因变量其余放自变量。真正影响输出的是右边四个按钮逐项说明。统计量按钮勾选「估计值」「置信区间」「模型拟合度」「共线性诊断」「Durbin-Watson」「个案诊断」。共线性诊断不勾系数表里就不会出现 VIF 和容差列后面想排查只能重跑。绘制按钮把 ZRESID 放 Y、ZPRED 放 X并勾选「直方图」和「正态概率图」。残差图是判断异方差和函数形式错误的唯一直接手段。保存按钮勾选「未标准化预测值」「未标准化残差」「标准化残差」。保存下来的变量可以直接参与后续分段误差统计。选项按钮进入法用默认的 PIN 0.05、POUT 0.10如果改用步进法这两个值决定变量进出门槛样本量大时把 PIN 收紧到 0.01 可以少留噪声变量。对应语法如下可以直接粘进语法编辑器。REGRESSION /DESCRIPTIVES MEAN STDDEV CORR SIG N /MISSING LISTWISE /STATISTICS COEFF OUTS CI(95) R ANOVA COLLIN TOL /CRITERIAPIN(.05) POUT(.10) /NOORIGIN /DEPENDENT unit_price /METHODENTER area age metro_dist rooms elevator./METHODENTER是全部强制进入适合理论驱动的研究想让它自动挑变量改成/METHODSTEPWISE但步进法选出的模型系数偏乐观报告里要注明。/STATISTICS里的COLLIN TOL就是共线性诊断CI(95)输出系数的 95% 置信区间写结论时比只看 p 值更有说服力。3.3 三张核心表怎么读模型摘要、ANOVA、系数输出窗口里表很多真正决定结论的只有三张。输出指标所在表判读经验R 方 / 调整 R 方模型摘要两者差距大说明变量相对样本偏多优先信调整 R 方标准估计误差模型摘要与因变量均值相除可粗略理解预测的相对误差Durbin-Watson模型摘要横截面数据接近 2 即可明显偏离先检查数据排序F 与显著性ANOVA显著性小于 0.05 说明整体模型成立不代表每个变量都显著未标准化系数 B系数写业务解释用这一列自带单位标准化系数 Beta系数量纲不同时比较变量相对重要程度t 与显著性系数单变量显著性受共线性影响会失真VIF / 容差系数VIF 大于 10、容差小于 0.1 视为严重共线ANOVA 表显著但单个系数都不显著是共线性的经典信号整体能解释但说不清是谁在解释。3.4 系数的量纲与实际解释别把「0.03」直接念出来未标准化系数 B 自带单位解释时必须带上前提「其他变量保持不变」。假设 metro_dist 的 B 是 -0.42意思是到地铁站距离每增加 1 公里单价平均下降 0.42 万元/㎡elevator 的 B 是 0.35意思是电梯房比非电梯房平均贵 0.35 万元/㎡这两个数字直接可以拿去做业务沟通。分类变量的系数是相对基准组而言的。SPSS 默认把最后一类作为参照所以 ring1内环的系数如果没出现在表里说明它以参照组身份被吸收了其他环线的系数都要读成「相对于内环」。想让参照组变成内环在「分类」按钮里把对比方式改成「指示符」并指定第一类为参照。对数模型要换一种读法。如果因变量换成LN(unit_price)系数 0.08 表示自变量增加 1 单位单价上涨约 8%这是近似值精确值要算exp(0.08) - 1。这种弹性解释在跨板块比较时比绝对金额更合适因为内环和远郊的单价基数差了好几倍。4. 模型不达标怎么办共线性、异方差与异常值的排查修正第一轮回归跑完调整 R 方通常不会太难看的但诊断指标一般都有问题。这一章按「最常见的三类故障 一类结构性问题」来排。4.1 VIF 超标时的三条处理路径系数表里 VIF 一列只要出现两位数就不能直接写结论。三条路径各有代价选哪条取决于研究目的是解释还是预测。处理路径具体操作优点代价删除变量移除 VIF 最高的那个自变量最快模型干净可能丢掉理论上的控制变量产生遗漏变量偏误变量合并面积与卧室数合成套均面积距离与环线合成通达性得分保留信息系数更稳新指标的经济含义要重新解释降维与正则主成分回归、岭回归共线性彻底缓解系数不再对应单一变量业务方难读懂实操顺序建议先合并再考虑删除最后才上降维。因为合并是在保留信息的前提下解决问题而降维会让「面积每多 1 ㎡ 单价涨多少」这种具体结论消失。判断是否需要上岭回归可以看删除变量后 VIF 是否降到 5 以下降不下去说明多个变量同时纠缠合并也救不了。4.2 残差图与异方差从散点形状判断把 3.2 节保存的 ZPRED 和 ZRESID 画出来横轴预测值、纵轴残差。健康的图形是一团无形状的云点在 0 线两侧均匀分布。出现喇叭形预测值大时残差也大就是异方差出现弯曲的弧形说明函数形式不对房龄该加平方项了。COMPUTE ln_price LN(unit_price). EXECUTE. GRAPH /SCATTERPLOT(ZPRED WITH ZRESID) /MISSINGLISTWISE.LN()是自然对数SPSS 里还有LG10()是常用对数两者只差一个常数因子系数解释都以自然对数为基础。取对数之后残差图仍然呈喇叭形说明异方差来自自变量而非因变量的尺度过大这时候可以考虑对 metro_dist 也取对数或者改用加权最小二乘。SPSS 原生对异方差稳健标准误的支持有限实际项目里更常见的做法是用 Python 复算一遍对比系数的标准误是否被低估。4.3 异常值与强影响点个案诊断加箱线图3.2 勾了「个案诊断」之后输出里会多一张表列出标准化残差绝对值超过 3 的个案号。这张表要配合「保存」里的标准化残差一起看另外两个指标更值得关注Cook 距离大于 1 的记录是同时影响多个系数的高影响力点删掉它模型会明显变化。杠杆值大于2p/np 是自变量个数n 是样本量的记录说明它在这个自变量组合上离群常见于极端大户型或超高价房源。处理方式不是一律删除。先回到原始数据看这条记录是否录入错误如果价格属实例如某个顶级豪宅可以保留但做一次敏感性分析——删掉后重跑回归比较系数变化幅度在报告里说明。直接删除会让样本产生选择性偏误样本量本来就几千条的时候损失更明显。4.4 区域虚拟变量爆表时先用 SPSS 聚类分析把板块归并上海按板块细分能拆出上百个分类全做成哑变量会吃掉大量自由度而且很多小板块只有几十条挂牌记录系数极不稳定。这时候先用聚类把板块归并成几类再作为名义变量进回归是更常见的做法。算法选 K 均值聚类变量用板块层面的指标而不是房源层面的否则聚出来的是房源分群。QUICK CLUSTER avg_price vol metro_density med_age /MISSINGLISTWISE /CRITERIACLUSTER(4) MXITER(50) /METHODKMEANS(NOUPDATE) /SAVE CLUSTER /PRINT IDENTITY ANOVA./CRITERIACLUSTER(4)指定聚成 4 类这个数字不要拍脑袋先用 3、4、5、6 各跑一次看 ANOVA 表里各聚类变量的显著性是否都成立再看每一类能不能起个业务名字。/SAVE CLUSTER会把类别号写回数据文件新变量名通常叫 QCL_1之后在回归里把它当分类自变量用。/METHODKMEANS(NOUPDATE)表示不做迭代更新速度快但结果依赖初始中心数据量不大时改成默认的迭代法结果更稳。聚成 4 类之后通常能自然对应核心区、中心城区、近郊、远郊每一类内部的价格机制相对一致。这个分类变量进回归后系数之间仍然可能存在组内异质性但它比上百个哑变量实用得多。5. 让分析可复现把回归结果变成预测与一页结论的技巧5.1 用语法文件固化整条流水线SPSS 界面点出来的每一步操作都能通过「粘贴」按钮变成语法。把所有步骤粘进一个 .sps 文件从导入、分拆、相关、回归到保存预测值全部串起来下次换一批数据只需要改开头的数据路径。这一步在项目里的价值远超预期三个月后有人质疑「当时那个 VIF 是怎么算的」把语法文件跑一遍就能原样复现不需要回忆当时勾了哪个框。写语法文件时注意两点。一是所有SPLIT FILE都要有对应的SPLIT FILE OFF否则后面整段输出都被分组二是COMPUTE生成新变量后紧跟EXECUTE否则后续过程读到的是旧数据。这两条是语法化过程中最常出问题的地方。5.2 保存预测值与残差做误差体检表勾选「保存预测值」后数据文件里会多出 PRE_1未标准化预测值和 ZRE_1标准化残差。用它们做一张分段误差表可以看清模型在哪些价位上不准。COMPUTE abs_err ABS(unit_price - PRE_1). COMPUTE rel_err abs_err / unit_price. EXECUTE. DESCRIPTIVES VARIABLESabs_err rel_err /STATISTICSMEAN.ABS()取绝对值rel_err是相对误差。整体平均绝对误差MAE看着不错往往是因为大量中低价房源拉低了均值高单价段可能误差很大。把预测值按分位数分成四段每段单独算一次 MAE 和平均相对误差MAPE表格结构如下数值由输出填入。单价分段样本数MAE万元/㎡MAPE低段0~25 分位中低段25~50 分位中高段50~75 分位高段75~100 分位如果高段的 MAPE 明显高于其他段说明模型对高端房源的解释不足通常是因为高端房源的价格更多由景观、学区、品牌物业等未纳入变量决定这时候在报告里如实说明比硬调模型更负责。5.3 用 Python 交叉复核系数最后一步是复核。同一个线性模型用最小二乘从另一个工具算一遍能发现 SPSS 操作中的疏漏。import numpy as np import pandas as pd d pd.read_excel(sh_model.xlsx) cols [area, age, metro_dist, rooms, elevator] # 手动构造设计矩阵第一列全是 1对应截距项 X np.column_stack([np.ones(len(d)), d[cols].to_numpy(dtypefloat)]) y d[unit_price].to_numpy(dtypefloat) beta, *_ np.linalg.lstsq(X, y, rcondNone) resid y - X beta sst float((y - y.mean()) (y - y.mean())) r2 1 - float(resid resid) / sst print(dict(zip([截距] cols, np.round(beta, 4)))) print(R2 , round(r2, 4))np.column_stack前面加一列 1 是为了让截距项参与拟合漏掉这一步算出来的系数会全部偏移。np.linalg.lstsq用的是奇异值分解比直接求(XX)^-1 Xy数值稳定得多自变量高度相关时也不会报错。如果复算的系数和 SPSS 系数表在小数点后三位内一致说明两边的样本口径相同差得多按顺序查三处SPSS 里缺失值是成对剔除还是整列剔除、分拆文件是否忘记关闭、截尾处理是否在导出后又执行了一遍。系数一致但 R 方对不上通常是 Python 侧没做截距或数据里混进了 SPSS 填补过的记录。本文还有配套的精品资源点击获取