「入門はじめての多変量解析」をPythonで写経 Vol.17 ~ 4章「はじめての因子分析」②モデル、解釈、因子負荷量
4章「はじめての因子分析」
書籍の著者 石村貞夫 先生、石村光資郎 先生
書籍「入門はじめての多変量解析」4章「はじめての因子分析」の Python写経活動記録 です。
多変量解析の入門を Python と一緒に学ぶ写経シリーズです。
因子分析のうち「探索的因子分析」を取り扱います。
この記事は、因子分析のモデル理解を試みます。
具体的には書籍掲載の パス図、モデル式、共通因子の解釈、因子負荷量のイメージ にチャレンジします。
ChatGPT 活用型学習で進めてまいります!
では書籍を開いて多変量解析の旅に出かけましょう🚀

はじめに
このブログシリーズは、書籍「入門はじめての多変量解析」(東京図書、「テキスト」と呼びます)の Python 写経を通じて得た「多変量解析の楽しさ」をご紹介します。
書籍の紹介と引用表記はリンク先の記事に掲載しています。
4章 はじめての因子分析
この記事は4章の以下のSectionを取り扱います。
4.1 因子分析で共通要因を?!
4.2 因子分解のモデル式と因子の解釈
4.3 因子分析の分散共分散行列
4.4 主因子法による因子分析
記事に用いるデータは、テキストに掲載されたデータそのものを引用しています。
データ件数の少ないものはコード上でデータを登録し、データ件数の多いものはCSVファイル化してデータを読み込みしています。
この記事で用いるライブラリをインポートします。
### インポート
# 数値計算
import numpy as np
import pandas as pd
# 統計処理
import statsmodels.api as sm
# 描画
import matplotlib.pyplot as plt
from graphviz import Digraph
plt.rcParams['font.family'] = 'Meiryo' # または import japanize_matplotlib
さまざまなパス図
テキストに沿って、「重回帰分析」「主成分分析」「因子分析」のパス図を比べて、因子分析のモデル理解を進めます!
■ 重回帰分析のパス図 p.124
おなじみの重回帰モデルでパス図の見方を確認します。
テキスト p.124 図 4.1.1 に相当します。
graphviz ライブラリの Digraph(有向グラフ)を利用します。
## 重回帰分析のパス図 p.124 図4.1.1
## 設定
# 有向グラフオブジェクトの生成、neatoでnodeの位置調整を実施
g = Digraph(engine='neato')
# graphタイトルの設定
g.attr('graph', label='重回帰分析のパス図', fontname='Meiryo UI')
# nodeの基本属性の設定
g.attr('node', shape='box', fontname='Meiryo UI')
## node:頂点の作成、posで位置固定
g.node('原因x1', pos='0, 2!')
g.node('原因x2', pos='0, 1!')
g.node('原因x3', pos='0, 0!')
g.node('結果y', pos='3, 1!')
g.node('ε', pos='4, 2!', shape='circle')
## edge:辺の作成
g.edge('原因x1', '結果y', label='β1')
g.edge('原因x2', '結果y', label='β2')
g.edge('原因x3', '結果y', label='β3')
g.edge('ε', '結果y')
## グラフの表示
g【実行結果】
以下の重回帰分析のモデル式をパス図に描いています。
説明変数と目的変数の間に因果関係が存在することが前提になっています。
$$
y = \beta_1 x_1 + \beta_2 x_2 + \beta_3 x_3 + \varepsilon
$$

四角形は「観測変数」を示します。
後に登場する楕円形は「潜在変数」(観測できない変数)です。
$${\varepsilon}$$ は誤差です。
偏回帰係数 $${\beta_1, \beta_2, \beta_3}$$ は、各説明変数が目的変数に与える影響を示しています。

■ 主成分分析のパス図
つづいて主成分分析を振り返りつつ、パス図を確認します。
テキスト p.125 図 4.1.2 に相当します。
## 主成分分析のパス図 p.125 図4.1.2
## 設定
# 有向グラフオブジェクトの生成、neatoでnodeの位置調整を実施
g = Digraph(engine='neato')
# graphタイトルの設定
g.attr('graph', label='主成分分析のパス図', fontname='Meiryo UI')
# nodeの基本属性の設定
g.attr('node', shape='box', fontname='Meiryo UI')
## node:頂点の作成、posで位置固定
g.node('要因x1', pos='0, 2!')
g.node('要因x2', pos='0, 1!')
g.node('要因x3', pos='0, 0!')
g.node('主成分z', pos='3, 1!', shape='oval')
## edge:辺の作成
g.edge('要因x1', '主成分z', label='a1')
g.edge('要因x2', '主成分z', label='a2')
g.edge('要因x3', '主成分z', label='a3')
## グラフの表示
g【実行結果】
以下の主成分分析のモデル式をパス図に描いています。
$$
z = a_1 x_1 + a_2 x_2 + a_3 x_3
$$

