Rによるデータ分析

Rによる外れたサンプルの探索

外れたサンプルの探索 をRで実施する時の例です。

このページは、特に外れたサンプルに注目したい時の方法になります。

高次元を2次元に圧縮して可視化 で外れたサンプルを探索する方法は、 Rによる高次元を2次元に圧縮して可視化 と手順が変わらないので、このページでは紹介していません。

1次元

ヒストグラム

外れたサンプルは、数が少ないので、通常のヒストグラムでは、見落とすことがあります。 ここでは、 ggplot2Plotly を組み合わせて、範囲を自由に変えられるグラフにしています。

library(ggplot2) # ライブラリを読み込み
library(plotly))
# ライブラリを読み込み
setwd("C:/Rtest")
# 作業用ディレクトリを変更
Data1 <- read.csv("Data.csv", header=T)
# データを読み込み
ggplotly(ggplot(Data1, aes(x=X1)) + geom_histogram()))
# ヒストグラムを描く
outlier outlier outlier
ヒストグラムは、最初、一番左のものができます。 真ん中のグラフのようにして、範囲を選択すると、一番右のものができます。 すると、20のあたりのサンプルが見えやすくになります。

箱ひげ図(ボックスプロット)

箱ひげ図 は、上下の四分位点の幅の1.5倍のところに、「ひげ」を描き、それよりも離れたサンプルは外れているものとして、「点」で表します。

library(ggplot2) # ライブラリを読み込み
library(plotly))
# ライブラリを読み込み
setwd("C:/Rtest")
# 作業用ディレクトリを変更
Data1 <- read.csv("Data.csv", header=T)
# データを読み込み
ggplot(Data1, aes(y=X1)) + geom_boxplot()
# 箱ひげ図を描く
outlier

スミルノフ=グラブス検定

スミルノフ=グラブス検定は、1次元のデータについて、分布の一番外側のサンプルについて、外れ値がどうかを判定します。

library(outliers)# ライブラリを読み込み
setwd("C:/Rtest")
# 作業用ディレクトリを変更
Data <- read.csv("Data.csv", header=T)
# データを読み込み
grubbs.test(Data[,1])
# 1列目のデータをスミルノフ=グラブス検定
outlier
この場合は、最大値の「20」が外れ値かどうかを検定して、p値がかなり小さいので、外れ値と判定したことになります。

p値で判定することになるのですが、p値はサンプル数が多いと、小さな値になりやすいです。 筆者は目安として、「サンプル数が30位までの時は、p値が0.01よりも大きかったら、外れ値ではない」、と考えています。 30よりも大きいと、この方法で外れ値を定量的に判断はできないと思っています。

多次元

クラスター分析(階層型)

クラスター分析 の階層型を使う方法です。 階層型はいろいろありますが、外れ値を見つけやすいのは、最近接法(single)なので、下記はsingleにしています。

また、デンドログラムは、plotlyと組み合わせて、拡大できるようにしています。

library(plotly)
library(ggdendro)
setwd("C:/Rtest")
# 作業用ディレクトリを変更
Data1 <- read.csv("Data.csv", header=T)
# データを読み込み
Data10 <- Data1[,1:2]#
# クラスター分析に使うデータを指定。ここでは1〜2列目の場合
Data11_dist <- dist(Data10)
# サンプル間の距離を計算
hc <- hclust(Data11_dist, "single")
# 最近接法による階層型クラスター分析
ggplotly(ggdendrogram(hc, segments = TRUE, labels = TRUE, leaf_labels = TRUE, rotate = FALSE, theme_dendro = TRUE))
# 拡大可能なデンドログラム
outlier outlier
最初にできるデンドログラムが左で、そのデンドログラムの左側を拡大すると、右になります。 グラフの縦軸は、距離に相当するものなので、 1番目と、2番目のサンプルが、他の大多数からは離れていることが、このグラフからわかります。

