外れ値となるアイマスメンバーを探す

Journal ClubでFRaCという機械学習を紹介した。
最後に、確認としてこんな問題を出した。

アイドル174人分のデータセットimas1.txtがある。
この中で他のメンバーとは明らかに違う特徴をもったアイドルがいる。MinPtsを10程度に設定して検出し、オレの好きな渋谷凛ちゃんとGoogle検索で画像を探しだして比較せよ。

というわけでやってみる。
imas1.txtは下で。
 
LOFでやってみる。

data0 <- read.delim("~/Desktop/imas1.txt")
data1 <- data0[, -1]
library(Rlof)
lof0 <- lof(data1, 2:100)
plot(lof0[, 5], ylab="anomaly score", pch=16, main="LOF, MinPts = 5")
Anomal0 <- apply(lof0, 2, order, decreasing=TRUE) 
data0$name[Anomal0[, 5]] #外れ値のアイドル


 
SVMでやってみる。

library(e1071)
svm0 <- svm(data1)
anomaly_score <- svm0$decision.value
data0$name[order(anomaly_score)] #外れ値のアイドル
plot(anomaly_score, main="SVM", pch=16)


 
FRaCでやってみる。
Python上でFRaCをやるとき、アイドルの名前とヘッダーは邪魔っぽいのでそれらを削除しておく。

# detect スクリプトがある frac ディレクトリで
python detect -X ~/Desktop/imas1FRaC.txt -Q ~/Desktop/imas1FRaC.txt -T -R -N -S -w ~/Desktop/weka-3-6-9/weka.jar > imasFRaC_anomaly_score.txt
# Training set examples: 174
# Test set examples:     174
# Infer feature types from imas1FRaC.txt
# 6 feature types (column, type, values):
# 1	continuous	9,31
# 2	continuous	127,182
# 3	continuous	28,60
# 4	continuous	60,105
# 5	continuous	47,65
# 6	continuous	65,93
# @0.02 seconds:  Feature #1, Decision Stump ...
# @0.03 seconds:  Feature #1, svm-train -s 3 -t 0 ...
# @0.50 seconds:  Feature #1, svm-train -s 3 -t 2 ...
# @0.68 seconds:  Feature #1, weka.classifiers.trees.REPTree ...
# @4.80 seconds:  Feature #2, Decision Stump ...
# @4.82 seconds:  Feature #2, svm-train -s 3 -t 0 ...
# @5.18 seconds:  Feature #2, svm-train -s 3 -t 2 ...
# @5.38 seconds:  Feature #2, weka.classifiers.trees.REPTree ...
# @9.53 seconds:  Feature #3, Decision Stump ...
# @9.55 seconds:  Feature #3, svm-train -s 3 -t 0 ...
# @10.02 seconds:  Feature #3, svm-train -s 3 -t 2 ...
# @10.23 seconds:  Feature #3, weka.classifiers.trees.REPTree ...
# @14.42 seconds:  Feature #4, Decision Stump ...
# @14.44 seconds:  Feature #4, svm-train -s 3 -t 0 ...
# @14.85 seconds:  Feature #4, svm-train -s 3 -t 2 ...
# @15.06 seconds:  Feature #4, weka.classifiers.trees.REPTree ...
# @19.32 seconds:  Feature #5, Decision Stump ...
# @19.33 seconds:  Feature #5, svm-train -s 3 -t 0 ...
# @19.85 seconds:  Feature #5, svm-train -s 3 -t 2 ...
# @20.05 seconds:  Feature #5, weka.classifiers.trees.REPTree ...
# @24.20 seconds:  Feature #6, Decision Stump ...
# @24.22 seconds:  Feature #6, svm-train -s 3 -t 0 ...
# @24.75 seconds:  Feature #6, svm-train -s 3 -t 2 ...
# @24.99 seconds:  Feature #6, weka.classifiers.trees.REPTree ...
# @29.22 seconds:  Write normalized surprisal ...
fracAS <- c(as.matrix(read.delim("~/Desktop/imasFRaC_anomaly_score.txt", header=FALSE)))
data0$name[order(fracAS, decreasing=TRUE)] #外れ値のアイドル
plot(fracAS, ylab="anomaly score", pch=16, main="FRaC")


 
LOF, SVM, FRaCの3つの手法で外れ値アイドルを検出した。anomaly scoreの大きなものから選び出すと

Agirls <- list(data0$name[Anomal0[, 5]], data0$name[order(anomaly_score)], data0$name[order(fracAS, decreasing=TRUE)])
TopAS <- sapply(Agirls, as.character)
colnames(TopAS) <- c("LOF", "SVM", "FRaC")
head(TopAS)
     LOF          SVM          FRaC        
[1,] "諸星きらり" "諸星きらり" "及川雫"    
[2,] "及川雫"     "及川雫"     "諸星きらり"
[3,] "片桐早苗"   "佐城雪美"   "佐城雪美"  
[4,] "西川保奈美" "市原仁奈"   "市原仁奈"  
[5,] "白坂小梅"   "横山千佳"   "横山千佳"  
[6,] "望月聖"     "海老原菜帆" "海老原菜帆"

このアイドルたちがなぜ外れ値なのかを検討すると

data0[mapply(function(x) which(data0$name == x), unique(c(head(TopAS)))), ]
          name age height weight   B  W  H
150 諸星きらり  17    182     60  91 64 86
137     及川雫  16    170     56 105 64 92
141   片桐早苗  28    152     47  92 58 84
102 西川保奈美  16    155     55  88 60 86
99    白坂小梅  13    142     34  65 50 70
113     望月聖  13    150     37  82 56 86
94    佐城雪美  10    137     30  63 47 65
156   市原仁奈   9    128     29  61 57 67
23    横山千佳   9    127     31  60 55 65
136 海老原菜帆  17    162     58  92 65 93

諸星きらり及川雫が上位に挙がった。おそらくこれは日本人離れしすぎたプロポーションのせいだとおもわれる。
諸星きらりの182cmとかオレよりでけぇよ。
あとは佐城雪美、市原仁奈や横山千佳など、あまりにもロリィなアイドルが挙がった。
182cmという上背を考慮して、諸星きらりを外れ値アイドルにします。