主成分 $${z}$$ は、変数 $${x_1, x_2, x_3}$$ を総合化して生成された新しい座標軸です。
係数 $${a_1, a_2, a_3}$$ はデータの分散共分散行列(または相関行列)の固有ベクトルです。
係数は各変数が主成分 $${z}$$ の方向づけに与える影響を示しています。

■ 因子分析のパス図
テキスト p.124 図 4.1.3 に相当します。
## 因子分析のパス図 p.125 図4.1.3
## 設定
# 有向グラフオブジェクトの生成、neatoでnodeの位置調整を実施
g = Digraph(engine='neato')
# graphタイトルの設定
g.attr('graph', label='因子分析のパス図', fontname='Meiryo UI')
# nodeの基本属性の設定
g.attr('node', shape='box', fontname='Meiryo UI')
## node:頂点の作成、posで位置固定
g.node('要因x1', pos='1.5, 2!')
g.node('要因x2', pos='1.5, 1!')
g.node('要因x3', pos='1.5, 0!')
g.node('共通因子f', pos='4.5, 1!', shape='oval')
g.node('ε1', pos='0, 2!', shape='circle')
g.node('ε2', pos='0, 1!', shape='circle')
g.node('ε3', pos='0, 0!', shape='circle')
## edge:辺の作成
g.edge('共通因子f', '要因x1', label='a1')
g.edge('共通因子f', '要因x2', label='a2')
g.edge('共通因子f', '要因x3', label='a3')
g.edge('ε1', '要因x1')
g.edge('ε2', '要因x2')
g.edge('ε3', '要因x3')
## グラフの表示
g【実行結果】
以下の因子分析のモデル式をパス図に描いています。
$$
\begin{align*}
x_1 &= a_1 f + \varepsilon_1 \\
x_2 &= a_2 f + \varepsilon_2 \\
x_3 &= a_3 f + \varepsilon_3 \\
\end{align*}
$$

「共通因子 $${f}$$」という潜在変数が、変数 $${x_1, x_2, x_3}$$ に係数 $${a_1, a_2, a_3}$$ の大きさで影響を及ぼしています。
また変数には誤差(独自因子)が含まれます。
主成分分析は「各変数を総合化する:各変数から潜在変数へ」でしたが、因子分析は「各変数が共通の因子に影響される:潜在変数から各変数へ」です。
因子分析は「共通因子」を見出すことが分析の目的になります。
特に係数 $${a_1,a_2, a_3}$$ =因子負荷量の推定が一つのメインイベントになります。
テキストでは因子負荷量の推定方法に「主因子法」と「最尤法」を用いています。

因子分析の例題で因子を解釈する
■ 例題データの概要
テキスト p.126 表 4.1.1、表 4.1.2 のアンケート結果データを用いて、因子分析の例を探ります。
アンケートは3つの項目=要因を5段階で答えるものです。
【項目=要因】
・仕事に集中できる
・疲れが取れない
・イライラする
【回答の5段階】
1:全く当てはまらない
2:あまり当てはまらない
3:どちらともいえない
4:当てはまる
5:とても当てはまる
テキストのアンケート結果データをお借りします。
### アンケート調査の結果 p.126 表4.1.2
# データの登録
data1 = pd.DataFrame(
{'仕事に集中できる_x1': [3, 4, 3, 1, 2, 5, 1, 4, 2, 5],
'疲れがとれない_x2': [1, 1, 4, 4, 5, 2, 5, 2, 3, 3],
'イライラする_x3': [2, 1, 5, 4, 5, 1, 4, 3, 3, 2]},
index=range(1, 11))
data1.index.name = '被験者No.'
# 結果の表示
data1【実行結果】

