Python Scikit-learnの因子分析はPCAと何が違う?理論と実装コードで徹底比較

Python

はじめに – 因子分析とPCA、違いを説明できますか?

データ分析の世界に足を踏み入れると、**因子分析(Factor Analysis, FA)主成分分析(Principal Component Analysis, PCA)**という、よく似た二つの手法に出会います。どちらも「たくさんの変数をより少ない指標にまとめる」という点で共通しており、「この二つ、何が違うの?」と疑問に思ったことがある方も多いのではないでしょうか。

実際に、これらは目的も背景にある理論も全く異なるアプローチです。この違いを理解しないまま何となく使ってしまうと、誤った解釈や分析結果につながる可能性もあります。

ご安心ください。この記事を最後まで読めば、あなたは以下の状態になれます。

  • 因子分析とPCAの理論的な違いが、図や言葉で明確に説明できるようになる。
  • PythonのScikit-learnを使い、両方の手法を実装できるようになる。
  • 自分の分析目的に合わせて、どちらの手法を選ぶべきか判断できるようになる。

理論と実践の両面から、この永遠のテーマに終止符を打ちましょう!


まずは基本から!因子分析(Factor Analysis)とは?

まずは因子分析(FA)の基本を押さえましょう。一言で言うと、観測データそのものではなく、その背後にある構造に焦点を当てる手法です。

目的:観測データの背後にある「共通因子」を見つけること

因子分析の最大の目的は、直接観測できない潜在的な変数(共通因子)を発見することです。

例えば、顧客満足度アンケートで「接客の丁寧さ」「商品の品質」「価格の満足度」「店舗の清潔さ」「アフターサービスの充実度」といった項目を調査したとします。これらの観測データの背後には、おそらく「サービス品質」や「コストパフォーマンス」といった、より大きな概念(共通因子)が存在するはずです。

このように、観測された変数群がなぜ互いに相関するのかを、共通の要因で説明しようとするのが因子分析の核心です。

モデルの考え方:データは”共通因子”と”独自因子”から作られる

因子分析では、観測データは**「共通因子」「独自因子」**の二つから成り立っていると考えます。

観測データ=共通因子(全変数に影響)+独自因子(特定変数のみに影響する誤差など)

先ほどの例で言えば、「接客の丁寧さ」という観測データは、「サービス品質」という共通因子の影響を受けつつ、「その日の担当者によるブレ」といった独自因子の影響も受けている、とモデル化します。この考え方が、PCAとの大きな違いを生む重要なポイントです。


多くの人が使う主成分分析(PCA)とは?

次に、主成分分析(PCA)です。こちらは特に機械学習の前処理などで頻繁に利用される、非常にポピュラーな手法です。

目的:データの情報をなるべく失わずに「次元削減」すること

主成分分析の主な目的は、元のデータが持つ情報を可能な限り維持したまま、変数の数を減らす(次元削減する)ことです。

たくさんの変数(特徴量)があると、モデルの計算コストが上がったり、過学習の原因になったりします。PCAを使えば、例えば100個ある変数を、元の情報の95%を保持した3個の「主成分」という新しい変数に要約できます。

これにより、データの可視化が容易になったり、機械学習モデルの精度が向上したりといったメリットがあります。あくまで情報を効率よく要約することがゴールです。

モデルの考え方:データを最もよく表す”新しい軸(主成分)”を作る

主成分分析では、既存の観測変数の線形結合(足し合わせ)によって、新しい変数(主成分)を作り出します

主成分=w1​×変数1​+w2​×変数2​+…

このとき、新しい軸(主成分)は、データのばらつき(分散)が最も大きくなる方向に次々と作られていきます。第1主成分が最も多くの情報を持つ軸、第2主成分が第1主成分と直交する中で次に多くの情報を持つ軸…といった具合です。元の変数の情報をすべて使って、新しい代表変数を作り出すイメージです。


【本題】理論で比較!因子分析とPCAの決定的的な違い

基本を理解したところで、いよいよ本題です。両者の違いを3つのポイントで徹底的に比較します。

違い①:分析の目的(潜在的な構造 vs 情報の要約)

これが最も本質的な違いです。

  • 因子分析:観測変数の原因となる共通因子を探り、背景にある構造を解釈するのが目的。
  • 主成分分析:観測変数の情報を要約し、次元削減や可視化を行うのが目的。
因子分析 (FA)主成分分析 (PCA)
目的潜在構造の発見、原因の解釈情報の要約、次元削減
問いなぜこれらの変数は相関するのか?どうすれば情報を失わずに要約できるか?

違い②:モデルの仮定(誤差の扱いが異なる)

分析モデルの前提も大きく異なります。

  • 因子分析:「独自因子」という形で、各変数に固有の誤差の存在を明確に仮定します。共通因子で説明できない部分を考慮に入れます。
  • 主成分分析:明確な誤差モデルを持ちません。観測データのすべてのばらつき(分散)を主成分で説明しようと試みます。

この違いにより、因子分析は変数の共分散構造に注目し、主成分分析は全体の分散構造に注目するという差が生まれます。

違い③:矢印の向きで理解する関係性

モデルの違いを視覚的に理解するには、「矢印の向き」をイメージするのが一番です。

  • 因子分析共通因子 → 観測変数
    • (「サービス品質」という因子が、「接客の丁寧さ」や「アフターサービス」という観測データに影響を与える)
  • 主成分分析観測変数 → 主成分
    • (「接客の丁寧さ」や「アフターサービス」などの観測データを合成して、「総合満足度スコア」という主成分を作り出す)

