因子分析とカテゴリカル因子分析の結果はとのくらい異なるか

ノーマルな因子分析は連続変数を用いる。その拡張としてカテゴリカル変数でも因子分析は可能である。今回は、連続変数で推定した結果とカテゴリカル因子分析の推定はどのくらい異なるのかをシミュレーションしてみたい。

大前提としてカテゴリカル変数といっても、その背景に連続変数、正規分布が仮定できなければならない。男女や東京に住んでいる、名古屋に住んでいるといった値は因子分析では扱えない。比較的有名な研究でも、「○○という体験をした」というマルチアンサーを因子分析したり、精神医学の診断を因子分析したりするものもあるが、因子分析を使うのは誤りである。どうしてもグルーピングがしたければ潜在クラス分析を使うべきである。

サンプルデータ

児童向けウェクスラー式知能検査(Wechsler Intelligence Scale for Children; WISC)のサンプルデータを用いてシミュレーションをしてみよう。サンプルデータはこちらこちらからダウンロードする。

変数名 説明
info Information
comp Comprehension
arith Arithmetic
simil Similarities
vocab Vocabulary
digit Digit Span
pictcomp Picture Completion
parang Paragraph Arrangement
block Block Design
object Object Assembly
coding Coding

それぞれの項目は20点満点(0~20)である。 WISCは階層構造になっているとされているが、面倒くさい上に、実データは教科書通りの因子構造をしていないので、そのまま因子分析にかけることにする。

データの加工

Rのpsychパッケージを利用して因子分析行う。

library(foreign)
d1 <- read.spss("wiscsem.sav", to.data.frame=TRUE)
d2 <- d1[3:13] # 因子分析に使用するのは3~13列目

リコード

今回は機械的に分位点で数値を分けていく。 OneRパッケージの分位点で連続変数を分けるbin functionを使う。

library(OneR)
d3 <- bin(d2, nbins = 4, labels = c(1,2,3,4))
d4 <- bin(d2, nbins = 2, labels = c(1,2))

d3は4分位で分けたデータをいれる。4段階の変数となる。d4には2分位で分けたデータを入れるので、2値データとなる。

データ型の変更

OneRでラベルをつけていることをみてもわかるように、データの中身はfactor型である。psychパッケージは整数型、つまりinteger型でないと作動しないので変換が必要になる。

いくつか方法があるようだが、dplyrパッケージを使う。コマンドはis.factorつまりfactor型である変数をas.integerintger型へ変換するという意味である。

library(dplyr)
d3 <- d3 %>% mutate_if(is.factor, as.integer)
str(d3) # データ構造の確認
d4 <- d4 %>% mutate_if(is.factor, as.integer)
str(d4) # データ構造の確認

因子数の決定

一応、手続きに則り、因子数の決定を行う。連続変数の方で行う。

スクリー・プロット

library("psych")
scree(d2,factors=TRUE,pc=TRUE,main="Scree plot",hline=NULL,add=FALSE)
VSS.scree(d2, main = "scree plot")  

平行分析

fa.parallel(d2)

MAP情報量

res01<-vss(d2) 
print(res01,digits =4)

スクリーは1因子、平行分析は2因子、Map情報量は2因子という提案であったため、2因子を採用する。

因子分析

連続変数での実施。

library("psych")
library("GPArotation")
res2 <- fa(d2, nfactors = 2, fm = "minres", rotate = "oblimin", scores=TRUE)
print(res2, digits = 3, sort=TRUE)

オプションで推定法(minres: 最小残差法)と回転(oblimin: オブリミン)をしているが、これはデフォルト値なので指定しなくてもよいが、結果を比較するので一応記述した。

4段階の順序変数での実施。corオプションは"poly"にする。

res02 <- fa(d3, nfactors = 2, fm = "minres", rotate = "oblimin",
                   scores=TRUE, cor="poly")
print(res02, digits = 3)

2値データでの因子分析。corオプションは"tet"にする。

res03 <- fa(d4, nfactors = 2, fm = "minres", rotate = "oblimin", 
                   scores=TRUE, cor="tet")
print(res03, digits = 3)

結果

因子1

連続 4分位 2分位
info 0.831 0.816 0.978
comp 0.502 0.393 0.351
arith 0.604 0.621 0.453
simil 0.562 0.460 0.647
vocab 0.743 0.620 0.785
digit 0.487 0.392 0.353
pictcomp 0.063 -0.030 0.080
parang 0.095 -0.027 -0.082
block 0.057 0.040 0.087
object -0.088 -0.027 -0.101
coding 0.101 0.084 -0.141

因子2

連続 4分位 2分位
info -0.075 -0.101 -0.085
comp 0.315 0.391 0.438
arith -0.031 -0.037 0.335
simil 0.225 0.326 0.214
vocab 0.029 0.160 0.033
digit -0.128 0.033 -0.023
pictcomp 0.587 0.670 0.679
parang 0.382 0.397 0.444
block 0.616 0.533 0.537
object 0.656 0.552 0.731
coding -0.021 0.052 0.231

共通性(communalities)

連続 4分位 2分位
info 0.63671 0.5943 0.8828
comp 0.50340 0.4594 0.4652
arith 0.34791 0.3641 0.4663
simil 0.48808 0.4657 0.5992
vocab 0.57303 0.5077 0.6421
digit 0.19385 0.1673 0.1175
pictcomp 0.38448 0.4302 0.5204
parang 0.18932 0.1479 0.1684
block 0.41647 0.3073 0.3411
object 0.38311 0.2908 0.4729
coding 0.00856 0.0141 0.0413

一つ一つ見るとめんどくさいが、ざっくりとまとめると、それほど値は変わらない。時々、違うものも混じっている。また、2分位より4分位の方が連続変数に近いというわけでもないようだ。

結果は、連続変数から作成したカテゴリカル変数であれば、もともとの連続変数の結果からは大きく外れない、というものだ。
ただ「逆も真なり」ではない。

調査データでは、連続変数からカテゴリカル変数に変換してカテゴリカル因子分析をするということはしない。連続変数があれば連続変数で分析するのがよいからだ。

実際には、背後に連続変数が想定されると考えられるカテゴリカル変数で因子分析をすることなる。連続変数が想定される根拠は無い。「おそらく想定されるであろう」という当て推量である。その当て推量があっている場合もあれば、見当はずれの場合もある。これは、いくらシミュレーションをしてもわからないもので、どうしようもない。カテゴリカル因子分析を使用する注意点はそのあたりだろうか。