3項目の相関係数を見てみましょう。
### 相関係数の確認
data1.corr()【実行結果】
「仕事に集中できる」と「疲れが取れない」「イライラする」は負の相関、「疲れが取れない」と「イライラする」は正の相関です。
「仕事に集中できない」に変えると、3つの項目は正の相関関係になりそうです。


■ パス図の描画
3つの要因の背後に潜む「共通因子」をパス図で可視化します。
テキスト p.127 図 4.1.4 に相当します。
## 因子分析のパス図 p.125 図4.1.3
## 設定
# 有向グラフオブジェクトの生成、neatoでnodeの位置調整を実施
g = Digraph(engine='neato')
# graphタイトルの設定
g.attr('graph', label='因子分析のパス図', fontname='Meiryo UI')
# nodeの基本属性の設定
g.attr('node', shape='box', fontname='Meiryo UI')
## node:頂点の作成、posで位置固定
g.node('仕事に集中できるx1', pos='1.5, 2!')
g.node('疲れが取れないx2', pos='1.5, 1!')
g.node('イライラするx3', pos='1.5, 0!')
g.node('共通因子f', pos='4.5, 1!', shape='oval')
g.node('ε1', pos='0, 2!', shape='circle')
g.node('ε2', pos='0, 1!', shape='circle')
g.node('ε3', pos='0, 0!', shape='circle')
## edge:辺の作成
g.edge('共通因子f', '仕事に集中できるx1', label='a1')
g.edge('共通因子f', '疲れが取れないx2', label='a2')
g.edge('共通因子f', 'イライラするx3', label='a3')
g.edge('ε1', '仕事に集中できるx1')
g.edge('ε2', '疲れが取れないx2')
g.edge('ε3', 'イライラするx3')
## グラフの表示
g【実行結果】


■ 因子負荷量の推定
サクッと Python で因子負荷量を求めて、共通因子の解釈に進みます。
statsmodels の Factor を利用します。
### 因子負荷量の算出
# データの標準化 ※標準偏差の分母はN-1
X_std = (data1 - data1.mean()) / data1.std(ddof=1)
# 因子分析の実行
result = sm.multivariate.Factor(X_std, method='pa', smc=True).fit(maxiter=12)
# 因子負荷量の表示
result.summary().tables[7].round(3)【実行結果】
3つの要因の因子負荷量が求まりました。

パス図に因子負荷量を付記しましょう。
テキスト p.129 図 4.2.1 に相当します。
## 因子分析のパス図 p.125 図4.2.1
## 設定
# 有向グラフオブジェクトの生成、neatoでnodeの位置調整を実施
g = Digraph(engine='neato')
# graphタイトルの設定
g.attr('graph', label='共通因子の解釈', fontname='Meiryo UI')
# nodeの基本属性の設定
g.attr('node', shape='box', fontname='Meiryo UI')
## node:頂点の作成、posで位置固定
g.node('仕事に集中できるx1', pos='1.5, 2!')
g.node('疲れが取れないx2', pos='1.5, 1!')
g.node('イライラするx3', pos='1.5, 0!')
g.node('共通因子を解釈すると…', pos='6, 1!', shape='oval')
g.node('ε1', pos='0, 2!', shape='circle')
g.node('ε2', pos='0, 1!', shape='circle')
g.node('ε3', pos='0, 0!', shape='circle')
## edge:辺の作成
g.edge('共通因子を解釈すると…', '仕事に集中できるx1', label='a1=-0.732')
g.edge('共通因子を解釈すると…', '疲れが取れないx2', label='a2=0.889')
g.edge('共通因子を解釈すると…', 'イライラするx3', label='a3=0.955')
g.edge('ε1', '仕事に集中できるx1')
g.edge('ε2', '疲れが取れないx2')
g.edge('ε3', 'イライラするx3')
## グラフの表示
g【実行結果】


■ 共通因子の解釈
仕事の集中度には「強い負の影響」を及ぼし、疲れやイライラの発生・継続には「強い正の影響」を及ぼす「共通因子」とは、いったい何でしょう…?
テキストの解釈例は「やせたいという意識」です。
おそらく、アンケートの他の項目回答や、アンケート外で得た情報から、このような解釈をしたのでしょう。
一般化すると「大きな悩みごとを抱えている」といった解釈でしょうか。
大きな悩みごとを抱えているので、仕事に集中できない(負の影響)
大きな悩みごとを抱えているので、疲れが取れない(正の影響)
大きな悩みごとを抱えているので、イライラする(正の影響)
因子の内容を知るには、様々な情報を用いて「解釈」する必要があります。

