一.介绍
主成分分析在统计中的地位不言自明,而因子分析像一个孪生兄弟一样,常常和主成分分析密不可分,本帖将用最简单的叙述,越过证明,只从基本的步骤来学习一下如何用python做因子分析。
因子分析研究相关阵或协方差阵的内部依赖关系,它将多个变量综合为少数几个因子,以再现原始变量和因子之间的关系。
举个例子,在资产配置时,我们常常遇到相关性比较高的资产,会带来极大的风险,我们可以把影响风险的变量分解到几个正交的因子上,以此为标准配置资产,以避免风险聚集。
二.正交因子模型
设X=(X1,⋯,Xp)T是P个观察到的随机变量,每个变量有n个样本,E(X)=μ,Cov(X)=Σ,又设F=(F1,⋯,Fm)T(m
取日收益率,以ticker名为列名
2
X = pd.DataFrame()
3
for i in universe:
4
data = DataAPI.MktFunddGet(ticker=i,beginDate=u”20160401”,endDate=u”20160701”,field=u”preClosePrice,closePrice”,pandas=”1”)
5
X[i] = data[‘closePrice’]/data[‘preClosePrice’]-1
查看全部
1
X.head() #看看日收益率的前5行
查看全部
150008 150012 512300 512330 513100
0 0.008138 0.000853 -0.008757 -0.004745 -0.005212
1 -0.001009 -0.002558 0.020318 0.030989 0.005894
2 0.025253 0.000855 0.010390 -0.005780 0.000000
3 -0.013793 0.000854 -0.004284 -0.006977 0.011068
4 -0.011988 0.000853 -0.010327 -0.015222 -0.010947
1
X.shape
查看全部
(62, 5)
1.计算样本均值,样本离差阵E及样本相关阵R:
样本均值x¯:
X¯=1n∑t=1nX(t)=(x1¯,⋯,xp¯)T
1
X_mean = X.mean()
2
print X_mean
查看全部
150008 -0.000277
150012 0.000111
512300 0.000215
512330 0.001097
513100 0.000178
dtype: float64
样本离差阵E:
E=∑t=1n(X(t)−X¯)(X(t)−X¯)T=def(eij)
1
E = np.mat(np.zeros((5,5)))
2
for i in range(len(X)):
3
E += (X.iloc[i,:].reshape(5,1)-X_mean.reshape(5,1))*(X.iloc[i,:].reshape(1,5)-X_mean.reshape(1,5))
查看全部
样本相关阵R:
R=(rij),rij=eij(√eiiejj)
1
R= np.mat(np.zeros((5,5)))
2
for i in range(5):
3
for j in range(5):
4
R[i,j] = E[i,j]/sqrt(E[i,i]*E[j,j])
查看全部
1
R
查看全部
matrix([[ 1. , 0.10155843, 0.44977163, 0.44254457, 0.11262073],
[ 0.10155843, 1. , 0.13173956, 0.2268017 , 0.13834493],
[ 0.44977163, 0.13173956, 1. , 0.83522507, 0.34464978],
[ 0.44254457, 0.2268017 , 0.83522507, 1. , 0.31025561],
[ 0.11262073, 0.13834493, 0.34464978, 0.31025561, 1. ]])
其实也可以直接使用dataframe的函数corr
1
X.corr()
查看全部
150008 150012 512300 512330 513100
150008 1.000000 0.101558 0.449772 0.442545 0.112621
150012 0.101558 1.000000 0.131740 0.226802 0.138345
512300 0.449772 0.131740 1.000000 0.835225 0.344650
512330 0.442545 0.226802 0.835225 1.000000 0.310256
513100 0.112621 0.138345 0.344650 0.310256 1.000000
2.求R的特征值和标准化特征值向量
1
import numpy.linalg as nlg
2
eig_value,eig_vector=nlg.eig(R) #求特征值,特征向量
查看全部
1
eig = pd.DataFrame()
2
eig[‘names’] = X.columns
3
eig[‘eig_value’] = eig_value
4
eig
查看全部
names eig_value
0 150008 2.400086
1 150012 0.605739
2 512300 0.968248
3 512330 0.868160
4 513100 0.157767
把特征值从大到小排序λ1≥λ2≥λ3≥⋯≥λp≥0:
1
eig.sort(‘eig_value’,ascending=False,inplace=True)
2
eig
查看全部
names eig_value
0 150008 2.400086
2 512300 0.968248
3 512330 0.868160
1 150012 0.605739
4 513100 0.157767
3.求因子模型的因子载荷阵A
先确定公共因子的个数m:
这里使用前m个特征值的比重大于80%的标准,即:
λ1+⋯+λmλ1+⋯+λm+⋯+λp≥0.8
1
for m in range(1,6):
2
if eig[‘eig_value’][:m].sum()/eig[‘eig_value’].sum() >= 0.8:
3
print m
4
break
查看全部
3
所以公共因子是三个,然后就可以求因子载荷阵了:
A=(λ√1l1,⋯,λ√mlm)
1
A=np.mat(np.zeros((5,3)))
2
A[:,0]=sqrt(eig_value[0])*eig_vector[:,0]
3
A[:,1]=sqrt(eig_value[2])*eig_vector[:,2]
4
A[:,2]=sqrt(eig_value[3])*eig_vector[:,3]
查看全部
1
pd.DataFrame(A)
查看全部
0 1 2
0 0.639456 0.355693 0.369517
1 0.327550 -0.815825 0.475186
2 0.900198 0.168980 -0.066508
3 0.904278 0.085293 0.028512
4 0.505784 -0.374608 -0.707516
4.求特殊因子方差σ^2i和Xi的共同度h2i的估计
σ^2i=1−∑t=1ma2it(i=1,⋯,p)
h2i=∑j=1ma2ij,(i=1,2,⋯,p)
1
h=np.zeros(5) #共同度
2
D=np.mat(np.eye(5)) #特殊因子方差
3
for i in range(5):
4
a=A[i,:]*A[i,:].T
5
h[i]=a[0,0]
6
D[i,i] = 1-a[0,0]
查看全部
1
print h
2
print pd.DataFrame(D).to_html()
查看全部
[ 0.67196497 0.99866116 0.84333396 0.82580655 0.89672678]
0 1 2 3 4
0 0.328035 0.000000 0.000000 0.000000 0.000000
1 0.000000 0.001339 0.000000 0.000000 0.000000
2 0.000000 0.000000 0.156666 0.000000 0.000000
3 0.000000 0.000000 0.000000 0.174193 0.000000
4 0.000000 0.000000 0.000000 0.000000 0.103273
5.对公共因子做解释
基本想法是:首先看哪些变量在这个因子中的负荷量大,然后利用专业知识讨论这些变量组合的实际含义。
1
a=pd.DataFrame(A)
2
a.columns=[‘factor1’,’factor2’,’factor3’]
3
a.index=[‘x1’,’x2’,’x3’,’x4’,’x5’]
4
a
查看全部
factor1 factor2 factor3
x1 0.639456 0.355693 0.369517
x2 0.327550 -0.815825 0.475186
x3 0.900198 0.168980 -0.066508
x4 0.904278 0.085293 0.028512
x5 0.505784 -0.374608 -0.707516
比如看因子载荷阵的第二列,除了a22的绝对值较大外,其它相对较小,可以说F2主要反映x2的信息
当然,这样子经常容易使公共因子的意义含糊不清,在统计上,有一种方差最大正交旋转的方法可以改善这个问题,使公共因子的典型代表变量更加突出~
因子分析部分的内容还有很多,此帖先介绍到此,错误之处望指出,继续交流学习~
参考文献:应用多元统计分析 高惠璇