output <- cutree(hc,k=3)# 3個にグループ分け
Data <- cbind(Data1, output)  # 最初のデータセットにグループ分けの結果を付ける
Data$output <-factor(Data$output) # グループの変数を文字列型にする
ggplot(Data, aes(x=X1, y=X2)) + geom_point(aes(colour=output))# 二次元散布図 色分け・形分け
outlier
外れたサンプルは、「1」、「2」というグループになり、大多数が含まれれる「3」のグループと区別できています。

クラスター分析(DBSCAN)

クラスター分析 のDBSCANを使う方法です。

library(ggplot2) # ライブラリを読み込み
setwd("C:/Rtest")
# 作業用ディレクトリを変更
Data1 <- read.csv("Data.csv", header=T)
# データを読み込み
Data10 <- Data1[,1:2]#
# クラスター分析に使うデータを指定。ここでは1〜2列目の場合
Data11 <- Data10
# 出力先の行列を作る
for (i in 1:ncol(Data10)) {
# ループの始まり。データの列数を数えて同じ回数繰り返す
Data11[,i] <- (Data10[,i] - min(Data10[,i]))/(max(Data10[,i]) - min(Data10[,i]))
}
# ループの終わり
Data11_dist <- dist(Data10)
# サンプル間の距離を計算
library(dbscan)
# ライブラリを読み込み
dbs <- dbscan(Data11, eps = 0.2)
# DBSCANで分類。epsは、コア点からの距離の範囲です。ここでは、0.2にしました。
output <- dbs$cluster
# 分類結果の抽出
Data <- cbind(Data1, output) 
# 最初のデータセットにグループ分けの結果を付ける
Data$output <-factor(Data$output) # グループの変数を文字列型にする
ggplot(Data, aes(x=X1, y=X2)) + geom_point(aes(colour=output))# 二次元散布図 色分け・形分け
outlier
外れたサンプルは、「0」というグループになります。

LOF

LOF を使う方法です。

library(Rlof)# ライブラリを読み込み
library(ggplot2)
# ライブラリを読み込み
setwd("C:/Rtest")
# 作業用ディレクトリを変更
Data <- read.csv("Data.csv", header=T)
# データを読み込み
Data1 <- Data
# 加工用のデータの作成
Data1 <- Data[,1:2]
# 分析するデータを1から2列目で指定
LOF <- lof(Data1,5)
# LOF。近傍の5個を使う場合
Data2 <- as.data.frame(cbind(LOF ,Data))
# データを合体
ggplot(Data2, aes(x=X1, y=X2)) + geom_point(aes(colour=LOF))+ggtitle("LOF")+ scale_color_viridis_c(option = "D")
# 散布図を描く
outlier
ggplot(Data2, aes(y=LOF)) + geom_boxplot()# 箱ひげ図を描く
outlier
外れている2個のサンプルのLOFは、高く計算されました。

One-Class SVM

One-Class SVMで、分布の内側と外側を分ける方法です。

library(ggplot2) # ライブラリを読み込み
library(kernlab)
# ライブラリを読み込み
setwd("C:/Rtest")
# 作業用ディレクトリを変更
Data1 <- read.csv("Data.csv", header=T)
# データを読み込み
Data10 <- Data1[,1:2]
# クラスター分析に使うデータを指定。ここでは1〜2列目の場合
Data11 <- transform(Data10, type=1)
# ラベルの列を追加
OC <- ksvm(type~.,data=Data11,type='one-svc', kernel="besseldot", nu = 0.01)
# nuは外れ値の割合
output <- predict(OC,Data11)
# 分類結果の抽出

#カーネルがanovadot
OC <- ksvm(type~.,data=Data11,type='one-svc', kernel="anovadot", nu = 0.01)# nuは外れ値の割合

#カーネルがrbfdot
OC <- ksvm(type~.,data=Data11,type='one-svc', kernel="rbfdot", nu = 0.01)# nuは外れ値の割合

Data <- cbind(Data1, output)  # 最初のデータセットにグループ分けの結果を付ける
Data$output <-factor(Data$output) # グループの変数を文字列型にする
ggplot(Data, aes(x=X1, y=X2)) + geom_point(aes(colour=output))# 二次元散布図 色分け・形分け
outlier
外れたサンプルは、「FALSE」というグループになります。




Tweet データサイエンス教室