因子分析のモデル式
■ 共通因子が2個の場合
いままでは共通因子が1つの例を見てきました。
次に共通因子が2つの場合をパス図で見てみましょう。
テキスト p.128 の図に相当します。
## 共通因子が2個の場合の因子分析のパス図 p.128
## 設定
# 有向グラフオブジェクトの生成、neatoでnodeの位置調整を実施
g = Digraph(engine='neato')
# graphタイトルの設定
g.attr('graph', label='因子分析のパス図:2つの共通因子', fontname='Meiryo UI')
# nodeの基本属性の設定
g.attr('node', shape='box', fontname='Meiryo UI')
## node:頂点の作成、posで位置固定
g.node('要因x1', pos='1.5, 2!')
g.node('要因x2', pos='1.5, 1!')
g.node('要因x3', pos='1.5, 0!')
g.node('共通因子f1', pos='4.5, 1.5!', shape='oval', color='navy')
g.node('共通因子f2', pos='4.5, 0.5!', shape='oval', color='tomato')
g.node('ε1', pos='0, 2!', shape='circle')
g.node('ε2', pos='0, 1!', shape='circle')
g.node('ε3', pos='0, 0!', shape='circle')
## edge:辺の作成
g.edge('共通因子f1', '要因x1', label='a11', color='navy', fontcolor='navy')
g.edge('共通因子f1', '要因x2', label='a21', color='navy', fontcolor='navy')
g.edge('共通因子f1', '要因x3', label='a31', color='navy', fontcolor='navy')
g.edge('共通因子f2', '要因x1', label='a12', color='tomato', fontcolor='tomato')
g.edge('共通因子f2', '要因x2', label='a22', color='tomato', fontcolor='tomato')
g.edge('共通因子f2', '要因x3', label='a32', color='tomato', fontcolor='tomato')
g.edge('ε1', '要因x1')
g.edge('ε2', '要因x2')
g.edge('ε3', '要因x3')
## グラフの表示
g【実行結果】
各要因(変数)は2つの共通因子の影響を受けるようです。

2つの共通因子がある場合のモデル式は次のようになります。
$$
\begin{align*}
x_1 &= a_{11} f_1 + a_{12} f_2 + \varepsilon_1 \\
x_2 &= a_{21} f_1 + a_{22} f_2 + \varepsilon_2 \\
x_3 &= a_{31} f_1 + a_{32} f_2 + \varepsilon_3 \\
\end{align*}
$$

■ モデル式の一般化
因子分析のモデル式を一般化します。
変数の数が $${p}$$ 個、共通因子の数が $${m}$$ 個の場合です。
テキスト p.128 の数式をお借りします。
$$
\begin{align*}
x_1 &= a_{11} f_1 + a_{12} f_2 + \cdots + a_{1m}f_m + \varepsilon_1 \\
x_2 &= a_{21} f_1 + a_{22} f_2 + \cdots + a_{2m}f_m + \varepsilon_2 \\
\quad \vdots \\
x_p &= a_{p1} f_1 + a_{p2} f_2 + \cdots + a_{pm}f_m + \varepsilon_p \\
\end{align*}
$$
因子負荷量を行列化する目的で、上記モデル式を行列形式で記述します。
テキスト p.129 の数式をお借りします。
$$
\begin{bmatrix}x_1 \\ x_2 \\ \vdots \\ x_p\end{bmatrix}
= \begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1m} \\
a_{21} & a_{22} & \cdots & a_{2m} \\
\vdots & \vdots & \ddots & \vdots \\
a_{p1} & a_{p2} & \cdots & a_{pm} \\
\end{bmatrix}
\begin{bmatrix}f_1 \\ f_2 \\ \vdots \\f_p\end{bmatrix}
+ \begin{bmatrix}\varepsilon_1 \\ \varepsilon_2 \\ \vdots \\\varepsilon_p\end{bmatrix}
$$
右辺第1項の因子負荷量の行列を「因子負荷行列」または「因子パターン行列」$${\Lambda_f}$$ と呼びます。
$$
\Lambda_f = \begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1m} \\
a_{21} & a_{22} & \cdots & a_{2m} \\
\vdots & \vdots & \ddots & \vdots \\
a_{p1} & a_{p2} & \cdots & a_{pm} \\
\end{bmatrix}
$$

