井出草平の研究ノート

コレスポンデンス分析 その1[R]

www.sthda.com

コレスポンデンス分析(CA)は、主成分分析の拡張版で、質的変数(またはカテゴリデータ)間の関係を探索するのに適している。主成分分析と同様に、データセットを2次元プロットで要約し、可視化するためのソリューションを提供する。

ここでは、2つのカテゴリデータが形成する頻度、すなわちコンテンジェンシーテーブルと呼ばれるデータテーブルを分析するために使用される、単純なコレスポンデンス分析について説明する。これは、分割表の行と列の両方の点に対する因子得点(座標)を提供するものである。これらの座標は、分割表の行と列の要素間の関連をグラフで可視化するために使用される。

二元分割表を分析するとき、典型的な質問は、ある行の要素が列の要素のいくつかの要素と関連しているかどうかである。コレスポンデンス分析は、二元分割表の行と列を低次元空間の点として可視化し、行と列の点の位置が表中の関連と一致するようにする幾何学的アプローチである。その目的は、解釈のために有用なデータのグローバルビューを持つことである。

本章では,2つのRパッケージ、i) FactoMineRによる解析とii) factoextraによるデータの可視化を用いて、コレスポンデンス解析の計算と解釈の方法を紹介する。さらに、データセットの変動を説明する最も重要な変数を明らかにする方法を紹介する。さらに、補足の行と列を使用してコレスポンデンス分析を適用する方法を説明する。これは、CAで予測をしたい場合、重要だ。このガイドの最後のセクションでは、最も寄与の大きい変数だけを保持するために、CAの結果をフィルタリングする方法も説明する。最後に、外れ値を取り扱う方法を示す。

コレスポンデンス分析の計算を行うために,R ソフトウェアには様々なパッケージからいくつかの関数が提供されている。

  • CA() [FactoMineRパッケージ]
  • ca() [caパッケージ]
  • dudi.coa() [ade4パッケージ]
  • corresp() [MASSパッケージ]
  • epCA() [ExPositionパッケージ]

どの関数を使うにしても、factoextra Rパッケージで提供されているR関数を使えば、コレスポンデンス解析の結果を簡単に抽出・可視化することができる。

ここでは、FactoMineR(解析用)とfactoextra(ggplot2ベースのエレガントな可視化用)を使用することにする。

library("FactoMineR")
library("factoextra")

データ形式

データは分割表でなければならない。ここでは、factoextra Rパッケージで提供されているデモデータセットhousetasksを使用する。

data(housetasks)

データ

           Wife Alternating Husband Jointly
Laundry     156          14       2       4
Main_meal   124          20       5       4
Dinner       77          11       7      13
Breakfeast   82          36      15       7
Tidying      53          11       1      57
Dishes       32          24       4      53

分割表のグラフとカイ二乗検定

上記の分割表はそれほど大きくはない。そのため、行と列のプロフィールを視覚的に確認し、解釈することが容易である。

  • 洗濯、食事、夕食といった家事は、「妻」がより頻繁に行うことがわかる。
  • 修理や運転は、圧倒的に夫が行うことが多い。
  • 休日は "共同jointly"の列と関連することが多い。

分割表の探索的データ解析と可視化については、前回の記事で取り上げた。簡単に説明すると、分割表は関数 balloonplot() [gplots package] と mosaicplot() [garphics package] を使って可視化することができる。 http://www.sthda.com/english/wiki/chi-square-test-of-independence-in-r

library("gplots")
# 1. convert the data as a table
dt <- as.table(as.matrix(housetasks))
# 2. Graph
balloonplot(t(dt), main ="housetasks", xlab ="", ylab="",
            label = FALSE, show.margins = FALSE)

行と列の合計は、デフォルトでそれぞれ下と右の余白に表示されることに注目。これらの値は、上記のプロットでは、引数 show.margins = FALSE を使って隠されている。

小さな分割表では、カイ二乗検定を使用して、行と列のカテゴリ間に有意な依存性があるかどうかを評価することができる。

chisq <- chisq.test(housetasks)
chisq
 Pearson's Chi-squared test

data:  housetasks
X-squared = 1944.5, df = 36, p-value < 2.2e-16

この例では、行と列の変数が統計的に有意に関連している(p-value = r chisq$p.value).

CAを計算するためのRコード

CA()[FactoMinerパッケージ]という関数が使用可能だ。簡略化した書式は:

CA(X, ncp = 5, graph = TRUE)
  • X : データフレーム(分割表)
  • ncp : 最終結果に保持される次元数
  • graph : 論理値。TRUE の場合、グラフが表示される

コレスポンデンス解析の計算には、このように入力する。

library("FactoMineR")
res.ca <- CA(housetasks, graph = FALSE)

関数CA () の出力は以下を含むリストである。

print(res.ca)
**Results of the Correspondence Analysis (CA)**
The row variable has  13  categories; the column variable has 4 categories
The chi square of independence between the two variables is equal to 1944.456 (p-value =  0 ).
*The results are available in the following objects:

   name              description                   