原因から結果へと向かうのが因子分析、結果から要約へと向かうのが主成分分析と覚えると分かりやすいでしょう。


Scikit-learnで実装!コードと結果で違いを比較する

理論の違いを理解したところで、今度はPythonのScikit-learnを使って実際にデータを動かし、結果の違いを見ていきましょう。

準備:ライブラリのインポートとサンプルデータの用意

まず、必要なライブラリと、サンプルとして有名なアヤメ(iris)のデータセットを読み込みます。スケールを揃えるために標準化も行っておきましょう。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Scikit-learnのライブラリ
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import FactorAnalysis, PCA

# データの読み込み
iris = load_iris()
X = iris.data
feature_names = iris.feature_names

# データを標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 分かりやすいようにDataFrameに変換
df = pd.DataFrame(X_scaled, columns=feature_names)

print(df.head())

Scikit-learnによる因子分析(FactorAnalysis)の実装

FactorAnalysisクラスを使って因子分析を実行します。ここでは、背後にある共通因子を2つと仮定してn_components=2と設定します。

# 因子分析の実行
# n_componentsで因子数を指定
n_factors = 2
fa = FactorAnalysis(n_components=n_factors, random_state=42)
fa.fit(df)

# 因子負荷量を取得
# fa.components_で行列の転置(.T)を行うと解釈しやすい
fa_loadings = pd.DataFrame(fa.components_.T, 
                           index=feature_names, 
                           columns=[f'Factor {i+1}' for i in range(n_factors)])

print("--- 因子分析の結果(因子負荷量) ---")
print(fa_loadings)

因子負荷量は、各観測変数が共通因子からどれくらい影響を受けているかを示す指標です。この値が高いほど、その因子との関連が強いことを意味します。

Scikit-learnによる主成分分析(PCA)の実装

同様にPCAクラスで主成分分析を実行します。比較のために、こちらも2つの主成分を抽出します。

# 主成分分析の実行
# n_componentsで主成分の数を指定
n_components = 2
pca = PCA(n_components=n_components, random_state=42)
pca.fit(df)

# 主成分負荷量を取得
# 主成分負荷量 = 主成分ベクトル * (対応する固有値の平方根)
pca_loadings = pd.DataFrame(pca.components_.T * np.sqrt(pca.explained_variance_),
                            index=feature_names,
                            columns=[f'PC {i+1}' for i in range(n_components)])

print("--- 主成分分析の結果(主成分負荷量) ---")
print(pca_loadings)

主成分負荷量は、各観測変数が主成分とどれくらい相関があるかを示す指標です。


結果の解釈と実践的な使い分け

実装しただけでは終わりません。結果をどう解釈し、どう使い分けるかが重要です。

可視化して比較:因子負荷量と主成分負荷量の違い

得られた負荷量をヒートマップで可視化すると、違いがより直感的に理解できます。

# 結果を可視化して比較
fig, axes = plt.subplots(1, 2, figsize=(12, 6))

# 因子負荷量のヒートマップ
sns.heatmap(fa_loadings, annot=True, cmap='coolwarm', ax=axes[0])
axes[0].set_title('Factor Analysis Loadings')

# 主成分負荷量のヒートマップ
sns.heatmap(pca_loadings, annot=True, cmap='coolwarm', ax=axes[1])
axes[1].set_title('Principal Component Loadings')

plt.tight_layout()
plt.show()

この可視化結果を見ると、似たような傾向を示しつつも、各変数の重み付けが微妙に異なることが分かります。因子分析は共通性を、主成分分析は分散を最大化しようとするため、このような違いが生まれます。

結局どっちを使うべき?目的別の使い分けシナリオ

最後の疑問、「結局、いつどっちを使えばいいの?」にお答えします。すべてはあなたの分析目的次第です。

因子分析が適しているシナリオ

  • 目的: データの背後にある潜在的な構造や心理的な構成概念を理解したい。
  • :
    • アンケート結果から、顧客が商品を評価する上での「デザイン性」「機能性」「価格」といった評価軸を抽出したい。
    • 複数の性格テストの項目から、根底にある「外向性」「協調性」などのパーソナリティ因子を特定したい。

主成分分析が適しているシナリオ

  • 目的: データを要約して、可視化や機械学習モデルの入力として使いたい。
  • :
    • 数百次元ある画像の特徴量を、モデルの計算負荷を下げるために10次元に次元削減したい。
    • 多変量データを2次元平面にプロットして、データの分布やクラスタを可視化したい。
    • 多数の経済指標を一つの「総合景気指数」として合成したい。

まとめ:因子分析とPCAを正しく理解して使いこなそう

今回は、混同されがちな因子分析と主成分分析の違いについて、理論からPythonでの実装、使い分けまでを徹底的に解説しました。

最後に、重要なポイントをまとめておさらいしましょう。

  • 目的が違う:因子分析は原因(共通因子)の探求、PCAは情報(分散)の要約
  • モデルが違う:因子分析は誤差(独自因子)を考慮するが、PCAはしない。
  • 矢印の向きが違う:FAは「因子→変数」、PCAは「変数→主成分」。
  • 使い分けが重要:背景構造の解釈ならFA、次元削減や要約ならPCAを選ぶ。

Scikit-learnを使えばどちらの手法も数行のコードで実装できますが、その背景にある理論を理解することで、より深く、そして正しくデータと向き合うことができます。

この記事が、あなたのデータ分析の引き出しを一つ増やし、より適切な手法選択の助けとなれば幸いです。

コメント

タイトルとURLをコピーしました