データの分散共分散行列との関係
次のようにテキストにならい、データ分散共分散行列・相関行列と因子負荷行列の関係を探ります。
データの分散共分散行列を因子負荷行列を用いて公式化する
データの相関行列から因子負荷行列の具体的な値を求める

■ データの分散共分散行列と因子負荷行列
共通因子が2個の場合について、テキストの数式をお借りして、両者の関係を探ります。
📊 因子分析のモデル式
$$
\begin{align*}
x_1 &= a_{11} f_1 + a_{12} f_2 + \varepsilon_1 \\
x_2 &= a_{21} f_1 + a_{22} f_2 + \varepsilon_2 \\
x_3 &= a_{31} f_1 + a_{32} f_2 + \varepsilon_3 \\
\end{align*}
$$
📊 データの分散共分散行列
$$
\Sigma = \begin{bmatrix}
\text{Var}(x_1) & \text{Cov}(x_1, x_2) & \text{Cov}{x_1, x_3}\\
\text{Cov}(x_2, x_1) & \text{Var}(x_2) & \text{Cov}(x_2, x_3) \\
\text{Cov}(x_3, x_1) & \text{Cov}(x_3, x_2) & \text{Var}(x_3) \\
\end{bmatrix}
$$
📊 モデルの仮定
① 共通因子は分散1、共通因子同士の共分散は0
$$
\text{Var}(f_k) =1, \quad \text{Cov}(f_k, f_l) = 0\ \ (k \neq l)
$$
② 誤差(独自因子)同士の共分散は0
$$
\text{Cov}(\varepsilon_i,\varepsilon_j) = 0, \quad i \neq j
$$
③ 誤差(独自因子)と共通因子の共分散は0
$$
\text{Cov}(\varepsilon_j, f_k) = 0
$$
📊 分散共分散行列と因子負荷行列の関係式
データの分散共分散行列を $${\Sigma}$$、因子負荷行列を $${\Lambda_f}$$、誤差分散(独自性)の対角行列を $${D}$$ とすると
$$
\Sigma = \Lambda_f \Lambda_f^{\top} + D
$$
【計算の詳細】
もっと詳細(例えば1行目から2行目への展開)はテキストをご確認下さい。
$$
\begin{align*}
\Sigma &= \begin{bmatrix}
\text{Var}(x_1) & \text{Cov}(x_1, x_2) & \text{Cov}{x_1, x_3}\\
\text{Cov}(x_2, x_1) & \text{Var}(x_2) & \text{Cov}(x_2, x_3) \\
\text{Cov}(x_3, x_1) & \text{Cov}(x_3, x_2) & \text{Var}(x_3) \\
\end{bmatrix} \\
\\
&= \begin{bmatrix}
{a_{11}}^2 + {a_{12}}^2 + \text{Var}(\varepsilon_1) & a_{11} a_{21} + a_{12} a_{22}& a_{11} a_{31} + a_{12} a_{32}\\
a_{11} a_{21} + a_{12} a_{22}& {a_{21}}^2 + {a_{22}}^2 + \text{Var}(\varepsilon_2) & a_{21} a_{31} + a_{22} a_{32} \\
a_{11} a_{31} +a_{12} a_{32} & a_{21} a_{31} + a_{22} a_{32}& {a_{31}}^2 + {a_{32}}^2 + \text{Var}(\varepsilon_3) \\
\end{bmatrix} \\
\\
&=
\begin{bmatrix}
{a_{11}}^2 + {a_{12}}^2 & a_{11} a_{21} + a_{12} a_{22} & a_{11} a_{31} + a_{12} a_{32} \\
a_{11} a_{21} + a_{12} a_{22} & {a_{21}}^2 + {a_{22}^2} & a_{21} a_{31} + a_{22} a_{32} \\
a_{11} a_{31} + a_{12} a_{32} & a_{21} a_{31} + a_{22} a_{32} & {a_{31}}^2 + {a_{32}}^2 \\
\end{bmatrix} \\
&\quad + \begin{bmatrix}
\text{Var}(\varepsilon_1) & 0 & 0 \\
0 & \text{Var}(\varepsilon_2) & 0 \\
0 & 0 & \text{Var}(\varepsilon_3) \\
\end{bmatrix} \\
\\
&=
\underbrace{\begin{bmatrix}
a_{11} & a_{12} \\ a_{21} & a_{22} \\ a_{31} & a_{32}
\end{bmatrix}}_{\Lambda_f}
\underbrace{\begin{bmatrix}
a_{11} & a_{21} & a_{31} \\
a_{12} & a_{22} & a_{32} \\
\end{bmatrix}}_{\Lambda_f^{\top}}
+ \underbrace{\begin{bmatrix}
\text{Var}(\varepsilon_1) & 0 & 0 \\
0 & \text{Var}(\varepsilon_2) & 0 \\
0 & 0 & \text{Var}(\varepsilon_3) \\
\end{bmatrix}}_{D} \\
\\
&= \Lambda_f \Lambda_f^{\top} + D
\end{align*}
$$

