ノーマルな因子分析は連続変数を用いる。その拡張としてカテゴリカル変数でも因子分析は可能である。今回は、連続変数で推定した結果とカテゴリカル因子分析の推定はどのくらい異なるのかをシミュレーションしてみたい。
大前提としてカテゴリカル変数といっても、その背景に連続変数、正規分布が仮定できなければならない。男女や東京に住んでいる、名古屋に住んでいるといった値は因子分析では扱えない。比較的有名な研究でも、「○○という体験をした」というマルチアンサーを因子分析したり、精神医学の診断を因子分析したりするものもあるが、因子分析を使うのは誤りである。どうしてもグルーピングがしたければ潜在クラス分析を使うべきである。
サンプルデータ
児童向けウェクスラー式知能検査(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.integer
intger型へ変換するという意味である。
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分位の方が連続変数に近いというわけでもないようだ。
結果は、連続変数から作成したカテゴリカル変数であれば、もともとの連続変数の結果からは大きく外れない、というものだ。
ただ「逆も真なり」ではない。
調査データでは、連続変数からカテゴリカル変数に変換してカテゴリカル因子分析をするということはしない。連続変数があれば連続変数で分析するのがよいからだ。
実際には、背後に連続変数が想定されると考えられるカテゴリカル変数で因子分析をすることなる。連続変数が想定される根拠は無い。「おそらく想定されるであろう」という当て推量である。その当て推量があっている場合もあれば、見当はずれの場合もある。これは、いくらシミュレーションをしてもわからないもので、どうしようもない。カテゴリカル因子分析を使用する注意点はそのあたりだろうか。