「金塊か、キノコ料理か」(外れ値検出問題)を解く[クラスター分析]
外れ値とは他のデータから離れているという意味なので、次のようにクラスター分析を用いれは見つけられそうです。
ここではクラスター分析の代表的な手法であるk平均法(k-means)と階層的方法を用います。
結果を先に述べると、87番目と100番目のデータのどちらかが外れ値と推測されます。
階層的クラスタリング
標準化後のデータをクラスタリングした結果は下図(デンドログラム)のとおりです。クラスタ間距離の測り方によって結果は異なりますが、全般的に100番目と87番目のデータが外れ値のようです。
gold.clust <- hclust(dist(gold)^2, method="average") #平均法の場合 plot(gold.clust,cex=0.8)
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
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