分散共分散行列と因子負荷行列の関係を確かめる
■ 関係確認の準備
次式で示される「データの分散共分散行列」と「因子負荷行列」・「誤差分散(独自性)」の関係を Python の statsmodels ライブラリを用いて確認します。
$$
\Sigma = \Lambda_f \Lambda_f^{\top} + D
$$
標準化済みのデータ X_std を用います。
したがって、$${\Sigma}$$ は相関行列になります。
なお、標準化に用いた標準偏差の分母は $${N-1}$$ です。
計算結果とテキスト p.138 表 4.4.2「SPSSによる出力」と照合できるようにパラメータ値を指定して、因子分析を実行します。
### 因子分析の実行 ※テキストp.138 のSPSSの各値とほぼ同じになる
# 準備
index = ['x1', 'x2', 'x3']
# 因子分析の実行 標準化データを利用 ※smc=True, maxiter=12を設定
result1_sm = sm.multivariate.Factor(
X_std, method='pa', smc=True).fit(maxiter=12)【実行結果】なし
表 4.4.2「SPSSによる出力」と結果を照合して、テキストに合致したモデルになっていることを確かめていきます。

■ 因子負荷量
# 因子負荷量 ※SPSSの「因子行列」に相当
pd.DataFrame(result1_sm.loadings_no_rot, index=index, columns=['因子負荷量'])【実行結果】
SPSSの「因子行列」と一致しています。

■ 共通性(因子負荷量の二乗和)
# 共通性 ※SPSSの「共通性-因子抽出後」に相当
pd.DataFrame(result1_sm.communality, index=index, columns=['共通性'])【実行結果】
SPSSの「共通性-因子抽出後」と一致します。

■ 固有値
# 固有値 ※SPSSの「抽出後の負荷量平方和の固有値」に相当
pd.DataFrame(result1_sm.eigenvals, index=index, columns=['因子分析の固有値'])【実行結果】
SPSSの「抽出後の負荷量平方和の固有値」と一致しています。

statsmodels の因子分析の結果がテキストのSPSSと合っていることを確認できました。
「データの分散共分散行列」「因子負荷行列」「誤差分散(独自性)」の関係が成り立つことを探りに行きましょう!

■ $${\Sigma = \Lambda_f \Lambda_f^{\top} + D}$$ を探る
まず因子負荷行列の行列積 $${\Lambda_f \Lambda_f^{\top}}$$ を見ます。
statsmodels の因子分析の結果 result1_sm の属性 loadings_no_rot で因子負荷行列を取得します。
### Σ = Λ @ Λ.T + D の確認
# 因子負荷行列の積 Λ @ Λ.T ※対角成分が共通性
Lambda = result1_sm.loadings_no_rot
pd.DataFrame(Lambda @ Lambda.T, index=index, columns=index)【実行結果】

続いて誤差分散行列 $${D}$$ を見ます。
result1_sm の属性 uniquenessで独自性=誤差分散を取得します。
# D: 独自性を対角成分にもつ対角行列
pd.DataFrame(np.diag(result1_sm.uniqueness), index=index, columns=index)【実行結果】

因子負荷行列の行列積+誤差分散行列=標準化後データの相関行列、かどうかを確認しましょう。
# Σ = Λ @ Λ.T + D
pd.DataFrame(Lambda @ Lambda.T + np.diag(result1_sm.uniqueness),
index=index, columns=index)【実行結果】
$${\Lambda_f \Lambda_f^{\top} + D}$$ の結果です。

