猫も杓子も構造化

発達障害、特別支援などについて書いています。最近は心理学関係の内容が多めです。

いきなり因子分析(その1)

思いつきで何かをやりたくなるということがあって、今は因子分析な気分なのでやってみる。ちなみに多変量解析の経験値はほぼゼロ。

データセットの準備

ここのところマイブームがアセスメントなので、知能検査のデータセットを使うこととする。Rのパッケージlavaanには、HolzingerSwineford1939という名前で2つの学校の2つの学年の知能検査のデータが入っているらしい。

library(lavaan)

dat <- HolzingerSwineford1939
head(dat)

f:id:nekomosyakushimo:20180704093703p:plain
head()の結果

列を順番に見ていくと、ID、性別、、年齢(歳)、年齢(ヵ月)、学校、学年、と続いた後に9つの検査内容が続いている。

検査内容はHELPを見ると次のように書いてある。

  1. Visual perception
  2. Cubes
  3. Lozenges
  4. Paragraph comprehension
  5. Sentence completion
  6. Word meaning
  7. Speeded addition
  8. Speeded counting of dot
  9. Speeded discrimination straight and curved capitals

それぞれが具体的に何をやっているかは今回興味がないがまぁ言葉やら形やら色々な検査をやらせたんでしょう。

データの中身をのぞいてみる

まずは、データの確認である。psychというパッケージに入っているdescribe()pairs.panels() は便利だった気がする。describe()関数の方は変数ごとに記述統計量をまとめて算出してくれる。pairs.panels()の方は、散布図行列に相関行列に変数ごとのヒストグラムを合わせたようなものが関数一発算出される。今回は知能検査の変数を見てみる。

library(psych)

describe(dat)
pairs.panels(dat[,7:15],smooth=FALSE, density=FALSE , ellipses=FALSE, scale=FALSE)

f:id:nekomosyakushimo:20180704093713p:plain
describe(dat)結果

記述統計量は、歪度と尖度も合わせて出してくれるし便利である。

f:id:nekomosyakushimo:20180704093731p:plain
散布図行列

散布図行列の方も、色々な情報が一つにまとまっていて便利である。引数で色々とオプションを決められるので好みの設定を見つけると良い。

とりあえず探索的因子分析

因子分析のためには相関行列が必要ということで、データセットから作成する。 cormatrix <- cor(dat[,7:15])変数部分はさっき確認したように7列目から15列目である次のようなものができあがる。

f:id:nekomosyakushimo:20180704093716p:plain
相関行列

因子数の決定方法にも色々あるらしいけれど、とりあえず固有値を基準にするものでやってみよう。eigen()に相関行列で固有値固有値ベクトルを計算できる。固有値$values固有ベクトル$vectorsに格納されるので、固有値の方だけゲットして、スクリープロットをつくる。

eigen <- eigen(cormatrix)$values
plot(eigen, type="b")

f:id:nekomosyakushimo:20180704093655p:plain
スクリープロット

みたところ、1より大きいものは3つで、4つ目以降は緩やかな減少になっているので、今回は3つの因子でいってみましょうか。

回転を選んで実行

因子数が決まったところで、早速初期解の推定をするのだが、最初から入っている因子分析の関数factanal()だと最尤法しか扱えないらしい。ただ、回転はバリマックスかプロマックスかを選べるということなので、どちらでもやってみる。

result_varimax <- factanal(x=dat[,7:15], factor=3, rotation="varimax")
print(result_varimax, cutoff=0)

f:id:nekomosyakushimo:20180704093724p:plain
varimax結果

まずバリマックスの結果。一番上に独自性(Uniquenesses)が表示されている。独自性というのは、観測値のうち共通因子によって説明できない部分のことである。(1-共通性)の値である。例えば、この例だとx2(Cubes)は独自性が0.749と高い。言い換えると、この変数はの75%はその変数に特有の独自因子によって説明され、今回仮定した3つの共通の因子で説明でき流部分は25%しかないことになる。

次に因子負荷量(Loadings)が表示されている。これは、各観測変数に対して共通因子がどの程度の影響を持っているかを示している。値を見てみると、Factor1は変数4~6に、Factor2は変数1~3に、Factor3は変数7~9に高い因子負荷量を持っていることがわかる。

その下のブロックは、因子が全体の分散のうちどの程度を説明できているかを表す因子寄与(SS loadings)、その割合である因子寄与率(Proportion Var)、因子寄与率を高い順に足していき、因子全体で全体を何%説明できているかを表す累積寄与率(Cumurative Var)が表示されている。上記の結果だと、3つの因子で全体の情報の53.9%が説明されたことになる。

今度は、プロマックス回転で行ってみよう。

result_promax <- factanal(x=dat[,7:15], factor=3, rotation="promax")
print(result_promax, cutoff=0)

f:id:nekomosyakushimo:20180704094215p:plain
promax結果

結果を見てみる。大きく違うのは直行回転で表示される項目に加えて、因子の相関行列(Factor Correlations)が表示される。斜交回転というのは因子間の相関関係を仮定しているのでこうした項目が表示され、結果をみるとF1とF2には弱めの負の相関と、F1とF3には中くらいの相関があるのが分かる。

独自性については同じ値が表示されているが、大きく数字が変わったのが因子負荷量である。例えば因子1の値のみ抜き出して、直行回転と斜交回転で比べてみると以下の通りである。

変数 斜交回転 直行回転
x1 0.146 0.277
x2 0.007 0.105
x3 -0.122 0.034
x4 0.841 0.827
x5 0.896 0.861
x6 0.804 0.801
x7 0.047 0.091
x8 -0.048 0.051
x9 0.002 0.132

因子負荷が変数4,5,6について高いというの全体的な傾向は変わっていないが、高いものは高い、低いものは低いというように、よりメリハリのついた形で示されているのが分かる。

因子寄与や累積因子寄与率は、数字はいくらか変わるものの回転の方法ではそんなに変わらない様子である。

知能検査みたいなもので、因子間に相関か関係がないという仮定は無理筋でしょうから、今回は斜交回転を採択しておくとする。

因子の命名と解釈

こんな感じで因子数と因子の内容をしながら、もっともらしくデータの変動を説明できるものを探していくというのが探索的因子分析というようである。

因子分析の結果、変数の意味内容とかを考えながら因子に名前をつけるらしい。今回の結果だと、F1は因子分析の結果、Visual perception, Cubes,Lozengesという3つのテストに高い負荷があるので視空間能力、F2はParagraph comprehension, Sentence completion, Word meaningに高い負荷があるから言語能力, F3はSpeeded addition, Speeded counting of dot, Speeded discrimination straight and curved capitalsに高い負荷があるから処理速度のような感じで。

本当はもっと色々と試してみて決めるようだけれど、今回は流れを確かめるということでこのくらいで。

そのうち別の回転とか別の推定方法とか編でやってみよう。