はじめに
この記事では統計検定準1級レベルのクラスター分析について扱います。内容の多くは2017年6月の過去問を参考にしています。
まずは統計検定準1級の出題範囲表を確認します。だいたい以下の内容が抑えられればよしとしましょう。
大項目 | 小項目 | 項目例 |
---|---|---|
多変量解析 | クラスター分析 | 階層型クラスター分析・デンドログラム、 k-means法、距離行列 |
クラスター分析とは
クラスター分析(cluster analysis)とは、異なる性質が混ざった集団から、互いに似た性質のものを集めクラスター(集まり)を作る分析方法です。あらかじめ分類の基準が決まっていない(≒分類のための外的基準が与えられない)教師なしの分類法です。
クラスター分析は、階層型クラスター分析と非階層型クラスター分析に大別できます。階層型クラスター分析は、最も似ている組み合わせから順番にクラスターにしていく方法です。途中過程が階層のように表せるため、アウトプットとして樹形図(デンドログラム)を描くことができます。一方、非階層クラスター分析は階層的な構造を持ちません。これはあらかじめクラスターの数を決め、決めた数にサンプルを分割する方法です。アウトプットとして散布図を描くことができます。サンプル数が大きいビッグデータを分析するときに適しています。
階層型クラスター分析
生徒1~生徒5の数学(math)と英語(eng)のテスト結果を用いて、階層型クラスター分析をやってみます。階層型クラスター分析は、次のステップで行います。
- データ行列を作成する
- この行列に対して、個体間の距離を計算した距離行列を作成する
- クラスター間の距離の求め方(最近隣法や最遠隣法等)を選択し、コーフェン行列を求める
- コーフェン行列に基づき樹形図を描く
データ行列を作成する
> math <- c(10,10,9,7,6) > eng <- c(10,8,6,8,7) > n <- 5 > data <- data.frame(id = paste(1:n),math=math,eng=eng) > as.data.frame(data) id math eng 1 1 10 10 2 2 10 8 3 3 9 6 4 4 7 8 5 5 6 7
散布図を描いてみましょう。
> #scatter plot > ggplot(data = data, mapping = aes(x = math, y = eng)) + + geom_point() + + geom_text(aes(label=id),vjust = -0.5, color="blue")
距離行列を作成する
距離行列はデータ間の距離を配列して行列の形に並べたものです。距離の求め方にも様々ありますが、ここではユークリッド距離を用います。
> distance <- dist(data) > as.matrix(distance) 1 2 3 4 5 1 0.000000 2.000000 4.123106 3.605551 5.000000 2 2.000000 0.000000 2.236068 3.000000 4.123106 3 4.123106 2.236068 0.000000 2.828427 3.162278 4 3.605551 3.000000 2.828427 0.000000 1.414214 5 5.000000 4.123106 3.162278 1.414214 0.000000
距離行列を確認すると、最も近いのは{生徒4,生徒5}の組の1.41だと分かります。ここでまずクラスターが形成されます。次に小さい距離は{生徒1,生徒2}の組の2.00であり、2番目のクラスターが形成されます。最後に残るのが{生徒3}です。こうして{生徒4,生徒5},{生徒1,生徒2},{生徒3}と3つのクラスターが形成されます。
クラスター間の距離を求める
クラスター間の距離の求め方は最近隣法、最遠隣法、群平均法、メディアン法 、重心法、ウォード法など複数あります。ここでは最近隣法と最遠隣法を扱います。簡単に説明すると、
- 最近隣法
別名単連結法 (single-linkage) 法。2つのクラスターのそれぞれの中から1個ずつ個体を選び、最も近い個体間の距離をクラスター間の距離とする方法。
- 最遠隣法
別名完全連結 (complete-linkage) 法。2つのクラスターの中のそれぞれの中から1個ずつ個体を選び、最も離れた個体間の距離をこの2つのクラスター間の距離とする方法。
クラスター間の距離を表す行列をコーフェン行列と呼びます。
> #最近隣法 > single <- hclust(distance, "single") > #最遠隣法 > complete <- hclust(distance,"complete") > > #最近隣法のコーフェン行列 > cophenetic(single) 1 2 3 4 2 2.000000 3 2.236068 2.236068 4 2.828427 2.828427 2.828427 5 2.828427 2.828427 2.828427 1.414214 > #最遠隣法のコーフェン行列 > cophenetic(complete) 1 2 3 4 2 2.000000 3 5.000000 5.000000 4 5.000000 5.000000 3.162278 5 5.000000 5.000000 3.162278 1.414214
樹形図を描く
最後に樹形図を描きます。
> plot(single,hang = -1,main="Single-linkage") > plot(complete,hang = -1,main="Compete-linkage")
樹形図の縦軸は距離(クラスターから伸びる枝の長さ)です。左の最近隣法の方が、クラスター間の距離が近くなっていることが分かります。
階層クラスター分析では、あらかじめクラスター数を決めません。似ているもの同士から順番にクラスターを形成していけばよいので、後からクラスター数を決めることができます。上図の結果を使って、3つのクラスターに分割してみましょう。
> plot(single,hang = -1,main="Single-linkage") > rect.hclust(single, k=3) > plot(complete,hang = -1,main="Compete-linkage") > rect.hclust(complete, k=3)
各生徒がどのクラスターに含まれるかはcutree()を使えば確認できます。
> cutree(tree=single,k=3) [1] 1 1 2 3 3 > cutree(tree=complete,k=3) [1] 1 1 2 3 3
非階層型クラスター分析
k-means法
先ほどと同じデータを使って非階層クラスタリングを行います。ここではk-平均法(k-means method)を使います。k-means法はクラスターの平均(mean)を使い、あらかじめ決められた数のクラスター数(k個)に分割するためのアルゴリズムです。k=2個のクラスターに分割する場合、
クラスター中心の初期点を生徒1、生徒2とします。先ほどの距離行列を見ると、生徒3,4,5からはいずれも生徒2までの距離の方が近いため、初期点に対して{1}と{2,3,4,5}の2つのクラスターに割り当てられます。クラスター{2,3,4,5}の重心を計算すると、(8,7.25)だと分かります。これを先ほどの散布図に追加します。
ここで新たなクラスター中心は生徒1(10,10)と{2,3,4,5}の重心(8,7.25)となりました。重心(8,7.25)を先ほどの距離行列に加える(下表の6)と、生徒3,4,5は生徒1(10,10)よりも重心(8,7.25)の方が近く、一方生徒2は生徒1(10,10)の方が近くなります。
> distance.add <- dist(data.add) > as.matrix(distance.add) 1 2 3 4 5 6 1 0.000000 2.236068 4.582576 4.690416 6.403124 4.164583 2 2.236068 0.000000 2.449490 3.605551 5.099020 2.616056 3 4.582576 2.449490 0.000000 3.000000 3.741657 1.960548 4 4.690416 3.605551 3.000000 0.000000 1.732051 1.530931 5 6.403124 5.099020 3.741657 1.732051 0.000000 2.468552 6 4.164583 2.616056 1.960548 1.530931 2.468552 0.000000
したがって、k-meas法の結果{1,2}と{3,4,5}のクラスターに分割されます。
散布図を描く
Rのコマンドkmeans()とclusplot()を使えば簡単です。
> #set initial centers > c1 <- c(data[1,2],data[1,3]) > c2 <- c(data[2,2],data[2,3]) > #2-means > km <- kmeans(data.r,rbind(c1,c2)) > result <- km$cluster > result [1] 1 1 2 2 2 > clusplot(data.r, km$cluster, color=TRUE, shade=TRUE, labels=2, lines=0)
{1,2}と{3,4,5}のクラスターに分割されることが確認できました。
ちなみにkmeans()の中身には各クラスターの平均等が含まれます。
> (km <- kmeans(data.r,rbind(c1,c2))) K-means clustering with 2 clusters of sizes 2, 3 Cluster means: math eng 1 10.000000 9 2 7.333333 7 Clustering vector: [1] 1 1 2 2 2 Within cluster sum of squares by cluster: [1] 2.000000 6.666667 (between_SS / total_SS = 60.6 %) Available components: [1] "cluster" "centers" "totss" "withinss" "tot.withinss" [6] "betweenss" "size" "iter" "ifault"
次はより規模の大きなデータを使って非階層クラスタリングをやってみたいと思います。以上、お読みいただきありがとうございました。
クラスター分析の出口は
階層・非階層ともにクラスター分析は、教師なし学習です。教師なし学習の目的は、データ内の隠れた構造やパターンを見つけることであり、仮説やモデルの「正しさ」を判断する基準を与えてくれる訳ではありません。p値や決定係数等の結果が出力される訳ではなく、何をもって仮説を検証できたと考えるのか、その線引きは主観に依らざるを得ません。ですので何かを検証するためというよりも、感覚や好み等定量化しにくいものを可視化するサポートツール、ぐらいの道具だと考えております。
参考資料
![日本統計学会公式認定 統計検定 1級・準1級 公式問題集[2016〜2017年] 日本統計学会公式認定 統計検定 1級・準1級 公式問題集[2016〜2017年]](https://m.media-amazon.com/images/I/51BLT89dHwL.jpg)
日本統計学会公式認定 統計検定 1級・準1級 公式問題集[2016〜2017年]
- 発売日: 2018/03/14
- メディア: 単行本(ソフトカバー)