因子分析法(Factor Analysis)是一种利用降维的思想,从研究原始变量相关矩阵内部的依赖关系出发,把一些具有错综复杂关系的变量归结为少数几个综合因子的一种多变量统计分析方法。其优势在于不仅可以在减少大量指标分析的工作量的同时保证分析结果的合理性,还能够使得提取的公因子更具有对研究对象的解释性和客观性。
设随机变量X=(X1,X2,…,Xp)X=(X_{1},X_{2},\dots,X_{p})X=(X1,X2,…,Xp), 其中E(X)=μ,D(X)=∑E(X)=\mu,D(X)=\sumE(X)=μ,D(X)=∑; 同时有几个难以观测的随机变量F=(F1,F2,…,Fm)(m
在正交因子模型中,需要使用m+pm+pm+p个不可观测的随机变量FFF、eee来表示原始变量XXX,常用的回归方法无法确定因子载荷矩阵AAA。基于前述的关于公共因子及特殊因子之间的相关假设,可以得出
∑=E[(X−μ)(X−μ)T]=E[(AF+ϵ)(AF+ϵ)T]=AD(F)AT+D(ϵ)=AAT+D\begin{aligned}\sum&=E[(X-\mu)(X-\mu)^{T}]\\&=E[(AF+\epsilon)(AF+\epsilon)^{T}]\\&=AD(F)A^{T}+D(\epsilon)\\&=AA^{T}+D\end{aligned}∑=E[(X−μ)(X−μ)T]=E[(AF+ϵ)(AF+ϵ)T]=AD(F)AT+D(ϵ)=AAT+D因此∑−D=AAT\sum-D=AA^{T}∑−D=AAT,由此可知模型中第jjj变量和第kkk个变量的协方差σjk\sigma_{jk}σjk可以由下述公式得到:σjk=aj1ak1+aj2ak2+⋯+ajnakn\sigma_{jk}=a_{j1}a_{k1}+a_{j2}a_{k2}+\dots+a_{jn}a_{kn}σjk=aj1ak1+aj2ak2+⋯+ajnakn如果原始变量已经被标准化为单位方差,那么在∑−D=AAT\sum-D=AA^{T}∑−D=AAT中就可以使用相关矩阵来代替协方差矩阵。因此可以看出,公共因子解释观测变量之间的相关关系,而因子分析的目的是由样本的协方差矩阵∑^\hat{\sum}∑^来估计∑\sum∑,进而求出AAA和DDD。即从可观测的变量XXX所给出的样本求出载荷矩阵AAA,然后再预测公共因子FFF。
因子分子法使用的前提是各指标变量之间应当具有可比性,但研究中所选取的指标单位可能不统一,而且有一些是正向指标,有一些是适度指标,因此进行因子分析前,需要对选取的原始变量无量纲化处理。
在进行因子分析时,需要对原始变量进行相关系数矩阵运算,来检测所选取的原始变量之间是否存在较强的相关关系。可以使用KMO(Kaiser-Meyer-Olkin)与Bartlett球形度检测方法来对因子分析进行适用性检验。
公因子提取一方面可以对原始数据进行优化,另一方面提取相同性质的关键因子,以便于减少无用变量。常用的公因子提取方法是主成分分析法。实际应用常共同使用以下两个准则来确定因子的个数:
注意:这里说的特征值指的是相关系数矩阵的特征值。
公因子只有经过正交旋转后,因子载荷矩阵中的系数才会更加显著,公因子才会具备实际意义,这样提取的公因子才能更加清晰准确地解释原始变量。通常因子旋转所用的手段是:正交旋转。得到因子解后,需要赋予每个因子一个有意义的解释,即给因子命名。
这里使用Python中专门进行因子分析的包factor_analyzer来展示因子分析的整个过程,实验数据来自于参考文献5。具体代码如下:
import pandas as pd
import numpy as np
from factor_analyzer import FactorAnalyzer
import factor_analyzer
from sklearn.preprocessing import MinMaxScaler
from sympy import *
from matplotlib import pyplot as pltdata=pd.read_excel(r'C:/Users/sunta/Downloads/因子分析数据.xlsx',header=0,index_col=0)#预处理:归一化
mm_scaler=MinMaxScaler()
data=mm_scaler.fit_transform(data)#计算相关系数矩阵
data_corr=factor_analyzer.corr(data)#验证是否适用于因子分析
_,kmo_total=factor_analyzer.calculate_kmo(data)
bartlett=factor_analyzer.calculate_bartlett_sphericity(data)
print("KMO:{}, Bartlett球形检测:{}".format(kmo_total,bartlett))#求取相关系数矩阵的特征值
eig_w,_=np.linalg.eig(data_corr)#绘制碎石图
plt.plot(range(1,data.shape[1]+1),eig_w,'o-')
plt.xticks(range(1,data.shape[1]+1))for i in range(1,data.shape[1]+1):plt.text(i,eig_w[i-1],'{:.3f}'.format(eig_w[i-1]))
plt.xlabel('因子个数')
plt.show()#因子分析
fa=FactorAnalyzer(n_factors=3,rotation=None)
fa.fit(data)#转换后的数据
data=fa.transform(data)
这里的结果与参考文献5中的不一样,原因可能在于图片中的数据并不没有展示完整的数据。
主成分分析和因子分析都是利用降维思想,尝试用几个主成分(或公因子)来代表所有原始变量的信息。这两者的不同点如下:
上文中,因子分析的第一步即为数据归一化,这一部分主要是想验证归一化是否会对相关性的计算产生影响。通过随机生成多个字段,并对比归一化前后字段之间的相关性计算值。具体如下:
import numpy as np
import pandas as pdx1=np.random.randint(0,100,size=100)*5+2
x2=3*x1+2+np.random.random(size=100)*1.1
x3=np.random.random(size=100)*7+3+np.random.random(size=100)*0.5a=np.array([x1,x2,x3]).T
a=pd.DataFrame(a,columns=['x1','x2','x3'])print('归一化前的相关性:')
print(a.corr())
print('=====================================')
from sklearn.preprocessing import MinMaxScaler
mm_scaler=MinMaxScaler()
a_mm=pd.DataFrame(mm_scaler.fit_transform(a),columns=['x1','x2','x3'print('最大最小归一化后的相关性:')
print(a_mm.corr())
print('=====================================')from sklearn.preprocessing import StandardScalerstd_scaler=StandardScaler()
a_std=pd.DataFrame(std_scaler.fit_transform(a),columns=['x1','x2','x3'])print("标准化之后的相关性:")
print(a_std.corr())
其结果如下:
从实验结果中可以发现:归一化并不会对相关性的计算产生影响。
若在使用pip命令安装factor_analyzer包时可能会遇到如下图所示的错误(AttributeError: module ‘enum’ has no attribute ‘IntFlag’)。
出现上述错误是因为在site-packages包中安装的enum34包和标准库中的enum产生了冲突,这里只需要卸载enum34包(命令:pip uninstall enum34),然后再重新执行pip install factor_analyzer命令即可。这个方案也适用于Windows系统。
上一篇:JavaScript 字符串
下一篇:Java_Git:4. 分支管理