この投稿は 「R Advent Calendar 2017 - Qiita」 の 4日目の記事です。
こんにちは、akiyoko です。
「R Advent Calendar 2017」は 3年ぶり 2回目の参加になります。 *1
何をしたのか?
「あなたの趣味は?」というアンケート結果に対して「因子分析」を実施 することで回答の奥に潜む共通要因を探り、どんな趣味趣向を持った人たちがアンケートに回答してくれていたのか? を分析してみました。
具体的にはこんなシチュエーションです。
現在、アンケートの回収に Google Forms を使っていて、回答項目の一つに「あなたの趣味は何ですか?」(*2)という項目が含まれています。例えばこんな感じです(実際には他にも項目があります)。
Q1.あなたの趣味は何ですか? 当てはまるものを次の中から全てお答えください
【選択肢】特に無い/将棋/囲碁/チェス/ポーカー/麻雀/その他のボードゲーム・テーブルゲーム/TVゲーム・PCゲーム(携帯用を含む)/映画鑑賞/音楽鑑賞/楽器演奏/演芸・演劇鑑賞/美術鑑賞/スポーツ観覧/ダンス/料理・お菓子作り/ガーデニング/読書/ネットサーフィン/パチンコ・パチスロ/競馬・競輪・競艇/カラオケ/その他(自由回答)
回答結果をグラフにすると、以下のようになりました。
しかしながら、このままでは面白くない。何か新しい視点で分析できないものか? *3
ということで、このアンケート回答者の趣味の傾向から、どんなクラスタの人たちがアンケートに回答してくれているのか?ということを趣味の背後に潜んでいる共通因子から推測してみよう、と思い立ったわけです。
そもそも因子分析とは?
こちらの説明が非常に分かりやすいです。
- 因子分析は,複数の変数間の関係性を探る際によく用いられる手法である(ただし正確には潜在的な変数を仮定するのだが,以下に説明する)。
- 因子分析をする目的は,「因子」を見つけることである。
- 因子とは,実際に測定されるものではなく,測定された変数間の相関関係をもとに導き出される「潜在的な変数」(観測されない,仮定された変数)である。
- 言い換えると,因子分析とは「ある観測された変数(たとえば質問項目)が,どのような潜在的な因子から影響を受けているか」を探る手法といえる。
「心理データ解析第8回(1)」より
よく「主成分分析」と混同しやすい「因子分析」ですが、
- 因子分析をする目的は「共通因子を見つけること」である
- その一方で,主成分分析の目的は「情報を縮約すること」である。
「心理データ解析補足01」より
といった違いがあります。上記サイトの図が特に分かりやすいです。
私の感覚では、主成分分析は、主成分を1つに縮約して観測された変数に重み付けをして各データ行の「合計得点」を求めたいときや、主成分を2つに次元圧縮して特徴量を一つの散布図にまとめて表示するときに使うもの、と考えています。
なぜ R?
普段は Excel や Python でデータ分析をしていて R は使わないのですが、私の知る限りでは、因子分析に関しては Excel 単体ではできず、Python でも簡単にできるようなものがありません(scikit-learn には sklearn.decomposition.FactorAnalysis というクラスがあるのですがそれを使ったサンプルが何故かあまりありません。主成分分析をするサンプルならいつくもあるのですが・・)。
その点、R なら超簡単に出来てしまうことが分かってからは、因子分析には R を利用するようにしています。
実践
ここからが本番です。
Google Forms のアンケート結果をクレンジングしてファイルを CSV形式で保存し、R に読み込ませて分析します。
データクレンジング
Google Forms からアンケート結果を xlsx形式でエクスポートすると、こんな感じになっています。
Excel関数を使ってチェックボックス形式のデータを整形します。
具体的には、別の Excelファイルを新規作成し、(選択肢として不要なので)「特に無い」「その他」の列を削除した後、以下のようにして「0」「1」のデータに変換します。
[ファイル]>[名前を付けて保存]から、ファイルを CSV 形式で保存します。
ファイル名は、例えば「factor_analysis.csv」など、日本語を使わない方が無難です(RStudio から読み込めない可能性があります)。
将棋,囲碁,チェス,ポーカー,麻雀,その他のボードゲーム・テーブルゲーム,TVゲーム・PCゲーム(携帯用を含む),映画鑑賞,音楽鑑賞,楽器演奏,演芸・演劇鑑賞,美術鑑賞,スポーツ観覧,ダンス,料理・お菓子作り,ガーデニング,読書,ネットサーフィン,パチンコ・パチスロ,競馬・競輪・競艇,カラオケ 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0 (以下略)
RStudio にデータ投入
インストールしていない場合は、公式ダウンロードページ から RStudio をダウンロードしてインストールします。
私が使ったバージョンは、RStudio for Mac(Version 1.0.153)です。
作成した CSVファイルを読み込みます。
> data <- read.csv(file="~/Downloads/factor_analysis.csv", header=T, fileEncoding="Shift-JIS") > head(data)
将棋 囲碁 チェス ポーカー 麻雀 その他のボードゲーム.テーブルゲーム TVゲーム.PCゲーム.携帯用を含む. 映画鑑賞 音楽鑑賞 楽器演奏 演芸.演劇鑑賞 美術鑑賞 スポーツ観覧 ダンス 料理.お菓子作り 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 4 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 5 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 6 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 ガーデニング 読書 ネットサーフィン パチンコ.パチスロ 競馬.競輪.競艇 カラオケ 1 0 0 1 0 0 0 2 0 0 0 0 1 0 3 0 1 1 0 0 0 4 0 0 1 0 0 0 5 0 0 0 0 0 0 6 0 1 0 0 0 0
上記は CSV ファイルのエンコード形式が「Shift-JIS」の場合の記述ですが、もし「UTF-8」にした場合は「fileEncoding="UTF-8"」とすれば OK です。
RStudio で因子分析
以降は、ほぼ「Rで因子分析やってみた」のままです。
まずは、因子数を決定します。
> c <- cor(data) > e <- eigen(c)$values > e
[1] 2.7796088 2.6282309 1.7220938 1.6669475 1.4724370 1.3176913 1.2386144 1.0709480 0.9855064 0.8927945 0.7569210 0.6899642 0.6341069 0.6018854 0.5724795 0.4168670 0.3761065 0.3551432 0.3143882 [20] 0.2790165 0.2282491
固有値のグラフをスクリープロットとして出力します。
> plot(e, type="b", main="Scree Plot", xlab="Number", ylab="Eigenvalue")
固有値の減少がなだらかになる直前までの固有値の数を因子数とする(スクリー基準)、および、因子数の基準となる固有値の最小値を「1」とする(カイザーガットマン基準)を考慮して、因子数を「6」としました。 *4, *5
最後に、因子数を 6 として因子分析をおこないます。
> factanal(x=data, factors=6, rotation="promax")
「rotation」の引数は、"none", "varimax", "promax" などがありますが、今回は、因子間の相関を仮定しないする(2017.12.26 訂正)プロマックス回転「 promax」を選択しました。 *6
この結果を因子負荷量の大小で色付けすると、以下の表のようになります。
上記の表から、以下のように共通因子(趣味趣向クラスタ)を分類してみました。あくまでも仮説ですが。
- 因子1:「麻雀」「囲碁」「将棋」の因子負荷量が大きい ・・・ 囲碁将棋系
- 因子2:「美術鑑賞」「演芸・演劇鑑賞」の因子負荷量が大きい ・・・ アート系?
- 因子3:「楽器演奏」「料理・お菓子作り」「ダンス」の因子負荷量が大きい ・・・ 音楽系?
- 因子4:「競馬・競輪・競艇」「パチンコ・パチスロ」の因子負荷量が大きい ・・・ ギャンブル系
- 因子5:「その他のボードゲーム・テーブルゲーム」「チェス」の因子負荷量が大きい ・・・ その他のボードゲーム系
- 因子6:「映画鑑賞」「音楽鑑賞」の因子負荷量が大きい ・・・ オーソドックスな趣味系?
一部強引なところもあるかもしれませんが、アンケートに回答した人が「ああ、私はこの趣味趣向クラスタだな」と分かりやすいような分類になっているのではないかと思います。
まとめ
- 因子分析は R でやれば超簡単
- 数行で書けるよ
これを言うためだけに 8000字オーバーの記事を書いてしまいました。。
明日は、yamano357 さんの「R Advent Calendar 2017 - Qiita」 5日目の記事です。
よろしくお願いします。
おまけ
因子分析の結果表示でそれぞれの出力行がガタついて項目がズレてしまう場合は、
[Preferences]>[Appearance]から、Editor font に「Osaka-Mono」を選択すれば解決します(Mac の場合)。
今回の場合はグラフ描画時に日本語を出力していませんが、RStudio でグラフを描画する際に文字化けしてしまう場合は、
par(family="HiraKakuProN-W3")
と事前に実行しておけばよいです。 *7
*1:《過去記事》akiyoko.hatenablog.jp
*2:今回はインドア系の趣味についてのみアンケートしました。
*3:選択肢に挙げた15種類の趣味は、総務省統計局が5年ごとに実施している「社会生活基本調査」(出典:平成28年 社会生活基本調査結果(総務省統計局))の「趣味・娯楽」の34種類の区分のうちの15種類と一致させているので、やろうと思えば、その種類別行動者数(≒趣味にしている人の割合)と照らし合わせることで世間一般の平均的な趣味趣向と比較することもできます。
*4:http://cogpsy.educ.kyoto-u.ac.jp/personal/Kusumi/datasem06/minemoto.pdf
*5:実際には「5」から「7」を順次選んで計算したところ、「6」が結論を導きやすかったという理由もあります。