はちみつブログ

趣味や生活の話を好きなタイミングで書いていきたいと思います。

因子分析と主成分分析について

前回の残りのポイントとして、回転をあげた。因子分析の基本、因子分析らしさが回転だと思う。

回転を考える上で個人的に大事と思っているのが、主成分分析と因子分析の違いだ。完全に個人の思想なので、一般的な違い、正しい違いについては、検索なりAIなりに書いて出てくる「主成分分析は観測変数の集約、因子分析は背後の因子を求める。思想が違う。」的なものを調べてもらえればと思う。ここから先は完全に自分向けの、まあ他の人で同じようにつまづいている人の参考になればいいな、くらいのチラ裏だと思ってもらえればと思う。

ということで、回転の内容は今後に回すとして、今回は主成分分析と因子分析の違いの個人的見解、は言い過ぎで自分を納得させるための考え方を書いていこうと思う。

はじめに結論

はじめに結論だが「因子分析は主成分分析の解を含む、より広い解空間を対象としている」と理解することにした。

主成分分析も因子分析も、何も制約がないと解が求めづらい分析の数式となっている。そこで、いろいろな制約をかけて解を求めていくのだが、主成分分析の方が因子分析よりも制約が厳しいと思う。

概念的に

次に概念的に先ほどの「因子分析は主成分分析の解を含む、より広い解空間を対象としている」を考えたいと思う。

概念といいつつ、具体例を使いながら、何を目指してるんだっけ?というところを確認しようと思う。今回は単純化のために2変数の主成分分析と因子分析を考えてみようと思う。

前回の成績データのうち、算数と理科を使おうと思う。もともと同じ因子から算出することとしているので、かなり相関が見られると思う。

import matplotlib.pyplot as plt
import japanize_matplotlib
import pandas as pd

# データの読み込み
df = pd.read_csv("../../01_factor-analysis/data/factor_analysis_test_data.csv", index_col=0)

# 算数と理科のデータを抽出
math_science = df[["算数", "理科"]]

# 算数と理科の散布図を描画
plt.figure(figsize=(8, 6))
plt.scatter(math_science["算数"], math_science["理科"], alpha=0.5)
plt.title("算数と理科の散布図")
plt.xlabel("算数")
plt.ylabel("理科")
plt.grid() # グリッドを表示
plt.savefig("../fig/02_org_scatter.png", dpi=300, bbox_inches='tight') # 保存する場合
# plt.show() # 表示する場合

改めて、散布図を書いてみると、よく相関している。というか理科0点の人いるな…笑

後処理など数式を解こうと思った際も楽になるので、データの標準化をしておく。数式の展開はあまり議論する気がない(というか自信がない)が…

# データを標準化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
math_science_scaled = scaler.fit_transform(math_science)

# 標準化後のデータをDataFrameに変換
math_science_scaled = pd.DataFrame(math_science_scaled, columns=["算数", "理科"], index=math_science.index)

# 標準化後の算数と理科の散布図を描画
plt.figure(figsize=(8, 6))
plt.scatter(math_science_scaled["算数"], math_science_scaled["理科"], alpha = 0.5)
plt.title("標準化後の算数と理科の散布図")
plt.xlabel("算数 (標準化後)")
plt.ylabel("理科 (標準化後)")
plt.grid() # グリッドを表示
plt.savefig("../fig/03_scaled_scatter.png", dpi=300, bbox_inches='tight') # 保存する場合
plt.show() # 表示する場合

ここに主成分でも、因子でも良いのだが、要約できそう or 背後にありそうな線を1本引くと考えると、こんな感じだと思う。

で、正直この時点では、で主成分分析と因子分析の違いを感じないし、「要約する」のと「背後にある」のと何が違うんだろか…というのが自分の正直なところだった。

主成分分析の場合

ここからはそれぞれを細かく見ていくとして、まずは主成分分析の方を考える。

数式にすると以下を求めることになる。 $n$ 個の観測変数 $x_{n}$ から主成分 $t_{n}$ を考えるとして、

$$ \begin{align} t_{1} = w_{11}x_{1} + w_{12}x_{2} + ... + w_{1n}x_{n} \\ t_{2} = w_{21}x_{1} + w_{22}x_{2} + ... + w_{2n}x_{n} \\ ... \\ t_{n} = w_{n1}x_{1} + w_{n2}x_{2} + ... + w_{nn}x_{n} \end{align} $$

ここでは $t_{1}$, $x_{1}$がベクトル、$w_{11}$とかは数値。

今回の例で言うと、

$$ \begin{align} t_{1} = w_{11}x_{算数} + w_{12}x_{理科} \\ t_{2} = w_{21}x_{算数} + w_{22}x_{理科} \\ \end{align} $$

を考えることになる。 $x_{算数}$ は算数の100人分の点数のベクトルとなっている。

この時、 $t_{1}$と$t_{2}$ が主成分となるとのことだが、 $||w_{1}|| = ||w_{2}|| = 1$ と言う条件の中で、その時その時の分散が最大な順に $t_{1}$ と $t_{2}$ を求めるよ、と言うこととなっている。まあ、なるべく単独の $t_{1}$ で説明することを目指して第1主成分を求めて、次に残りからなるべく説明ができる $t_{2}$ を探すよ、と言うこと。

例えば、$w_{11} = 1, w_{12} = 0$ と $w_{21} = 0, w_{22} = 1$ は条件を満たすが、$t_1$ が算数軸、$t_2$ が理科軸で、理解はしやすいが、どうにか $t_1$ で最大限説明するように…と言うことを満たしていない。

ここでポイントは主成分を考えると変数と同じ数、今回の例だと第2主成分まであるということ。そして、解く順もあり、第1主成分の次に、直交する第2主成分を求める形になるかと思う。(実際には固有値などで解けるようで、一気に解けるように見えるかもだが…)

