verum ipsum factum

sudillap's blog

「金塊か、キノコ料理か」(外れ値検出問題)を解く[クラスター分析]

外れ値とは他のデータから離れているという意味なので、次のようにクラスター分析を用いれは見つけられそうです。

  • データを一つしか含まない孤立したクラスターに分類されたデータ
  • クラスターの中心から離れた場所にあるデータ

ここではクラスター分析の代表的な手法であるk平均法(k-means)階層的方法を用います。

結果を先に述べると、87番目と100番目のデータのどちらかが外れ値と推測されます。

階層的クラスタリング

標準化後のデータをクラスタリングした結果は下図(デンドログラム)のとおりです。クラスタ間距離の測り方によって結果は異なりますが、全般的に100番目と87番目のデータが外れ値のようです。

gold.clust <- hclust(dist(gold)^2, method="average") #平均法の場合
plot(gold.clust,cex=0.8)

f:id:sudillap:20130325105552p:plainf:id:sudillap:20130325105600p:plainf:id:sudillap:20130325105606p:plainf:id:sudillap:20130325105609p:plainf:id:sudillap:20130325105615p:plainf:id:sudillap:20130325105616p:plainf:id:sudillap:20130325105619p:plain

k平均法1

3次元散布図から、このデータは大きく2つのクラスターに分けることができます。
k平均法でデータを2つに分けたとき、各クラスターの中心から最も離れているデータを外れ値とします。

次の図の青色のデータが外れ値候補上位5つ(1,2,4,87,100番)となります。

n.cluster <- 2
km <- kmeans(gold,n.cluster,nstart=30)
centers <- km$centers[km$cluster,]
outliers <- order(rowSums((gold-centers)^2),decreasing=TRUE)[1:5]
outliers
[1]   1   2 100  87   4

f:id:sudillap:20130325110312p:plain

k平均法2

ここでもk平均法を用いますが、別のアイデアで外れ値を探してみます。

クラスター数を増やしていけば、ある時点で外れ値のみを含むクラスターが生成されると考えられます。
データを一つだけ含むクラスターが複数個できた時点のクラスター情報をもとに、外れ値を探します。

Rスクリプトとその実行結果は次のとおりです。73番目と100番目を外れ値とみなせそうです。

max.outlier <- 3
outliers <- c()
for(iter in 1:20){
  for(i in 2:40){
    gold.kmeans <- kmeans(gold,i,nstart=30)
    found <- which(gold.kmeans$size==1)
    if(length(found)>=max.outlier){
      break
    }
  }
  outliers <- c(outliers, which(gold.kmeans$cluster %in% found))
}
table(outliers)
outliers
 22  73  79  87 100 
 12  19   3  11  20