基於Python的多因子分析

公衆號:尤而小屋
作者:Peter
編輯:Peter

大家好,我是Peter~

最近看了很多的關於因子分析的資料,整理出這篇理論+實戰文章分享給大家。後續會出一篇PCA主成分分析的文章,將主成分分析和因子分析兩種降維的方法進行對比。

因子分析

作爲多元統計分析裏的降維方法之一,因子分析可以應用於多個場景,如調研、數據建模等場景之中。

起源

因子分析的起源是這樣的:1904年英國的一個心理學家發現學生的英語、法語和古典語成績非常有相關性,他認爲這三門課程背後有一個共同的因素驅動,最後將這個因素定義爲“語言能力”。

基於這個想法,發現很多相關性很高的因素背後有共同的因子驅動,從而定義了**因子分析,這便是因子分析的由來。

基本思想

我們再通過一個更加實際的例子來理解因子分析的基本思想:

現在假設一個同學的數學、物理、化學、生物都考了滿分,那麼我們可以認爲這個學生的理性思維比較強,在這裏理性思維就是我們所說的一個因子。在這個因子的作用下,偏理科的成績纔會那麼高。

到底什麼是因子分析?就是假設現有全部自變量x的出現是因爲某個潛在變量的作用,這個潛在的變量就是我們說的因子。在這個因子的作用下,x能夠被觀察到。

因子分析就是將存在某些相關性的變量提煉爲較少的幾個因子,用這幾個因子去表示原本的變量,也可以根據因子對變量進行分類

因子分子本質上也是降維的過程,和主成分分析(PCA)算法比較類似。

2種因子分析

因子分析又分爲兩種:

  • 探索性因子分析:不確定在現有的自變量背後到底有幾個因子在起作用,我們通過需要這種方法試圖尋找到這幾個因子
  • 驗證性因子分析:已經假設自變量背後有幾個因子,試圖通過這種方法去驗證一下這種假設是否正確。

模型推導

假設有p個原始的變量x_i(i=1,2,…p),它們之間可能獨立也可能相關。將x_i標準化後得到新的變量z_i,我們可以建立如下的因子分析模型:

z_{i}=a_{i 1} F_{1}+a_{i 2} F_{2}+\cdots+a_{i m} F_{m}+c_{i} U_{i} (i=1,2, \cdots, p)

其中,我們可以定義以下幾個術語:公共因子、特殊因子、載荷因子、載荷矩陣

1、第一點:F_j(j=1,2,…m)出現在每個變量的式子中且m<p,稱之爲公共因子

2、第二點:U_i(i=1,2,…p)僅僅與變量z_i相關,稱之爲特殊因子

3、第三點:係數a_{ij}、c_i(i=1,2…p,j=1,2,…m)稱之爲載荷因子

4、第四點:A={(a_{ij})}稱之爲載荷矩陣

上面的式子可以表示爲:z=AF+CU

同時也就滿足:

z=\left(z_{1}, z_{2}, \cdots, z_{p}\right)^{T}, F=\left(F_{1}, F_{2}, \cdots, F_{m}\right)^{T}, U=\left(U_{1}, U_{2}, \cdots, U_{p}\right)^{T} A=\left(a_{i j}\right)_{p \times m}, \quad C=\operatorname{diag}\left(c_{1}, c_{2}, \cdots, c_{p}\right)

我們通常需要對上述模型的進行假設:

1.各個特殊因子以及特殊因子和公共因子之間相互獨立,即滿足:

\left\{\begin{array}{l}\operatorname{Cov}(U)=\operatorname{diag}\left(\sigma_{1}^{2}, \sigma_{2}^{2}, \cdots, \sigma_{p}^{2}\right) \\ \operatorname{Cov}(F, U)=0\end{array}\right.

2、各公共因子都是均值爲0、方差爲1的獨立正態隨機變量,其協方差矩陣爲單位矩陣I_m,即F-N(0,I_m)

3、m個公共因子對第i個變量方差的貢獻稱之爲第i貢獻度,記爲h_i^2

h_{i}^{2}=a_{i 1}^{2}+a_{i 2}^{2}+\cdots+a_{i m}^{2}

4、特殊因子的方差稱之爲特殊方差或者特殊值\sigma_{i}^{2},i=1,2,3…p

5、第i個變量的方差分解爲:\operatorname{Var} z_{i}=h_{i}^{2}+\sigma_{i}^{2}, i=1,2, \cdots, p

具體的模型推導過程:https://blog.csdn.net/qq_29831163/article/details/88901245

因子載荷矩陣的重要性質

關於因子載荷矩陣的幾個重要性質:

1、因子載荷a_{ij}是第i個變量與第j個公共因子的相關係數,反映的是第i個變量和第j個公共因子之間的重要性。絕對值越大,表示相關性的密切程度越高

2、貢獻度的統計意義

h_{i}^{2}=a_{i 1}^{2}+a_{i 2}^{2}+\cdots+a_{i m}^{2}=\sum_{i=1}^ma_{ij}^2

說明:變量X_i的貢獻度就是因子載荷矩陣的第i行的元素的平方和

上式兩邊同時求方差:

\operatorname{Var}\left(X_{i}\right)=a_{i 1}^{2} \operatorname{Var}\left(F_{1}\right)+\cdots+a_{i m}^{2} \operatorname{Var}\left(F_{m}\right)+\operatorname{Var}\left(\varepsilon_{i}\right)

也就是:1=\sum_{j=1}^{m} a_{i j}^{2}+\sigma_{i}^{2}

可以看出來:公共因子和特殊因子對變量X_i的貢獻度之和爲1。如果\sum_{i=1}^ma_{ij}^2非常接近1,則\sigma^2非常小,則因子分析的效果非常好。

3、公共因子F_{j}方差貢獻的統計意義

因子載荷矩陣中各列元素的平方和 S_j=\sum_{i=1}^p a_{ij}^2成爲F_(j)對所有的X_j的方差貢獻和,衡量F_j的相對重要性。

因子分析步驟

應用因子分析法的主要步驟如下:

  • 對所給的數據樣本進行標準化處理
  • 計算樣本的相關矩陣R
  • 求相關矩陣R的特徵值、特徵向量
  • 根據系統要求的累積貢獻度確定主因子的個數
  • 計算因子載荷矩陣A
  • 最終確定因子模型

factor_analyzer庫

利用Python進行因子分析的核心庫是:factor_analyzer

pip install factor_analyzer

這個庫主要有兩個主要的模塊需要學習:

  • factor_analyzer.analyze(重點)
  • factor_analyzer.factor_analyzer

官網學習地址:https://factor-analyzer.readthedocs.io/en/latest/factor_analyzer.html

案例實戰

下面通過一個案例來講解如何進行因子分析。

導入數據

本文中使用的數據是公開的數據集,下面是數據的介紹和下載地址:

這個數據集收集了2800個人關於人格的25個問題。同時這些數據和隱藏的5個特徵相關,

Big Five Model is widely used nowadays, the five factors include: neuroticism,extraversion,openness to experience,agreeableness and conscientiousness.

特徵之間的對應關係爲:

  • 認同性:agree=c(“-A1”,“A2”,“A3”,“A4”,“A5”)
  • 勤奮的、有責任的:conscientious=c(“C1”,“C2”,“C3”,“-C4”,“-C5”)
  • 外向的:extraversion=c(“-E1”,“-E2”,“E3”,“E4”,“E5”)
  • 神經質、不穩定性:neuroticism=c(“N1”,“N2”,“N3”,“N4”,“N5”)
  • 開放的:openness = c(“O1”,“-O2”,“O3”,“O4”,“-O5”)

事先我們並不知道這些隱形變量的對應關係,所以想要通過因子分析來找到25個變量後面的隱藏變量。下面開始進行因子分析的實戰過程:

導入庫

導入數據處理和分析所需要的庫:

# 數據處理
import pandas as pd
import numpy as np

# 繪圖
import seaborn as sns
import matplotlib.pyplot as plt
# 因子分析
from factor_analyzer import FactorAnalyzer

數據探索

數據信息

首先我們先導進數據:總共是2800條數據,28個特徵屬性

df = pd.read_csv("bfi.csv", index_col=0).reset_index(drop=True)
df

查看下數據的缺失值情況:大部分的字段都是存在缺失值的

數據預處理

數據預處理包含去除3個無效的字段(對分析沒有任何作用:age、gender、education),同時去掉存在空值的數據:

#  去掉無效字段
df.drop(["gender","education","age"],axis=1,inplace=True)
# 去掉空值
df.dropna(inplace=True)

充分性檢測

在進行因子分析之前,需要先進行充分性檢測,主要是檢驗相關特徵陣中各個變量間的相關性,是否爲單位矩陣,也就是檢驗各個變量是否各自獨立。通常是兩種方法:

  • Bartlett's球狀檢驗(巴特利球形檢驗)
  • KMO檢驗

Bartlett's球狀檢驗

檢驗總體變量的相關矩陣是否是單位陣(相關係數矩陣對角線的所有元素均爲1,所有非對角線上的元素均爲零);即檢驗各個變量是否各自獨立。

如果不是單位矩陣,說明原變量之間存在相關性,可以進行因子分子;反之,原變量之間不存在相關性,數據不適合進行主成分分析

from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity

chi_square_value, p_value = calculate_bartlett_sphericity(df)
chi_square_value, p_value

# 結果
(18170.96635086924, 0.0)

我們發現統計量p-value的值爲0,表明變量的相關矩陣不是單位矩陣,即各個變量之間是存在一定的相關性,我們就可以進行因子分析。

KMO檢驗

檢查變量間的相關性和偏相關性,取值在0-1之間;KOM統計量越接近1,變量間的相關性越強,偏相關性越弱,因子分析的效果越好。

Kaiser-Meyer-Olkin (KMO) Test measures the suitability of data for factor analysis. It determines the adequacy for each observed variable and for the complete model.

KMO estimates the proportion of variance among all the observed variable. Lower proportion id more suitable for factor analysis. KMO values range between 0 and 1. Value of KMO less than 0.6 is considered inadequate.

通常取值從0.6開始進行因子分析

from factor_analyzer.factor_analyzer import calculate_kmo
kmo_all,kmo_model=calculate_kmo(df)
kmo_all

KMO大於0.6,也說明變量之間存在相關性,可以進行分析。

選擇因子個數

在數據說明中,我們已經知道了這些變量是和5個隱藏的因子相關。但是很多情況下,我們並不知道這個個數,需要自己進行探索。

方法:計算相關矩陣的特徵值,進行降序排列

特徵值和特徵向量

faa = FactorAnalyzer(25,rotation=None)
faa.fit(df)

# 得到特徵值ev、特徵向量v
ev,v=faa.get_eigenvalues()

可視化展示

我們將特徵值和因子個數的變化繪製成圖形:

 # 同樣的數據繪製散點圖和折線圖
plt.scatter(range(1, df.shape[1] + 1), ev)
plt.plot(range(1, df.shape[1] + 1), ev)

# 顯示圖的標題和xy軸的名字
# 最好使用英文,中文可能亂碼
plt.title("Scree Plot")  
plt.xlabel("Factors")
plt.ylabel("Eigenvalue")

plt.grid()  # 顯示網格
plt.show()  # 顯示圖形

從上面的圖形中,我們明確地看到:選擇5個因子是最合適的

建模

因子分析-fit

我們選擇5個因子來進行因子分子的建模過程,同時指定矩陣旋轉方式爲:方差最大化

ratation參數的其他取值情況:

  • varimax (orthogonal rotation)
  • promax (oblique rotation)
  • oblimin (oblique rotation)
  • oblimax (orthogonal rotation)
  • quartimin (oblique rotation)
  • quartimax (orthogonal rotation)
  • equamax (orthogonal rotation)

查看因子方差-get_communalities()

上面執行fit建模後,我們查看每個因子的方差,使用方法:get_communalities()

查看特徵值-get_eigenvalues

查看變量的特徵值:

查看成分矩陣-loadings

現在有25個變量,5個隱藏變量(因子),查看它們構成的成分矩陣:

如果轉成DataFrame格式,index就是我們的25個變量,columns就是指定的5個因子factor。轉成DataFrame格式後的數據:

查看因子貢獻率-get_factor_variance()

通過理論部分的解釋,我們發現每個因子都對變量有一定的貢獻,存在某個貢獻度的值,在這裏查看3個和貢獻度相關的指標:

  • 總方差貢獻:variance (numpy array) – The factor variances
  • 方差貢獻率:proportional_variance (numpy array) – The proportional factor variances
  • 累積方差貢獻率:cumulative_variances (numpy array) – The cumulative factor variances

隱藏變量可視化

爲了更直觀地觀察每個隱藏變量和哪些特徵的關係比較大,進行可視化展示,爲了方便取上面相關係數的絕對值:

然後我們通過熱力圖將係數矩陣繪製出來:

# 繪圖

plt.figure(figsize = (14,14))
ax = sns.heatmap(df1, annot=True, cmap="BuPu")

# 設置y軸字體大小
ax.yaxis.set_tick_params(labelsize=15)
plt.title("Factor Analysis", fontsize="xx-large")

# 設置y軸標籤
plt.ylabel("Sepal Width", fontsize="xx-large")
# 顯示圖片
plt.show()

# 保存圖片
# plt.savefig("factorAnalysis", dpi=500)

轉成新變量-transformn

上面我們已經知道了5個因子比較合適,可以將原始數據轉成5個新的特徵,具體轉換方式爲:

轉成DataFrame格式後數據展示效果更好:仍然是2436條數據,5個特徵(新特徵)

至此,我們完成了如下的工作:

  1. 原數據的相關性檢測
  2. 因子個數的探索
  3. 因子分析的建模過程
  4. 隱藏變量的可視化
  5. 轉成基於5個新變量的數據

參考資料

1、Factor Analysis:https://www.datasklr.com/principal-component-analysis-and-factor-analysis/factor-analysis

2、多因子分析:https://mathpretty.com/10994.html

3、factor_analyzer package的官網使用手冊:https://factor-analyzer.readthedocs.io/en/latest/factor_analyzer.html

4、淺談主成分分析和因子分析:https://zhuanlan.zhihu.com/p/37755749

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章