モデルがフィットした分散共分散行列を表示して、この計算結果と比較しましょう。
result1_sm の属性 fitted_cov でモデルがフィットした分散共分散行列を取得します。
# モデルがフィットしたΣ ≒ データの相関行列
pd.DataFrame(result1_sm.fitted_cov, index=index, columns=index)【実行結果】
計算結果と一致しました。

$${\Sigma = \Lambda_f \Lambda_f^{\top} + D}$$ を確認できました。
実は、標準化後データの相関行列と上記のフィットした分散共分散行列は若干違います。
フィットした分散共分散行列には計算誤差が含まれているからです。
標準化後データの相関行列と見比べてみましょう。
# (参考)データの相関行列
pd.DataFrame(X_std.cov(ddof=1).values, index=index, columns=index)【実行結果】
若干のずれがあることを確認できました。

記事の最後はChatGPTが締めくくります。
今回は川の流れに想いを寄せて。
📘 ChatGPTのひとこと:
今回は因子分析のモデル式や共通因子の解釈、そして分散共分散行列と因子負荷量の関係をざっくりと眺めてきました。
まるで静かな川のほとりで水面を見つめ、目に見えない深い流れを感じ取るように、データの奥底に潜む“共通の動き”をそっと味わえたのではないでしょうか😊
次回は、主因子法という新たな地図を手に取り、実際に因子負荷量を推定するプロセスを一緒に歩んでいきます。
川の深流を測るための細かな手順を一つひとつ試しながら、データの真の構造にさらに近づいていきましょう✨
今回の写経は以上です。
シリーズの記事
次の記事
前の記事
目次
ブログの紹介
note で7つのシリーズ記事を書いています。
ぜひ覗いていってくださいね!
1.のんびり統計
統計検定2級の問題集を手がかりにして、確率・統計をざっくり掘り下げるブログです。
雑談感覚で大丈夫です。ぜひ覗いていってくださいね。
統計検定2級公式問題集CBT対応版に対応しています。
Python、EXCELのサンプルコードの配布もあります。
2.実験!たのしいベイズモデリング1&2をPyMC Ver.5で
書籍「たのしいベイズモデリング」・「たのしいベイズモデリング2」の心理学研究に用いられたベイズモデルを PyMC Ver.5で描いて分析します。
この書籍をはじめ、多くのベイズモデルは R言語+Stanで書かれています。
PyMCの可能性を探り出し、手軽にベイズモデリングを実践できるように努めます。
身近なテーマ、イメージしやすいテーマですので、ぜひぜひPyMCで動かして、一緒に楽しみましょう!
3.実験!岩波データサイエンス1のベイズモデリングをPyMC Ver.5で
書籍「実験!岩波データサイエンスvol.1」の4人のベイジアンによるベイズモデルを PyMC Ver.5で描いて分析します。
この書籍はベイズプログラミングのイロハをざっくりと学ぶことができる良書です。
楽しくPyMCモデルを動かして、ベイズと仲良しになれた気がします。
みなさんもぜひぜひPyMCで動かして、一緒に遊んで学びましょう!
4.楽しい写経 ベイズ・Python等
ベイズ、Python、その他の「書籍の写経活動」の成果をブログにします。
主にPythonへの翻訳に取り組んでいます。
写経に取り組むお仲間さんのサンプルコードになれば幸いです🍀
5.RとStanではじめる心理学のための時系列分析入門 を PythonとPyMC Ver.5 で
書籍「RとStanではじめる心理学のための時系列分析入門」の時系列分析をPythonとPyMC Ver.5 で実践します。
この書籍には時系列分析のテーマが盛りだくさん!
時系列分析の懐の深さを実感いたしました。
大好きなPythonで楽しく時系列分析を学びます。
6.データサイエンスっぽいことを綴る
統計、データ分析、AI、機械学習、Pythonのコラムを不定期に綴っています。
統計・データサイエンス書籍にまつわる記事が多いです。
「統計」「Python」「数学とPython」「R」のシリーズが生まれています。
7.Python機械学習プログラミング実践記
書籍「Python機械学習プログラミング PyTorch & scikit-learn編」を学んだときのさまざまな思いを記事にしました。
この書籍は、scikit-learnとPyTorchの教科書です。
よかったらぜひ、お試しくださいませ。
最後までお読みいただきまして、ありがとうございました。
いいなと思ったら応援しよう!
応援ありがとうございます。これからもがんばって記事を作成します!
