因子分析

所要時間

100分

学ぶコト

・因子分析の概要
・因子分析をPythonで実装

主成分分析と似た手法であり、教師なし学習の1種である因子分析。

そんな因子分析の概要とPython実装方法を見ていきましょう!

因子分析をPythonで実装していこう!

それでは実際に因子分析をPythonで実装していきましょう!

まず以下のようにあらかじめ因子分析のライブラリをインストールしておいてください!

!pip install factor_analyzer

続いて、以下のように各種ライブラリをインポートしていきましょう!

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from factor_analyzer import FactorAnalyzer
from sklearn.datasets import load_wine
from sklearn.preprocessing import StandardScaler

今回も先ほど主成分分析の際に利用したワインのデータを扱っていきます。

データセットをインポートして標準化を進めていきます。

# データセット読み込み
wine = load_wine()
df = pd.DataFrame(wine.data, columns=wine.feature_names)
scaler = StandardScaler()
df_scale = scaler.fit_transform(df)
df_scale = pd.DataFrame(df_scale)
display(df_scale)

続いて相関行列を求めて固有値という指標を計算していきます。まずはコードを書いていきましょう!以下のようになります。

# 相関行列を求める
df_scale_corr = df_scale.corr()

# 固有値を求める
ev = np.linalg.eigvals(df_scale_corr)
ev

結果は以下のようになりました。

固有値は、因子分析で背後に存在すると考えられる因子それぞれの影響度の度合いを表しています。

固有値の大きい順に第1因子、第2因子、第3因子・・・となっており、何個目の因子まで含めれば全体をある程度説明できるのか確かめる必要があります。

一旦この配列をソートしてあげましょう(既にソートされているように見えるのですが、されていません)。

ev_sorted = sorted(ev, reverse=True)

そしてこのソートした固有値を元に以下のように記述して、何個の因子まで含めれば全体の何%ほどを説明できそうか見ていきましょう!

ev_ratio = ev_sorted / np.array(ev_sorted).sum()
np.cumsum(ev_ratio)

これを見ると第1因子で36%、第2因子までで55%、第3因子までで66%まで説明できることが分かります。

一旦第3因子まで因子負荷量という指標を計算していきます。以下のように計算することが可能です。

fa = FactorAnalyzer(n_factors=3)
fa.fit(df_scale)
loadings_df = pd.DataFrame(fa.loadings_, columns=["第1因子", "第2因子", "第3因子"])
loadings_df.index = df.columns
loadings_df

主成分分析の際のコードと見比べてみると似ているのが分かると思います。

固有値計算や因子の計算はこういうものだと覚えてしまいましょう。大事なのは因子分析をする意味やどんなアウトプットが得られるかを知っておくことです。丸暗記する必要はないので必要な時に調べて実行できるようになっておいてください。

結果は以下のようになりました。

この因子負荷量は、まさに主成分負荷量の因子分析バージョンと捉えていただいて問題ないです。

これを見ることで第1因子、第2因子、第3因子に対してどのように各変数が影響しているか見ることができるのです!

実際に見てみると、前のレッスンで主成分分析の際にも確認したように以下の変数が突出して高いことが分かります。

・total_phenols
・flavanoids
・od280/od315_of_diluted_wines

こちらはまさに重厚な赤ワインか否かを判断する因子ということになりそうですね。

最後にそれぞれのデータに対する第1因子の因子スコアを計算して、どのデータの第1因子が大きいのか見ていきましょう!

以下のようにコードを記述してください。

# 因子スコアを計算
factor_scores = fa.transform(df_scale)

# 第1因子だけ取り出す(0列目)
df_first_factor = pd.DataFrame(factor_scores[:, 0], columns=["第1因子スコア"])
print(df_first_factor)

まず、factor_scores = fa.transform(df_scale)の箇所で因子スコアを計算し、それを元に最初の要素だけ取り出して第1因子の情報だけ出力しています。

結果は以下のようになりました。

前半のワインは第1因子の因子スコアが正の方向に強くなっているので、重厚感・渋みのある赤ワインだと思われます。

一方で後半の方は、スッキリ飲める白ワインだと考えられますね!

数学的に理解しようとすると少々難易度が高いのでここでは省略しています。

動画でも解説しましたが、基本的に変数を集約して次元圧縮を行いたい時は主成分分析、変数の根本にある共通因子を探りたい時は因子分析を行うとよいでしょう!

変数が多すぎる時や、変数間の関係に着目してデータの構造を紐解きたい時は、これらのアプローチを検討してみましょう!

課題

第2因子や第3因子がどんな傾向を判断する因子になっているか見てみよう!

ここまでで機械学習の手法について網羅的に学んできました。

続いては「07.機械学習実装」コース!

ここからは機械学習を実践的に扱っていくコースに入っていきます!