今回は、Classification モデルの評価方法を取り上げる。
Confusion Matrix
以下のような流れで、スパム判定結果のデータから、スパム判定モデルを構築、confusion matrix で精度を測る。
- データを訓練用 spamTrain とテスト用 spamTest に分割
- 訓練データを線形回帰分析してモデル構築
- 訓練データとテストデータを説明変数にして、モデルで予測
- テストデータを説明変数にして、モデルで予測した結果から confusion matrix 化
> spamD <- read.table("Downloads/zmPDSwR-master/Spambase/spamD.tsv",
header=T, sep="\t")
# 単語毎の出現頻度
> colnames(spamD)
[1] "word.freq.make" "word.freq.address"
[3] "word.freq.all" "word.freq.3d"
...
[53] "char.freq.dollar" "char.freq.hash"
[55] "capital.run.length.average" "capital.run.length.longest"
[57] "capital.run.length.total" "spam"
[59] "rgroup"
# The number of non-spam and spam
> summary(spamD$spam)
non-spam spam
2788 1813
> spamTrain <- subset(spamD, spamD$rgroup>=10)
> spamTest <- subset(spamD, spamD$rgroup<10)
# 90% のデータを評価用(or 訓練用)、残りの 10% を判定用
> nrow(spamTrain); nrow(spamTest); nrow(spamTrain)+nrow(spamTest)
[1] 4143
[1] 458
[1] 4601
# カラム名から "rgroup","spam" を取り除く
> spamVars <- setdiff(colnames(spamD), list("rgroup","spam"))
# 線形回帰式
> spamFormula <- as.formula(paste('spam=="spam"',
paste(spamVars,collapse=' + '),sep=' ~ '))
> spamFormula
spam == "spam" ~ word.freq.make + word.freq.address +
...
+ capital.run.length.longest + capital.run.length.total
# 訓練データでモデル化
> spamModel <- glm(spamFormula,
family=binomial(link='logit'),
data=spamTrain)
警告メッセージ:
glm.fit: 数値的に 0 か 1 である確率が生じました
# Train, Test を説明変数にしてモデル入力して、「結果(response)=スパムか否か」を取得。
> spamTrain$pred <- predict(spamModel,
newdata=spamTrain,type='response')
> spamTest$pred <- predict(spamModel,
newdata=spamTest,type='response')
> (cM <- table(y=spamTest$spam, glmPred=spamTest$pred>0.5))
glmPred
y FALSE TRUE
non-spam 264 14
spam 22 158
注意:pred>0.5 で判定したが、必ずしもそうではなく、ROC カーブなどで決める。
次は、表 5.4 の Standard two-by-two confusion matrix 、先のスパム判定モデルの結果も含めている。
Prediction=NEGATIVE Prediction=POSITIVE
Truth mark=NOT IN True negatives (TN) False positives(FP)
CATEGORY cM[1,1]=264 cM[1,2]=14
Truth mark=IN False negatives(FN) True positives (TP)
CATEGORY cM[2,1]=22 cM[2,2]=158
これ以降、confusion matrix から読み取れる a performance measures of a classifier「分類器の性能値」を順に見ていく。ただ、confusion matrix の詳細は過去の投稿を参照(「Confusion Matrix 混合行列」)。
Accuracy:正解率
> (cM[1,1]+cM[2,2])/sum(cM)
[1] 0.9213974
スパムフィルターで「8% の誤検知」は高すぎる、つまり「このモデルの性能は悪い」。
次は、実際のスパムフィルターサービスの Akismet の混合行列。
> t <- as.table(matrix(data=c(288-1,17,1,13882-17),
nnrow=2,ncol=2))
Precision と Recall
precision TP / (TP+FP)
> cM[2,2]/(cM[2,2]+cM[1,2])
[1] 0.9186047
> t[2,2]/(t[2,2]+t[1,2])
[1] 0.9999279
スパム検知で precision が 92% とは、スパムとされた内で 8% が誤り(つまり「正常メール」)。Akismet の 99.99% がスパム検知で求められる性能値だろう。
recall TP / (TP+FN)
> cM[2,2]/(cM[2,2]+cM[2,1])
[1] 0.8777778
> t[2,2]/(t[2,2]+t[2,1])
[1] 0.9987754
それぞぞれの(accuracy, recall) が (91.86%, 88.77%), (99.99%, 99.87%) 。
つまり precision だけあっても意味がない。例えば、92% precision で 89 % recall では信頼性は高いとはいえない。
precision と recall について、まとめると
precision 等の算出時に、分母のセルがカラムだけで構成する場合、分類器の決定はどれほど正しいか、という confirmation「確証」を測る。
Prediction=NEGATIVE Prediction=POSITIVE
Truth mark=NOT IN True negatives (TN) False positives(FP)
CATEGORY
Truth mark=IN False negatives(FN) True positives (TP)
CATEGORY
分母のセルが行だけで構成する場合、分類器はどれほど正しく検知できるか、という effectiveness「効果」を測る。
Prediction=NEGATIVE Prediction=POSITIVE
Truth mark=NOT IN True negatives (TN) False positives(FP)
CATEGORY
Truth mark=IN False negatives(FN) True positives (TP)
CATEGORY
このように confusion matrix は確率というより「精度のモノサシ」。よって、
Prediction=NEGATIVE Prediction=POSITIVE
Truth mark=NOT IN True negatives (TN) False positives(FP)
CATEGORY cM[1,1]=264 cM[1,2]=14
Truth mark=IN False negatives(FN) True positives (TP)
CATEGORY cM[2,1]=22 cM[2,2]=158
Accuracy:正解率
> (cM[1,1]+cM[2,2])/sum(cM)
[1] 0.9213974
次は、実際のスパムフィルターサービスの Akismet の混合行列。
> t <- as.table(matrix(data=c(288-1,17,1,13882-17),
nnrow=2,ncol=2))
> rownames(t) <- rownames(cM)
> colnames(t) <- colnames(cM)
> t
FALSE TRUE
non-spam 287 1
spam 17 13865
> (t[1,1]+t[2,2])/sum(t)
[1] 0.9987297
99.87% 、やはりこれぐらいの精度は必要でしょう。
> colnames(t) <- colnames(cM)
> t
FALSE TRUE
non-spam 287 1
spam 17 13865
> (t[1,1]+t[2,2])/sum(t)
[1] 0.9987297
Precision と Recall
注意:precision と recall の、本書の定義を日本語訳したが、原文の方が解りやすい。ただ、この二つは混乱しがちなので、英文にそって、定義の違いを明確にしようと試みた。
precision TP / (TP+FP)
Precision is what fraction of the items the classifier flags as being in the class actually are in the class.
分類器が分けた区分に、現実にも分かれる割合。
> cM[2,2]/(cM[2,2]+cM[1,2])
[1] 0.9186047
> t[2,2]/(t[2,2]+t[1,2])
[1] 0.9999279
recall TP / (TP+FN)
The companion score to precision is recall. Recall is what fraction of the things that are in the class are detected by the classifier.
precision と共にあるのが recall 。あるクラスに属するものが分類器に判別される割合。
> cM[2,2]/(cM[2,2]+cM[2,1])
[1] 0.8777778
> t[2,2]/(t[2,2]+t[2,1])
[1] 0.9987754
それぞぞれの(accuracy, recall) が (91.86%, 88.77%), (99.99%, 99.87%) 。
In both cases most spam is in fact tagged (we have high recall) and precision is emphasized over recall (which is appropriate for a spam filtering application).
スパムフィルターに適切な「高い recall」があってこその precision 。
つまり precision だけあっても意味がない。例えば、92% precision で 89 % recall では信頼性は高いとはいえない。
precision と recall について、まとめると
Precision is a measure of confirmation (when the classifier indicates positive, how often it is in fact correct), and recall is a measure of utility (how much the classifier finds of what there actually is to find).
precision は「確証のモノサシ」:分類器が「陽性」とした内で「本当に陽性」の率。recall は「利便性のモノサシ」:分類器が見つけるべき「陽性」を見つけた率。
precision 等の算出時に、分母のセルがカラムだけで構成する場合、分類器の決定はどれほど正しいか、という confirmation「確証」を測る。
Prediction=NEGATIVE Prediction=POSITIVE
Truth mark=NOT IN True negatives (TN) False positives(FP)
CATEGORY
Truth mark=IN False negatives(FN) True positives (TP)
CATEGORY
分母のセルが行だけで構成する場合、分類器はどれほど正しく検知できるか、という effectiveness「効果」を測る。
Prediction=NEGATIVE Prediction=POSITIVE
Truth mark=NOT IN True negatives (TN) False positives(FP)
CATEGORY
Truth mark=IN False negatives(FN) True positives (TP)
CATEGORY
Precision and recall tend to be relevant to business needs and are good measures to discuss with your project sponsor and client.
precision と recall はビジネスニーズとも関係する。そして、プロジェクトスポンサーや顧客と議論する良い尺度。
確率やデータ分析の専門的数値ではなく、お互いに分かる confusion matrix を使ってみては、ということ。顧客に「p 値がどうだから、統計的に有意」など言っても無意味ということ。
F1(precision と recall の組合せ)
precision と recall の有益な組合せが次の F1
F1 = 2 × precision × recall / (precision + recall)
> pre <- 91.86; rec <- 88.77
> 2*pre*rec/(pre+rec)
[1] 90.28857
# Akisnet
> pre <- 99.99; rec <- 99.87
> 2*pre*rec/(pre+rec)
[1] 99.92996
次は Wikipedia の F1 score から
The F1 score can be interpreted as a weighted average of the precision and recall, where an F1 score reaches its best value at 1 and worst at 0.
「Scoring 評価」に続く。
0 件のコメント:
コメントを投稿