{
"cells": [
{
"cell_type": "markdown",
"id": "a228164f-c2d0-4635-aa29-c58c7ba28185",
"metadata": {},
"source": [
"# 因子分析\n",
"\n",
"**因子分析**(factor analysis)はデータの分散を分解することによって何らかの共通性を抽出する手法である。\n",
"\n",
"心理学などの分野において、「リーダシップ」や「社交性」のような直接観測することができない**構成概念**(construct)を抽出するために用いられる。\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "f8efa0b9-ac89-446a-998f-2e0b7e681e9c",
"metadata": {},
"source": [
"## 因子分析モデル\n",
"\n",
"### 1因子モデル\n",
"\n",
"$p$次元の観測値が$n$個得られているとし、$i$番目の$j$次元のデータを$x_{ij}$と表すことにする。$x_{ij}$を標準化して平均0、分散1にしたデータを$z_{ij}$と表すことにする。\n",
"\n",
"1因子モデルは標準化データを次のように分解するモデルである。\n",
"\n",
"$$\n",
"z_{ij} = a_j f_i + d_j u_{ij}\n",
"$$\n",
"\n",
"ここで\n",
"\n",
"- $f_i$は観測対象$i$の**共通因子**(common factor)で、構成概念を表す\n",
"- $u_{ij}$は**独自因子**(unique factor)と呼ばれ、構成概念で説明しきれない要因を表す\n",
"- $a_j$は観測変数$j$の**因子負荷**(factor loading)で、観測変数$j$が共通因子から受ける影響の程度を表す\n",
"- $d_j$は観測変数$j$の**独自係数**と呼ばれ、観測変数$j$が独自因子から受ける影響の程度を表す\n",
"\n",
"\n",
"### $m$因子モデル\n",
"\n",
"$m$個の因子を扱うように拡張すると\n",
"\n",
"\n",
"$$\n",
"\\begin{align}\n",
"z_{ij}\n",
"&= a_{j1} f_{i1} + \\cdots + a_{jm} f_{im} + d_j u_{ij}\\\\\n",
"&= \\sum^m_{l=1} a_{jl} f_{il} + d_j u_{ij}\\\\\n",
"\\end{align}\n",
"$$\n",
"\n",
"と表すことができる。"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "56e0ebea-226b-4e7f-9bb0-b543d0c0b99d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/local/lib/python3.9/site-packages/statsmodels/multivariate/factor.py:419: UserWarning: Fitting did not converge\n",
" warnings.warn(\"Fitting did not converge\")\n"
]
},
{
"data": {
"text/html": [
"
\n",
"\n",
" | | | | \n",
"
\n",
"
\n",
"\n",
"\n",
" | Communality | | | \n",
"
\n",
"
\n",
"\n",
"\n",
" | 英語 | 国語 | 数学 | \n",
"
\n",
"\n",
" | 0.9977 | 0.7723 | 0.5347 | \n",
"
\n",
"
\n",
"\n",
"\n",
" | | | | \n",
"
\n",
"
\n",
"\n",
"\n",
" | Pre-rotated loadings | | | \n",
"
\n",
"
\n",
"\n",
"\n",
" | factor 0 | \n",
"
\n",
"\n",
" 英語 | 0.9995 | \n",
"
\n",
"\n",
" 国語 | 0.8719 | \n",
"
\n",
"\n",
" 数学 | 0.7180 | \n",
"
\n",
"
\n",
"\n",
"\n",
" | | | | \n",
"
\n",
"
"
],
"text/plain": [
"\n",
"\"\"\"\n",
"Factor analysis results\n",
"=======================\n",
" \n",
"-----------------------\n",
" Communality \n",
"------------------------\n",
" 英語 国語 数学 \n",
"------------------------\n",
" 0.9977 0.7723 0.5347\n",
"-----------------------\n",
" \n",
"-----------------------\n",
" Pre-rotated loadings \n",
"-----------------------\n",
" factor 0\n",
"-----------------------\n",
"英語 0.9995\n",
"国語 0.8719\n",
"数学 0.7180\n",
"-----------------------\n",
" \n",
"=======================\n",
"\n",
"\"\"\""
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"\n",
"# テストの点数データ\n",
"scores = pd.DataFrame([\n",
" {\"英語\": 98, \"国語\": 95, \"数学\": 75},\n",
" {\"英語\": 90, \"国語\": 75, \"数学\": 70},\n",
" {\"英語\": 60, \"国語\": 57, \"数学\": 80},\n",
" {\"英語\": 50, \"国語\": 70, \"数学\": 60},\n",
" {\"英語\": 30, \"国語\": 50, \"数学\": 40},\n",
"])\n",
"Z = (scores - scores.mean()) / scores.std()\n",
"\n",
"from statsmodels.multivariate.factor import Factor\n",
"\n",
"fa = Factor(Z, n_factor=1, method=\"ml\").fit()\n",
"fa.summary()"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "eced271b-2241-41d9-ac5e-c7df2ce3184f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.00228581, 0.22772564, 0.46534024])"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fa.uniqueness"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "9ee26202-6a69-4aef-9681-f62ca035846c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 1.15171807],\n",
" [ 0.85998399],\n",
" [-0.19932969],\n",
" [-0.54814633],\n",
" [-1.26422604]])"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 共通因子スコア\n",
"fa.factor_scoring(Z)"
]
},
{
"cell_type": "markdown",
"id": "8fd00292-4018-40e2-b69a-a0998f207e46",
"metadata": {},
"source": [
"## 主成分分析との違い\n",
"\n",
"主成分分析も分散を分解して共通した成分を取り出す手法であり、因子分析と似ているが、誤差を分離するかどうかが異なる。\n",
"\n",
"因子分析は観測変数を共通した部分と誤差とに分解した上で共通因子を抽出するのに対し、主成分分析は誤差の分離を行わずに共通した部分を取り出そうとする。\n"
]
},
{
"cell_type": "markdown",
"id": "9b6331c7-afc4-4f2c-ba2f-72b9370ae873",
"metadata": {},
"source": [
"## 妥当性と信頼性\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "a7e5ab89-d2e9-4ff7-b9d7-2a5f0ffbef73",
"metadata": {},
"source": [
"## 探索的因子分析\n",
"\n",
"**探索的因子分析**(exploratory factor analysis: EFA)は、因子と観測変数の関係についての仮説や制約を置かずに、観測変数のみから相関係数を計算し、観測変数間に相関関係をもたらす因子を推定する方法。\n",
"\n",
"たとえば因子の数は固有値から探索して決める\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "1dad15b4-3322-407a-8acd-1a913f0533ee",
"metadata": {},
"source": [
"## 確認的因子分析\n",
"\n",
"**確認的因子分析**(confirmatory factor analysis: CFA)は、因子の数や観測変数との関係性などについての仮説(モデル)をあらかじめ立てておき、その仮説の正しさを検証するためにモデルをデータにあてはめていく。\n",
"\n",
"その妥当性はデータの分散をモデルがどれだけ説明できたか(適合度)の指標などによって確認される。\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "55178759-86f6-4bac-b9b5-80c5497adf51",
"metadata": {},
"outputs": [],
"source": [
"import semopy"
]
},
{
"cell_type": "markdown",
"id": "84148e98-2e7b-4b7e-be6e-782ae0dbb70d",
"metadata": {},
"source": [
"## 参考\n",
"\n",
"- Hofacker, C. (2004). Exploratory Factor Analysis, Mathematical Marketing. http://www.openaccesstexts.org/pdf/Quant_Chapter_11_efa.pdf\n",
"- J Bai, K Li (2012). Statistical analysis of factor models of high dimension. Annals of Statistics. https://arxiv.org/pdf/1205.6617.pdf"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "063c5383-8796-4e85-a860-0a9e66a43157",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}