统计学方法:主成分分析(PCA)实战
本文重点讨论对降维中常用的统计分析方法之一:主成分分析法。对影响31个城市综合评价的8个指标,用主成分分析法确定8个指标的权重,并使用SPASS和Python两种实战方式进行操作。
前置统计与概论相关知识点
- 协方差:衡量变量间相对于各自自身期望的变化趋势的统计指标,比如变量X大于自身期望时变量Y也大于自身期望,此时变量XY的协方差为正值,反之则为负值。
- 协方差矩阵:由协方差构成的矩阵称之为协方差矩阵。
- 相关系数:用以反映变量之间相关关系密切程度的统计指标。相关系数也可以看成是一种剔除了两个变量量纲影响、标准化后的特殊协方差,它消除了两个变量变化幅度的影响,而只是单纯反应两个变量每单位变化时的相似程度。
- 相关系数矩阵:由相关系数组成的矩阵称之为相关系数矩阵。
理论:
基本原理
主成分分析(Principal components analysis)的思路主要是将原始多个变量通过线性组合的(矩阵旋转)方式转化为几个线无关的变量,且新生成的变量包含了原始变量的绝大部分信息,从而达到降维的目的。但因为新生成成分中所有原变量都占有一定比例,不同比例之间没有一个统一衡量的标准,所以这种方式在解释性方面相对较差。
实际使用的时候,如果变量间的数据波动量比较大,需要进行数据的归一化处理。但在标准化的过程中会抹杀一部分原本刻画变量之间离散程度差异的信息。所以标准化是视实际使用场景而定。
主成分筛选标准
- 保留使得方差贡献率达到80%以上的主成分
- 保留方差(特征值)大于1的主成分的
- 根据碎石图选取变化比较大的前几个主要成分
适用场景
主成分分析不要求数据呈正态分布,主要是使用了线性变换的技术,因为其应用范围较广,通过对原始变量进行综合与简化,可以客观地确定各个指标的权重,避免主观判断的随意性。但是从主成分的思路出发,其主要适用于变量间相关性较强的数据,如果原始数据相关性弱,则起不到很好的降维作用,且降维后存在一定的数据丢失。
分析的基本步骤
- 选取初始变量
- 根据初始变量特性选择使用协方差矩阵还是相关矩阵来求主成分
- 计算协方差矩阵或相关矩阵的特征值和特征向量
- 确定主成分个数
- 对主成分做经济解释,主成分的经济意义由各线性组合中权重较大的几个指标来确定
实战:
SPASS 实战
数据准备:
从食品,衣着,居住,家庭设备,交通通讯,文教娱乐,医疗保健,其他8个指标对全国31个主要城市统计
注:数据不具实际含义,仅用于分析过程学习。
Spass操作:
- Spass -> 分析 -> 降维 -> 因子分析
注:基于相关系数进行矩阵变换。 - 描述选项中勾选初始解,系数,KMO和Bartlett形度检验。
- 提取选项中选择未旋转的因子解,基于特征值,相关性矩阵。
- 方法选项卡中选择无,载荷图。
- 得分中选择因子得分系数矩阵。
注Bartlett球形度检验:检验是否适合主成分析。其原假设是变量间两两相互独立。KMO判断适合主成分析的程度。
结果分析:
KMO和Bartlett检验表:
- Bartlett形度检验:与0.05的置信水平进行比较,小于0.05认为维度之间是相关的,适合主成分分析。
- KMO:取值在0到1之间,大于0.5认为是适合主成分分析。
总方差解释表:
查看各个主成分的特征根,方差,方差占比。
成分得分系数矩阵:
主要查看各个维度在成分上的载荷
权重计算
- 确定指标在各个主成分中的系数,系数求解公式=成分载荷数/√成分特征根
- 确定主成分的方差贡献率:F = ∑Wi*Fi/∑Fj (W是主成分权重,Fi的总方差中的占比,Fj是成分方差占比之和)
- 指标权重的归一化:每个指标的系数/指标系数之和
注:这部分可以借助Excel完成
指标计算
根据上一步的计算的权重计算主每个城市得分:
Indicator = ∑Di*Wi (D表示原始指标数值,W表示当前维度的权重)
结果可视化
SPASS方式结果Python实战
我们采用机器学习库Scikit-learn进行PCA操作,基于协方差进行矩阵变换。
步骤一:数据准备
data_pca = pd.read_excel('data_pca.xlsx', 'consumption', index_col=0, na_values=['NA'])
步骤二:PCA操作
# 该步骤主要是 计算特征根,方差占比,成分系数
# n_components的其他取值:主成分占比(主成分累计方差占比),维度(指定下降之后的维度),‘mle’(会自动确定保留的特征数)
pca = PCA(n_components='mle')
pca.fit(data_pca)
print('输出特征根:')
print(pca.explained_variance_)
print('输出解释方差比:')
print(pca.explained_variance_ratio_)
importance = pca.explained_variance_ratio_
plt.scatter(range(1,8),importance)
plt.plot(range(1,8),importance)
plt.title('碎石图')
plt.xlabel('Factors')
plt.ylabel('Eigenvalue')
plt.grid()
plt.show()
print('输出主成分系数阵:默认列是指标,行是指标在成为上的系数')
# print(pca.components_)
print('输出主成分个数: {}'.format(pca.n_components_))
碎石图
步骤三: 权重计算
# 由碎石图和方差占比可知,前两个主成分的方差变化比较大,且累计方差占比查过90%。所以我们选取前两个成分。
explained_variance_need = pca.explained_variance_[0:2]
print(explained_variance_need)
component_need = pca.components_[:2,:]
print(component_need)
# 确定指标在各个主成分中的系数,系数求解公式=成分载荷数/√成分特征根
component1 = component_need[0,:]/np.sqrt(explained_variance_need[0])
component2 = component_need[1,:]/np.sqrt(explained_variance_need[1])
components = np.vstack((component1.reshape(1,8),component2.reshape(1,8)))
# print(components)
# 确定主成分的方差贡献率:F = ∑Wi*Fi/∑Fj (W是主成分权重,Fi的总方差中的占比,Fj是成分方差占比之和)
component1_ratio = pca.explained_variance_ratio_[0]
component2_ratio = pca.explained_variance_ratio_[1]
weights = []
for x in range(8):
weight = (components[0][x]*component1_ratio + components[1][x]*component2_ratio)/(component1_ratio+component2_ratio)
weights.append(weight)
print(weights)
# 指标权重的归一化:每个指标的系数/指标系数之和
# weights/np.sum(weights)
步骤四: 指标计算
data_pca['indicator'] = np.matrix(data_pca.values).dot(np.transpose(np.matrix(weights)))
步骤五: 结果可视化
show_pic('上海在全国消费指数中排名第一',data_pca['indicator'].sort_values(ascending = False),False)
Python方式结果
小结
从3.1和3.2结果中可以看到排名中有些城市在两种方式上的结果略微有些差异,这个是SPASS和Scikit-learn实现上存在一定的差异,本文的重点在于讨论主成分分析在两种方式上的实现。
如果问题,欢迎回复交流。如有需要源数据的,可以回复获取。
特别声明,本文的数据来自于随机制造,不构成任何效力,仅用于技术学习使用。