1  "$eig"            "eigenvalues"                 
2  "$col"            "results for the columns"     
3  "$col$coord"      "coord. for the columns"      
4  "$col$cos2"       "cos2 for the columns"        
5  "$col$contrib"    "contributions of the columns"
6  "$row"            "results for the rows"        
7  "$row$coord"      "coord. for the rows"         
8  "$row$cos2"       "cos2 for the rows"           
9  "$row$contrib"    "contributions of the rows"   
10 "$call"           "summary called parameters"   
11 "$call$marge.col" "weights of the columns"      
12 "$call$marge.row" "weights of the rows"        

関数 CA() を使って作成されるオブジェクトは、多くの異なるリストやマトリックスに見られる多くの情報を含んでいる。これらの値については、次のセクションで説明する。

可視化と解釈

コレスポンデンス解析の解釈と可視化のために、以下の関数[in factoextra]を使用する。

  • get_eigenvalue(res.ca): 各次元(軸)が保持する固有値/分散を抽出する
  • fviz_eig(res.ca): 固有値を可視化する
  • get_ca_row(res.ca): get_ca_col(res.ca): 行と列の結果をそれぞれ抽出する
  • fviz_ca_row(res.ca): fviz_ca_col(res.ca): それぞれ、行と列の結果を視覚化する
  • fviz_ca_biplot(res.ca): 行と列のバイプロットを作成する

次の章では、それぞれの機能を説明する。

統計的有意

コレスポンデンス分析を解釈するためには、まず行と列の間に有意な従属関係があるかどうかを評価することである。

厳密な方法は、行と列の変数の間の関連を調べるために、カイ2乗統計量を使用することである。これは、関数summary(res.ca)またはprint(res.ca)によって生成されるレポートの最上部に表示さ れるものだ。高いカイ二乗統計量は、行変数と列変数の間の強い関連を意味する。

この例では、関連性は極めて有意である(カイ二乗:1944.456、p = 0)。

# Chi-square statistics
chi2 <- 1944.456
# Degree of freedom
df <- (nrow(housetasks) - 1) * (ncol(housetasks) - 1)
# P-value
pval <- pchisq(chi2, df = df, lower.tail = FALSE)
pval
[1] 0

固有値/分散

考慮すべき軸の数を決定するために、固有値を調べることを思い出してほしい。固有値と異なる軸によって保持される分散の割合は、関数get_eigenvalue()[factoextraパッケージ]を使用して抽出することができる。固有値は、最初の軸では大きく、後続の軸では小さくなる。

library("factoextra")
eig.val <- get_eigenvalue(res.ca)
eig.val
      eigenvalue variance.percent cumulative.variance.percent
Dim.1  0.5428893         48.69222                    48.69222
Dim.2  0.4450028         39.91269                    88.60491
Dim.3  0.1270484         11.39509                   100.00000

固有値は、各軸が保持する情報量に対応する。次元は、解の中で説明される分散の量に従って、減少するように並べられ、リスト化される。次元は、解の中で最も多くの分散を説明し、2次元がそれに続き、以下同様である。

累積説明率は、説明された変動の連続した比率を追加して、実行中の合計を得ることによって得られる。例えば、48.69% + 39.91% = 88.6%、などだ。したがって、変動の約88.6%は最初の2次元で説明される。

固有値は、保持すべき軸の数を決定するために使用することができる。データ解釈のために保持すべき次元の数を選択するための「経験則」はありません。それは、リサーチクエスチョンと研究者の必要性に依存する。例えば、説明された全分散の80%に満足するのであれば、それを達成するために必要な次元の数を使用する。

最初の数次元が変動の大きな割合を占めている場合、良好な次元削減が達成されることに留意されたい。

今回の分析では、最初の2軸で変動の88.6%を説明している。これは、許容できるほど大きな割合だ。

次元数を決定する別の方法は、固有値/分散を最大から最小に並べたプロットであるScree Plotを見ることだ。成分の数は、残りの固有値がすべて比較的小さく、同等のサイズである点を超えて決定さ れる。

scree plot は関数fviz_eig()またはfviz_screeplot()[factoextra package]を用いて作成することができる。

fviz_screeplot(res.ca, addlabels = TRUE, ylim = c(0, 50))

scree plotが曲がる点(いわゆる " elbow " )は、最適な次元を示すと考えることができる。

また、軸を解に残すべき平均固有値をそれ以上算出することも可能だ。

我々のデータには13行と4列が含まれている。

もしデータがランダムであれば、各軸の固有値の期待値は行の観点から 1/(nrow(housetasks)-1) = 1/12 = 8.33%になるはずである。

同様に、平均軸は4列の観点から1/(ncol(housetasks)-1) = 1/3 = 33.33%を占めるはずである。

According to (M. T. Bendixen 1995):

この2つの割合の最大値よりも大きな寄与率を持つ軸は、重要であるとみなし、データの解釈のための解に含める必要がある。

以下のRコードでは、平均固有値を指定した赤い破線でscree plotを描画している。

fviz_screeplot(res.ca) +
 geom_hline(yintercept=33.33, linetype=2, color="red")

上のグラフによると、解答には次元1と2のみが使用されるべきだ。3次元は全慣性の11.4%しか説明できず、平均的な固有値(33.33%)を下回り、さらなる解析のためには少なすぎる値だ。

2つ以上の次元を使用することができることに注意。しかし、補足的な次元は、行と列の間の関連性の解釈には、あまり寄与しないだろう。

次元と2次元は、それぞれ全慣性の約48.7%と39.9%を説明している。これは、2次元が保持するイナーシャの累積が88.6%であることに相当する。保持率が高いほど、元データの微妙なニュアンスが低次元解に保持されていることになる(M. Bendixen 2003)。

バイプロット

行と列の変数のバイプロットを描くには、関数fviz_ca_biplot()[factoextra package] を使用する。

# repel= TRUE: テキストが重ならないようにする(多点だと遅い)
fviz_ca_biplot(res.ca, repel = TRUE)

上のグラフはsymetric plotと呼ばれ、データ内のグローバルなパターンを示している。行は青い点、列は赤い三角形で表される。

任意の行または列の点間の距離は、それらの類似性(または非類似性)の指標を与える。プロファイルが類似している行点は、ファクターマップ上で閉じている。列点についても同様である。

このグラフからわかることは: 夕食、朝食、洗濯などの家事は妻が行うことが多い 運転や修理は夫が行う

symetric plotクは、行と列のプロファイルを共通の空間で同時に表現する。この場合、行点間の距離または列点間の距離のみが、本当に解釈できる。
どの行と列の項目間の距離も意味を持たない! 観察されたパターンについて、一般的な記述をすることができるだけだ。
列と行の間の距離を解釈するためには、列のプロファイルを行のスペースに表示するか、またはその逆を行わなければならない。このようなマップは非対称バイプロットと呼ばれ、この記事の最後に説明されている。

解釈のための次のステップは、モデルで保持されるさまざまな次元の定義において、どの行と列の変数が最も貢献しているかを決定することである。

行変数のグラフ

結果

行変数の結果を抽出するために、関数get_ca_row()[in factoextra]が使用さ れる。この関数は、行変数の座標、cos2、寄与度、慣性を含むリストを返す。

row <- get_ca_row(res.ca)
row
Correspondence Analysis - Results for rows
 ===================================================
  Name       Description                
1 "$coord"   "Coordinates for the rows" 
2 "$cos2"    "Cos2 for the rows"        
3 "$contrib" "contributions of the rows"
4 "$inertia" "Inertia of the rows"

get_ca_row()関数のコンポーネントは、以下のように行のプロットに使用することができる。

  • row$coord: 各次元(1,2,3)の各行点の座標。散布図の作成に使用
  • row$cos2: 行の表現の質
  • var$contrib: 次元の定義に対する行の寄与度(%)

なお、行点のプロットは可能で、i) ファクターマップの品質 (cos2) または ii) 次元の定義への寄与度 (contrib) に応じて色を付けることができる。

コンポーネントへのアクセスは以下の通り:

# 座標
head(row$coord)
# Cos2: ファクトリーマップ上の品質
head(row$cos2)
# 主成分への寄与
head(row$contrib)

このセクションでは、行の点のみを可視化する方法を説明する。次に、i) ファクターマップ上での表現の質、またはii) 次元への貢献度のいずれかによって、行をハイライトする。

行点の座標

以下のRコードでは、各次元(1、2、3)の各行点の座標を表示している。

head(row$coord)
                Dim 1      Dim 2       Dim 3
Laundry    -0.9918368  0.4953220 -0.31672897
Main_meal  -0.8755855  0.4901092 -0.16406487
Dinner     -0.6925740  0.3081043 -0.20741377
Breakfeast -0.5086002  0.4528038  0.22040453
Tidying    -0.3938084 -0.4343444 -0.09421375
Dishes     -0.1889641 -0.4419662  0.26694926

行点のみを可視化するには、関数fviz_ca_row()[in factoextra] を使用する。

fviz_ca_row(res.ca, repel = TRUE)

引数col.rowshape.rowを用いて、以下のように行点の色や形状を変更することが可能だ。

fviz_ca_row(res.ca, col.row="steelblue", shape.row = 15)

上のプロットは、行点間の関係を示している。

  • 似たようなプロファイルを持つ行は一緒にグループ化されている。
  • 負の相関を持つ行は、プロットの原点の反対側に配置さ れる(反対側の象限)。
  • 行点と原点間の距離は、ファクターマップ上の行点の品質を測定する。原点から離れた行点は、ファクターマップ上でよく表現される。