2016年10月9日日曜日

モデル構築、評価 & 判定:Classification 評価

評価のモノサシ」からの続き。

今回は、Classification モデルの評価方法を取り上げる。


Confusion Matrix

以下のような流れで、スパム判定結果のデータから、スパム判定モデルを構築、confusion matrix で精度を測る。

  1. データを訓練用 spamTrain とテスト用 spamTest に分割
  2. 訓練データを線形回帰分析してモデル構築
  3. 訓練データとテストデータを説明変数にして、モデルで予測
  4. テストデータを説明変数にして、モデルで予測した結果から 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.4Standard 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))
> 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% 、やはりこれぐらいの精度は必要でしょう。


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

スパム検知で precision92% とは、スパムとされた内で 8% が誤り(つまり「正常メール」)。Akismet 99.99% がスパム検知で求められる性能値だろう。


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% precision89 % recall では信頼性は高いとはいえない。

precisionrecall について、まとめると
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                                     


このように confusion matrix は確率というより「精度のモノサシ」。よって、

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)

# Spam fileter
> 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

次は WikipediaF1 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 件のコメント:

コメントを投稿