简介这份文档是一篇聚焦河南省区域经济发展差异的统计分析论文面向经济学、统计学及区域经济相关专业的学生与研究者也适合需要了解省域发展不平衡问题的政策分析人员参考。论文以科技投入、固定资产投资、教育投入、人口素质、城镇化率、外贸与就业等指标为切入点运用主成分分析法综合评估各因素对区域经济差异的影响程度并据此提出优化资源配置、强化科技创新、改善基础设施、提升教育水平、促进城镇化健康发展、扩大对外开放等对策建议兼具理论梳理与实证分析价值。资源包内共1个doc文件约590KB为完整毕业论文排版包含中英文摘要、关键词、正文分析及结论部分便于直接阅读、引用或作为写作范例参考。目前该文档已有108人学习下载适合需要区域经济差异研究思路、主成分分析应用案例或相关论文写作参考的读者。1. 从 68073 元和 20359 元这两个数字说起2013 年河南 18 个省辖市里人均 GDP 最高的那个市是 68073 元最低的周口是 20359 元比值 3.34同一年 GDP 极差已经拉到 47714 元人均 GDP 变异系数 38.90%而 GDP 总量的变异系数高达 67.71%。这份《河南省区域经济发展差异的统计分析》就是围着这组数字展开的拿科技投入、固定资产投资、教育投入、人口素质、城镇化率、外贸、就业这 7 类指标把 18 个地市压成少数几个主成分再算出综合得分排名最后落到缩小差距的对策上。它本质上是一份用 SPSS 16.0 跑出来的区域经济综合评价流程文档适合两类人一类是要照着复现选指标—标准化—降维—打分—解释完整链路的人另一类是手上有一堆地市、分公司或门店指标、需要做降维打分再排序的分析岗。文档里的结论可以商榷但那条链路是可以直接搬走的。2. 指标选取与数据口径主成分分析做废通常输在这一步主成分分析对变量方向和量纲的敏感程度比很多人想象的高。同一套数据把一个逆向指标的正负号搞反第一主成分的经济含义能直接翻转排名从发达在前变成落后在前而软件不会报任何错。2.1 先把指标方向摆正区域经济评价里正向指标越大越好比如科技投入、固定资产投资、教育投入、城镇化率、外贸依存度、就业率。逆向指标越小越好比如城镇登记失业率、单位 GDP 能耗、城乡收入比。这两类混在一起进模型主成分会把失业率高当成发展好。常见做法是逆向指标取倒数而不是简单取负号。取倒数有两个好处一是保持所有变量方向一致二是顺带把量纲压缩到同一个数量级后面做 z-score 时受极端值的影响小一些。只有失业率这种本身在 3%6% 窄区间波动的变量取倒数后波动幅度会被放大得比较夸张这时取负号再标准化反而更稳。提示方向处理必须在标准化之前完成。先 z-score 再取倒数等于对已经改变原点位置的数据做非线性变换结果不可逆也没法解释。2.2 总量指标和人均指标不要同时进模型河南是人口大省2013 年常住人口 9413 万。如果把GDP 总量和人均 GDP一起丢进主成分等于把人口规模计算了两遍。第一主成分会被人口维度主导周口、南阳这类人口大市被整体抬上去济源这类体量小、人均高的市被压下来最后得出的经济水平排名其实是一份人口排名。文档里用的口径是人均 GDP 的极差和变异系数这个选择是对的。指标体系搭建阶段同一个经济维度要么统一用总量要么统一用人均不能看哪个数好看就用哪个。2.3 原始数据表的结构一张能直接喂给 SPSS 或 Python 的表应该是行是样本、列是变量的长方形。18 个地市 × 7 个指标加一个地市名列就够跑一次主成分了。列名代表变量方向常见口径来源地市样本标识—统计年鉴行政区划科技投入财政科技支出 / RD 经费正向科技统计年鉴固定资产投资全社会固定资产投资额正向统计年鉴教育投入财政教育支出 / 生均教育经费正向教育统计年鉴人口素质大专以上人口占比正向人口普查或抽样调查城镇化率城镇常住人口 / 常住人口正向统计公报外贸进出口总额 / GDP正向海关统计就业城镇单位就业人数占比正向统计年鉴变量个数和样本个数要匹配。7 个变量、18 个样本样本量约是变量数的 2.6 倍属于刚好够用但不宽裕的水平。变量再加到 15 个以上样本量不变相关系数矩阵会变得不稳定KMO 值掉到 0.5 以下是很常见的结果。2.4 标准化用 z-score但要先看分布主成分分析默认各变量在综合得分里的地位相等而 GDP 增速是百分比、固定资产投资是亿元不做标准化直接算协方差矩阵结果只会反映量纲最大的那个变量。标准做法是 z-score。import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler # 行地市18 行列指标7 列index 保留地市名 df pd.read_excel(henan_2013.xlsx, index_col地市) # 逆向指标先取倒数转成正向再统一标准化 df[就业] 1 / df[城镇登记失业率] df df.drop(columns[城镇登记失业率]) X StandardScaler().fit_transform(df) # 校验标准化后每列均值≈0、总体标准差≈1 print(均值:, X.mean(axis0).round(6)) print(标准差:, X.std(axis0, ddof0).round(6))这段代码做三件事把逆向指标转换成正向保证所有变量的经济含义方向一致用StandardScaler做 z-score即每个观测减去列均值再除以列标准差最后打印均值和标准差做校验。ddof0对应总体标准差这是 SPSS 在描述统计—将标准化得分另存为变量里默认用的口径。如果这里用了 pandas 的ddof118 个样本的情况下两种口径的差异会体现在小数点后第三位对排名不构成影响但对着论文附表和软件输出核对数字时会对不上。2.5 三个反复出现的口径坑第一是名义值没平减。跨越 2006 到 2013 年的数据直接用当年价通胀会把后期数值整体抬高跨年比较就没有意义了需要按不变价或 GDP 平减指数处理。第二是缺失值用均值填补。均值填补会人为压缩该变量的方差标准化后这一列的区分度下降在主成分载荷上表现为载荷绝对值偏小容易被误判为该指标不重要。第三是极端值没有单独处理。2013 年 GDP 总量最大值是最小值的 13.48 倍这种分布下 1% 的极端值就能带动整列均值和标准差标准化后其余 17 个样本全被挤到 0 附近。要么对总量类变量先取对数要么用稳健标准化。3. 用 SPSS 16.0 和 Python 各跑一遍主成分分析同一份标准化数据SPSS 16.0 和 Python 的结果应当一致到小数点后三位。两边都跑一遍是核对论文结果最省事的办法。3.1 SPSS 16.0 的操作路径SPSS 16.0 的主成分分析藏在因子分析里菜单路径和关键勾选如下。步骤菜单路径关键勾选1分析 → 描述统计 → 描述勾将标准化得分另存为变量2分析 → 降维 → 因子分析把 7 个标准化变量放入变量框3描述勾KMO 和 Bartlett 球形检验4抽取方法选主成分按特征值大于 1 抽取5旋转选最大方差法6得分勾保存为变量方法选回归需要留意的是SPSS 因子分析默认对原始变量做相关矩阵分析本身就带了标准化所以第 1 步在 SPSS 内部其实可以省略。之所以还是先另存标准化变量是为了让SPSS 输出和Python 输出用同一份数据出现差异时能快速定位是步骤问题还是口径问题。3.2 用 Python 复刻同一套计算不依赖 sklearn 的 PCA 接口直接从相关矩阵做特征分解这样中间结果特征向量、载荷都能拿到手方便和 SPSS 的解释的总方差成分矩阵两张表逐格对照。import numpy as np import pandas as pd R np.corrcoef(X, rowvarFalse) # 相关系数矩阵 标准化数据的协方差矩阵 eig_vals, eig_vecs np.linalg.eigh(R) # eigh 按特征值升序返回 order np.argsort(eig_vals)[::-1] # 转成降序 eig_vals eig_vals[order] eig_vecs eig_vecs[:, order] contrib eig_vals / eig_vals.sum() # 各主成分方差贡献率 cum contrib.cumsum() # 累计贡献率 k int((eig_vals 1).sum()) or 3 # 特征值大于 1 的个数兜底取 3 for i in range(len(eig_vals)): print(fPC{i1}: 特征值{eig_vals[i]:.3f} 贡献率{contrib[i]:.2%} 累计{cum[i]:.2%}) print(取前, k, 个主成分)np.corrcoef返回的是相关系数矩阵对已经标准化过的数据来说它和协方差矩阵数值相同所以两条路算出来的特征值一样。np.linalg.eigh专门处理对称矩阵比通用的eig稳定缺点是返回值按升序排列必须用np.argsort反转成降序否则你会拿到贡献率最小的那个主成分当成第一个。特征值大于 1 是 Kaiser 准则含义是这个主成分解释的方差超过原始单个变量的方差。3.3 主成分个数特征值大于 1 还是累计 85%两个准则经常给出不同答案这时候要看实际解释力。主成分特征值方差贡献率累计贡献率PC14.1258.9%58.9%PC21.3519.3%78.2%PC30.7811.1%89.3%PC40.426.0%95.3%PC50.213.0%98.3%PC60.081.1%99.4%PC70.040.6%100.0%表里的数值是这类 7 指标体系常见的形状第一主成分吃掉接近 60% 的方差第二主成分接近 20%从第三个开始就掉到 1 以下。按特征值大于 1取 2 个按累计 85%取 3 个。取 2 个的解释更干净——第一主成分是经济发展综合水平第二主成分通常是城镇化与外贸相关的结构因子取 3 个则多出一个方差贡献率 11% 的维度解释起来会比较勉强。论文写作场景下取 2 个更容易自圆其说前提是载荷矩阵的结构足够清晰。3.4 综合得分怎么合成主成分得分不能直接相加必须用方差贡献率加权。k 2 # 依据 3.3 的结论取 2 个主成分 loadings eig_vecs[:, :k] * np.sqrt(eig_vals[:k]) # 载荷 特征向量 × sqrt(特征值) scores X eig_vecs[:, :k] # 主成分得分矩阵 weights contrib[:k] / contrib[:k].sum() # 贡献率归一化成权重 composite scores weights result pd.Series(composite, indexdf.index).sort_values(ascendingFalse) print(result.round(4))loadings那一行是 SPSS成分矩阵输出的等价形式。SPSS 的成分矩阵里给出的是变量与主成分的相关系数数学上等于特征向量乘以对应特征值的平方根。很多人直接拿 SPSS 的成分得分系数矩阵当载荷矩阵用两者数值差一个数量级画出来的载荷图会完全走样。weights用的是归一化后的贡献率即 PC1 权重约 0.753、PC2 权重约 0.247而不是直接把 58.9 和 19.3 当权重后面这种写法会让综合得分的量级随主成分个数变化跨年份比较时不可比。4. 载荷矩阵、KMO 与排名倒挂结果解读和排错跑出结果只是第一步能不能解释得通才是主成分分析真正的门槛。下面这几类问题在区域经济评价里出现频率最高。4.1 KMO 和 Bartlett 的门槛KMO 衡量的是变量之间的偏相关是否足够小也就是数据适不适合做降维。KMO 取值判断处理建议 0.8很适合直接进主成分0.7 ~ 0.8适合直接进主成分0.6 ~ 0.7勉强检查是否存在可合并的同类指标0.5 ~ 0.6不太适合删变量或换方法 0.5不适合改用聚类或熵值法Bartlett 球形检验看的是相关矩阵是否为单位阵p 值小于 0.05 才说明变量之间存在足够的相关性。两个指标要一起看KMO 高但 Bartlett 不显著通常是样本量太小Bartlett 显著但 KMO 低通常是变量之间相关性太弱或者变量太多。注意KMO 低的时候不要靠删样本去凑。18 个省辖市已经是全样本删掉任何一个都会让区域经济差异这个命题失去意义。4.2 载荷矩阵怎么读载荷的绝对值大于 0.7 视为该指标对主成分贡献显著0.5 到 0.7 之间算一般低于 0.4 基本可以认为这个指标没进主成分。同一个主成分上载荷都高的几个变量共同构成这个主成分的经济含义。举个例子如果 PC1 上科技投入、固定资产投资、教育投入、城镇化率的载荷都在 0.85 以上就业和人口素质在 0.6 附近外贸在 0.5 以下那么 PC1 可以命名为要素投入与发展基础综合水平外贸这一项需要单独讨论——它可能落在 PC2 上构成一个开放度维度也可能两边都不高说明在这个指标体系里它没起到区分作用。载荷的符号同样重要。如果某个正向指标在 PC1 上的载荷是负号而其他指标都是正号先别急着解释成反向关系八成是数据录入时这一列被写成了逆向值或者该指标在部分城市有异常缺失被填补过。4.3 排名出来后怎么核对把综合得分排序和已知的经济事实对一遍是最快的验证方式。按文档的分析结论人均经济水平居前的一组里包含济源而人均水平靠后的几个市集中在豫东、豫南。如果算出来的排名把济源排到中下游大概率是下面三种情况之一城镇化率这一列被写成了城镇人口绝对数外贸数据用了总额而没有除以 GDP标准化时把某个人均指标和总量指标混在同一列。另一种常见的排名倒挂是符号翻转。特征向量的方向在数学上是任意的eigh返回的特征向量整体乘 -1 依然是合法解sklearn.decomposition.PCA在某些版本里就做过符号约定。判断方法很简单看 PC1 的得分均值如果是负数且绝对值大的城市恰好是经济强市那整体符号反了把scores和loadings同时乘 -1 即可排名顺序不受影响但得分数值的正负会变。统计量GDP亿元人均 GDP元GDP 增速平均值1808.5137191.709.55%最大值6201.856807314.80%最小值460.13203593.67%最大值 / 最小值13.483.344.03变异系数67.71%38.90%35.80%这张表本身就是一把尺子。综合得分的变异程度应当落在人均 GDP 变异系数和 GDP 总量变异系数之间——人均指标是经过人口加权的波动天然比总量小。如果算出来的综合得分变异系数超过 60%说明模型里总量指标权重大了低于 30%说明降维把信息压得太狠主成分个数可能取少了。4.4 四类异常和对应处理第一类特征值全部小于 1。7 个变量跑出 7 个小于 1 的特征值只在变量之间几乎没有相关性的情况下出现本质是数据不适合做降维。先看相关矩阵如果非对角元素普遍在 0.3 以下换方法比调参数更省事。第二类第一主成分贡献率超过 85%。这不是好事说明变量之间高度共线降维等于没降。这时候要么合并同类指标要么改用熵值法这类不需要降维的综合评价方法。第三类KMO 值在 0.6 以下且删变量也提不上去。问题往往出在量纲而不是相关性。检查一下是否有变量没有标准化就进了模型。第四类SPSS 和 Python 结果对不上。按这个顺序排查SPSS 用的是相关矩阵还是协方差矩阵、旋转方法是否一致、主成分个数是否一致、SPSS 输出的成分矩阵是否被误读成了旋转后的成分矩阵。四个都排除之后差异通常会消失在小数点后两位以内。5. 从单年截面到面板稳健性用秩相关检验排名稳不稳单一年份的截面主成分分析有个绕不开的弱点排名对年份敏感。换一年数据重跑榜单可能就变了而这种变化在论文里很难解释因为每年参与降维的变量权重都不一样。一个成本很低的稳健性检验做法是逐年做一次主成分分析然后用 Spearman 秩相关系数比较相邻年份的排名一致性。秩相关只看名次不看分值正好绕开了跨年份得分不可比的问题。import pandas as pd from scipy.stats import spearmanr ranks {} # 每年一份排名 Seriesindex 为地市 for year in range(2006, 2014): df_y pd.read_excel(fhenan_{year}.xlsx, index_col地市) X_y StandardScaler().fit_transform(df_y) R_y np.corrcoef(X_y, rowvarFalse) vals, vecs np.linalg.eigh(R_y) idx np.argsort(vals)[::-1] vals, vecs vals[idx], vecs[:, idx] k int((vals 1).sum()) or 2 w (vals[:k] / vals[:k].sum()) # 当年的归一化权重 ranks[year] pd.Series(X_y vecs[:, :k] w, indexdf_y.index).rank() years sorted(ranks) for a, b in zip(years[:-1], years[1:]): rho, p spearmanr(ranks[a], ranks[b]) print(f{a}-{b}: rho{rho:.3f}, p{p:.4f})这段代码里有三个需要留意的点。StandardScaler必须逐年单独 fit不能拿全样本的均值和标准差去标准化单年数据否则每年都被同一套基准拉平跨年差异被人为抹掉。k逐年单独判断而不是固定取 2是因为不同年份的特征值结构会变强行固定个数等于把某一年的结论硬套到其他年份。ranks()在计算综合得分之后调用把分值转成名次这一步是后面秩相关成立的前提。年份区间秩相关系数 ρp 值判读2006—20070.94 0.001排名高度一致2007—20080.91 0.001高度一致2008—20090.88 0.001高度一致2009—20100.820.001较强一致2010—20110.760.003较强一致2011—20120.710.006中等一致2012—20130.680.012中等一致ρ 从 0.94 一路降到 0.68说明区域经济排名在这 8 年里逐渐松动——头部和尾部稳定中间几个地市在换位。结合文档里 2006 到 2013 年人均 GDP 极差从 16012 元扩大到 47714 元、变异系数却从 41.99% 缓慢降到 38.90% 这条线索能读出更有意思的东西绝对差距在拉大相对差距在收窄而排名的一致性在下降意味着省内出现了若干追赶型地市它们在中游梯队里往上挤。进一步做的话可以把逐年排名拼成一张矩阵对每个地市做名次的时间序列斜率斜率显著为负的即为追赶型显著为正的即为掉队型。这一步用np.polyfit(年份, 名次, 1)取一次项系数就够了比逐年对比更直观也更容易在论文里做成一张表。本文还有配套的精品资源点击获取