求め方もいろいろあると思うのだが、大学で理系だった人は実験などを通して、最小二乗法をやったことがあるのではないかと思う。その応用を考えると似ていて、切片が0で1次の式での最小二乗法とほぼ同じ結果になるはず。情報量を最大にするため、分散を最大にみたいなのが基本ではあるのだが、逆にみると残差、距離を最小化することと等価だと自分は理解している。

今回2次元の例でやっているが同じことで、何次元あろうと、もっともそれっぽい軸、直線は引けると思う。そして、直線に直行する面を新しく用意して、各点をそちらに射影したものをもとに新しい軸を取って行けば、おおむね主成分分析のやりたいことと一致するはずだ。求め方についてはこちらにも似たような解説があった。

これを一気にやるのが相関行列の対角化らしい。ここは自分の中に落とし込めていないので、省略するが…要は適切な制限の中で答えが求まる、ということかと思う。

因子分析の場合

一方、因子分析は加える制限が違う、というか素の状態だと答えが決まらないので、回転などで制限を加えて答えを決める、のではないかと自分は理解した。

数式的には $n$ 個の観測変数があり、 $ m $ 個の因子からなるとして、こんな感じだと思う。

$$ \begin{align} x_{1} = \lambda_{11} f_{1} + \lambda_{12} f_{2} + ... +\lambda_{1m} f_{m} + \varepsilon_{1} \\ x_{2} = \lambda_{21} f_{1} + \lambda_{22} f_{2} + ... +\lambda_{2m} f_{m} + \varepsilon_{2} \\ ... \\ x_{n} = \lambda_{n1} f_{1} + \lambda_{n2} f_{2} + ... +\lambda_{nm} f_{m} + \varepsilon_{n} \end{align} $$

先ほどと同様で、 $x_{1}$や $f_{1}$ 、 $\varepsilon_{1}$はベクトル、 $\lambda_{11}$は数値。基本的に $n > m$ で $=$ が入るのか調べてもあまり出てこなかった。先ほどの主成分分析は $n$ 個の観測変数に対して、 $n$ 個の主成分を考えるので、そこは確実に違うところと思う。

今回の例で言うと、因子はとりあえず1つとして

$$ \begin{align} x_{算数} = \lambda_{算数1} f_{1} + \varepsilon_{算数}\\ x_{理科} = \lambda_{理科1} f_{1} + \varepsilon_{理科} \end{align} $$

となるか。

よくある説明としては、観測変数を左辺に置くのが因子分析で、観測変数は右辺に置くのが主成分分析だ、というもののがある。ただ、それと同様に多いのが、式変形をすると結局同様の問題を解いているので答えが似る、というものだ。自分としてはここでうーーんとなってしまった。完全個人の感想だが…

一方で、自分の理解の「因子分析は主成分分析の解を含む、より広い解空間を対象としている」のベースとなる式の理解としては2つあり、1つ目が $\varepsilon$で、2つ目が $f_{1}$ 〜 $f_{m}$ に順位がないということ。

1つ目の $\varepsilon$ については、これにより解の自由度が増していると思う。もちろん、 $\varepsilon$ は「"誤差"で最小にしなくてはならない」場合、ほぼ主成分分析なのだが、必ずしもそうは書いていないものも多く(書いているものもあるが…)、 $\varepsilon$ は「"誤差"ではなく"独自因子"だ」と書いてあるものも多い。要は必ずしも最小にしなくても良いように思う、そう思うとめちゃくちゃ自由度が高くなると思う。

例えば、因子として算数の点数をそのまま表すようなものを考えた場合、理科の分は全く表せなくなってしまうので、独自因子の方で理科の点数を表すことになるだろう。つまり $\varepsilon_{算数} = 0$ で、 $\varepsilon_{理科} = x_{理科}$ みたいな感じだと思う。そして、これが許されるのが因子分析なのではないかと思う。自分の解釈が間違っているのかもしれないが…

2つ目の $f_{1}$ 〜 $f_{m}$ に順位がないも同様で、今回2つしか観測変数を用意していないので書きづらいが…主成分分析は明確に主成分に順番があるが、因子分析は因子に順番がない。かつ、必ずしも直行を守る必要もない(平行でなければいいのだろう…)。

完全にイメージで数学的には間違っていると思うが、図のように直交ではない因子も許されて、順番もないのだと思う。

こうなると、正直問題=因子分析が解けない、と言うのが正直なところだと思う。なんでもありなので。

そこで出てくる解き方の流れが、とりあえず $\varepsilon$ も最小としましょう、因子も $f_{1}$ から順に求めましょう(≒主成分分析しましょう)。そして、初期解を求めた後に回転しましょう。回転には直交回転も斜交回転も許しましょう。なのだと、自分は解釈した。間違っている気もめちゃくちゃするのだが、自分を納得させるためなので、まあいいか、と思っている。

まとめ

今回は因子分析の回転へ向けて(とはいえ回転の話はほぼ0だが)、因子分析と主成分分析の違いについて自分の思うところをまとめた。正直、数学的には間違いだらけだろうなと思う笑 ただ、まあ何かしらの参考になれば良いな、と今後回転を勉強していくので、適宜自分の認識の間違いも出てくれば修正していきたいと思う。

今後に向けて、まずは今回書いた図がPythonで書いてしまったので、せっかくRも勉強しはじめたし、Rでも書いてみようかと思っている。そして、回転の話へ移り、主成分分析の解や因子分析の回転無しの解、回転した解、と比較していきたいと思う。回転を先にと思っているが、そこからだんだんと因子数の決め方の話などへも移っていければと思っている。

参考文献

更新履歴

  • 2025/08/02: 公開
  • 2025/08/08: 数式の記法を修正