Python进行因子分析

1 因子分析

1.1 定义

  因子分析法(Factor Analysis)是一种利用降维的思想,从研究原始变量相关矩阵内部的依赖关系出发,把一些具有错综复杂关系的变量归结为少数几个综合因子的一种多变量统计分析方法。其优势在于不仅可以在减少大量指标分析的工作量的同时保证分析结果的合理性,还能够使得提取的公因子更具有对研究对象的解释性和客观性。
  设随机变量 X = ( X 1 , X 2 , … , X p ) X=(X_{1},X_{2},\dots,X_{p}) X=(X1,X2,,Xp), 其中 E ( X ) = μ , D ( X ) = ∑ E(X)=\mu,D(X)=\sum E(X)=μ,D(X)=; 同时有几个难以观测的随机变量 F = ( F 1 , F 2 , … , F m ) ( m < p ) F=(F_{1},F_{2},\dots,F_{m})(m \lt p) F=(F1,F2,,Fm)(m<p),其中 E ( F ) = 0 , D ( F ) = I m E(F)=0,D(F)=I_{m} E(F)=0,D(F)=Im,即 F F F中各个分量方差为1,并且彼此不相关。又有 p p p个附加的随机变量 e = ( e 1 , e 2 , … , e p ) e=(e_{1},e_{2},\dots,e_{p}) e=(e1,e2,,ep) F F F互不相关,并且有 E ( e ) = 0 , D ( e ) = d i a g ( σ 1 , … , σ p ) d e f = D E(e)=0,D(e)=diag(\sigma_{1},\dots,\sigma_{p})^{def}=D E(e)=0,D(e)=diag(σ1,,σp)def=D
  如果随机向量 X X X满足下面的模型: { x 1 = c 1 + a 11 f 11 + a 12 f 12 + ⋯ + a 1 m f 1 m + e 1 x 2 = c 2 + a 21 f 21 + a 22 f 22 + ⋯ + a 2 m f 2 m + e 2 ⋮ x p = c p + a p 1 f p 1 + a p 2 f p 2 + ⋯ + a p m f p m + e p (1) \left\{ \begin{aligned} x_{1}&=c_{1}+a_{11}f_{11}+a_{12}f_{12}+\dots+a_{1m}f_{1m}+e_{1}\\ x_{2}&=c_{2}+a_{21}f_{21}+a_{22}f_{22}+\dots+a_{2m}f_{2m}+e_{2}\\ \vdots & \\ x_{p}&=c_{p}+a_{p1}f_{p1}+a_{p2}f_{p2}+\dots+a_{pm}f_{pm}+e_{p} \end{aligned} \right.\tag{1} x1x2xp=c1+a11f11+a12f12++a1mf1m+e1=c2+a21f21+a22f22++a2mf2m+e2=cp+ap1fp1+ap2fp2++apmfpm+ep(1)则称该模型为正交因子模型,用矩阵可以写为: X = c + A F + E (2) X=c+AF+E \tag{2} X=c+AF+E(2)其中 F F F称作公共因子,随机变量 e e e称为 X X X的特殊因子,每个特殊因子之间以及特殊因子与各个公共因子之间都是互不相关的。矩阵 A = ( a i j ) p × m A=(a_{ij})_{p\times m} A=(aij)p×m是等待估计的系数矩阵,被称为因子载荷矩阵。关于因子载荷矩阵,需要说明以下几点:

  • a i j a_{ij} aij为因子载荷,是连接观测变量和因子变量之间的纽带,其值是 X i , F j X_{i},F_{j} Xi,Fj的协方差,其值越大,则 F j F_{j} Fj对于 X i X_{i} Xi的载荷量越大, X i X_{i} Xi F j F_{j} Fj之间的相关程度越大,关系越密切。
  • A A A中第 i i i行元素的平方和称为变量 X i X_{i} Xi的共同度,共同度大表明变量能被因子说明的程度高;
  • A A A中第 j j j列元素的平方和称为公共因子 F j F_{j} Fj X X X的方差贡献,是衡量公共因子相对重要性的指标,贡献越大公共因子的作用和影响越大。

  在正交因子模型中,需要使用 m + p m+p m+p个不可观测的随机变量 F F F e e e来表示原始变量 X X X,常用的回归方法无法确定因子载荷矩阵 A A A。基于前述的关于公共因子及特殊因子之间的相关假设,可以得出
∑ = E [ ( X − μ ) ( X − μ ) T ] = E [ ( A F + ϵ ) ( A F + ϵ ) T ] = A D ( F ) A T + D ( ϵ ) = A A T + 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 = A A T \sum-D=AA^{T} D=AAT,由此可知模型中第 j j j变量和第 k k k个变量的协方差 σ j k \sigma_{jk} σjk可以由下述公式得到: σ j k = a j 1 a k 1 + a j 2 a k 2 + ⋯ + a j n a k n \sigma_{jk}=a_{j1}a_{k1}+a_{j2}a_{k2}+\dots+a_{jn}a_{kn} σjk=aj1ak1+aj2ak2++ajnakn如果原始变量已经被标准化为单位方差,那么在 ∑ − D = A A T \sum-D=AA^{T} D=AAT中就可以使用相关矩阵来代替协方差矩阵。因此可以看出,公共因子解释观测变量之间的相关关系,而因子分析的目的是由样本的协方差矩阵 ∑ ^ \hat{\sum} ^来估计 ∑ \sum ,进而求出 A A A D D D。即从可观测的变量 X X X所给出的样本求出载荷矩阵 A A A,然后再预测公共因子 F F F

1.2 基本步骤

1.2.1 预处理

  因子分子法使用的前提是各指标变量之间应当具有可比性,但研究中所选取的指标单位可能不统一,而且有一些是正向指标,有一些是适度指标,因此进行因子分析前,需要对选取的原始变量无量纲化处理。

1.2.2 确定原始变量是否适用于因子分析

  在进行因子分析时,需要对原始变量进行相关系数矩阵运算,来检测所选取的原始变量之间是否存在较强的相关关系。可以使用KMO(Kaiser-Meyer-Olkin)与Bartlett球形度检测方法来对因子分析进行适用性检验。

  • KMO检验:该检验可以对原始变量之间的简单相关系数和偏相关系数的相对大小进行检验。其计算公式如下: K M O = ∑ ∑ i ≠ j r i j 2 ∑ ∑ i ≠ j r i j 2 + ∑ ∑ i ≠ j α i j ⋅ 1 , 2 , … , k 2 KMO=\frac{\sum\sum_{i \neq j}r_{ij}^{2}}{\sum\sum_{i \neq j}r_{ij}^{2}+\sum\sum_{i \neq j}\alpha_{ij \cdot1,2,\dots,k}^{2}} KMO=i=jrij2+i=jαij1,2,,k2i=jrij2其中, r i j r_{ij} rij为简单相关系数, α i j ⋅ 1 , 2 , … , k \alpha_{ij \cdot 1,2,\dots,k} αij1,2,,k为偏相关系数。 K M O ∈ [ 0 , 1 ] KMO \in [0,1] KMO[0,1]取值越大,变量间的相关性越强,偏相关性越弱,因子分析的效果越好。一般超过0.7,就可以进行因子分析。
  • Bartlett球形度检测:该检验可以检测变量是否独立,它是以相关系数矩阵为基础的。其对应的原假设及统计量为:
    H 0 : H0: H0:其相关系数矩阵为单位矩阵;
    统计量:根据相关系数矩阵的行列式得到的;
    如果该值较大,且其对应的相伴概率值小于指定的显著水平时。如果统计量值较大,拒绝零假设,表明相关系数矩阵不是单位阵,原有变量之间存在相关性,适合进行因子分析。
1.2.3 抽取公因子并确定公因子数量

  公因子提取一方面可以对原始数据进行优化,另一方面提取相同性质的关键因子,以便于减少无用变量。常用的公因子提取方法是主成分分析法。实际应用常共同使用以下两个准则来确定因子的个数:

  • 特征值准则:取特征值大于或等于1的主成分为公共因子,而放弃小于1的;
  • 碎石检验准则:按照因子被提取的顺序,画出因子的特征值随因子个数变化的散点图,再根据图的形状来判断所要提取=的公共因子及其个数。根据碎石图,一般认为曲线开始扁平前的一个点对应的因子数目是提取公共因子的最大数。

注意:这里说的特征值指的是相关系数矩阵的特征值。

1.2.4 因子旋转并命名

  公因子只有经过正交旋转后,因子载荷矩阵中的系数才会更加显著,公因子才会具备实际意义,这样提取的公因子才能更加清晰准确地解释原始变量。通常因子旋转所用的手段是:正交旋转。得到因子解后,需要赋予每个因子一个有意义的解释,即给因子命名。

2 Python进行因子分析

  这里使用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 plt

data=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中的不一样,原因可能在于图片中的数据并不没有展示完整的数据。

3 其他

3.1 因子分析与主成分分析

  主成分分析和因子分析都是利用降维思想,尝试用几个主成分(或公因子)来代表所有原始变量的信息。这两者的不同点如下:

  • 主成分分析法实在损失很少信息的前提下把多个指标转化为几个不相关的综合指标,即每个主成分都是原始变量的线性组合,且各个主成分之间一定互不相关。因子分析一般假定各因子互不相关,但实际上各公因子并不一定满足互不相关要求。
  • 相对于主成分分析,因子分析更倾向于描述原始变量之间的相关关系。

3.2 归一化是否影响相关性计算

  上文中,因子分析的第一步即为数据归一化,这一部分主要是想验证归一化是否会对相关性的计算产生影响。通过随机生成多个字段,并对比归一化前后字段之间的相关性计算值。具体如下:

import numpy as np
import pandas as pd

x1=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.5

a=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 StandardScaler

std_scaler=StandardScaler()
a_std=pd.DataFrame(std_scaler.fit_transform(a),
                   columns=['x1','x2','x3'])

print("标准化之后的相关性:")
print(a_std.corr())

其结果如下:
在这里插入图片描述
从实验结果中可以发现:归一化并不会对相关性的计算产生影响。

3.3 factor_analyzer包的安装

  若在使用pip命令安装factor_analyzer包时可能会遇到如下图所示的错误(AttributeError: module ‘enum’ has no attribute ‘IntFlag’)。
在这里插入图片描述
  出现上述错误是因为在site-packages包中安装的enum34包和标准库中的enum产生了冲突,这里只需要卸载enum34包(命令:pip uninstall enum34),然后再重新执行pip install factor_analyzer命令即可。这个方案也适用于Windows系统。

参考资料

  1. 《基于因子分析法的贵州百灵财务绩效评价研究》
  2. 《基于因子分析法的B互联网公司财务绩效评价研究》
  3. https://blog.csdn.net/qq_43517528/article/details/119653072
  4. https://blog.csdn.net/qq_31329259/article/details/82697117
  5. https://zhuanlan.zhihu.com/p/437473180
  6. 《基于因子分析的徽商银行竞争力实证》
  7. https://www.jb51.net/article/239608.htm

猜你喜欢

转载自blog.csdn.net/yeshang_lady/article/details/128181717
今日推荐