スコアのベクトルと実際のクラスラベルのベクトルが与えられた場合、R言語または単純な英語のバイナリ分類器の単一数値AUCメトリックをどのように計算しますか?
「AUC:より良い測定...」の9ページ目は、クラスラベルを知っている必要があるようです。これは、MATLABでの私が理解していない例です。
R(Actual == 1))
R(R言語と混同しないでください)はベクトルとして定義されていますが、関数として使用されているためですか?
スコアのベクトルと実際のクラスラベルのベクトルが与えられた場合、R言語または単純な英語のバイナリ分類器の単一数値AUCメトリックをどのように計算しますか?
「AUC:より良い測定...」の9ページ目は、クラスラベルを知っている必要があるようです。これは、MATLABでの私が理解していない例です。
R(Actual == 1))
R(R言語と混同しないでください)はベクトルとして定義されていますが、関数として使用されているためですか?
このパッケージを使用すると、ヘルプページから次の例のようなpROC
関数を使用できます。auc()
> data(aSAH)
>
> # Syntax (response, predictor):
> auc(aSAH$outcome, aSAH$s100b)
Area under the curve: 0.7314
ROCRパッケージは、他の統計の中でもAUCを計算します。
auc.tmp <- performance(pred,"auc"); auc <- as.numeric(auc.tmp@y.values)
他の人が述べているように、 ROCRパッケージを使用してAUCを計算できます。ROCRパッケージを使用すると、ROC曲線、リフト曲線、およびその他のモデル選択測定値をプロットすることもできます。
AUCが真の負よりもスコアが高い確率に等しいという事実を使用することにより、パッケージを使用せずにAUCを直接計算できます。
たとえば、pos.scores
が肯定的な例のスコアを含むneg.scores
ベクトルであり、が否定的な例を含むベクトルである場合、AUCは次のように近似されます。
> mean(sample(pos.scores,1000,replace=T) > sample(neg.scores,1000,replace=T))
[1] 0.7261
AUCの概算を示します。ブートストラップによってAUCの分散を推定することもできます。
> aucs = replicate(1000,mean(sample(pos.scores,1000,replace=T) > sample(neg.scores,1000,replace=T)))
追加パッケージなし:
true_Y = c(1,1,1,1,2,1,2,1,2,2)
probs = c(1,0.999,0.999,0.973,0.568,0.421,0.382,0.377,0.146,0.11)
getROC_AUC = function(probs, true_Y){
probsSort = sort(probs, decreasing = TRUE, index.return = TRUE)
val = unlist(probsSort$x)
idx = unlist(probsSort$ix)
roc_y = true_Y[idx];
stack_x = cumsum(roc_y == 2)/sum(roc_y == 2)
stack_y = cumsum(roc_y == 1)/sum(roc_y == 1)
auc = sum((stack_x[2:length(roc_y)]-stack_x[1:length(roc_y)-1])*stack_y[2:length(roc_y)])
return(list(stack_x=stack_x, stack_y=stack_y, auc=auc))
}
aList = getROC_AUC(probs, true_Y)
stack_x = unlist(aList$stack_x)
stack_y = unlist(aList$stack_y)
auc = unlist(aList$auc)
plot(stack_x, stack_y, type = "l", col = "blue", xlab = "False Positive Rate", ylab = "True Positive Rate", main = "ROC")
axis(1, seq(0.0,1.0,0.1))
axis(2, seq(0.0,1.0,0.1))
abline(h=seq(0.0,1.0,0.1), v=seq(0.0,1.0,0.1), col="gray", lty=3)
legend(0.7, 0.3, sprintf("%3.3f",auc), lty=c(1,1), lwd=c(2.5,2.5), col="blue", title = "AUC")
ここでの解決策のいくつかは遅いか混乱している(そしてそれらのいくつかはタイを正しく処理しない)ことがわかったので、Rパッケージmltoolsdata.table
に独自のベースの関数auc_roc()を書きました。
library(data.table)
library(mltools)
preds <- c(.1, .3, .3, .9)
actuals <- c(0, 0, 1, 1)
auc_roc(preds, actuals) # 0.875
auc_roc(preds, actuals, returnDT=TRUE)
Pred CountFalse CountTrue CumulativeFPR CumulativeTPR AdditionalArea CumulativeArea
1: 0.9 0 1 0.0 0.5 0.000 0.000
2: 0.3 1 1 0.5 1.0 0.375 0.375
3: 0.1 1 0 1.0 1.0 0.500 0.875
AUROCの詳細については、 MironKursaによるこのブログ投稿をご覧ください。
彼はAUROCに高速機能を提供します。
# By Miron Kursa https://mbq.me
auroc <- function(score, bool) {
n1 <- sum(!bool)
n2 <- sum(bool)
U <- sum(rank(score)[!bool]) - n1 * (n1 + 1) / 2
return(1 - U / n1 / n2)
}
それをテストしてみましょう:
set.seed(42)
score <- rnorm(1e3)
bool <- sample(c(TRUE, FALSE), 1e3, replace = TRUE)
pROC::auc(bool, score)
mltools::auc_roc(score, bool)
ROCR::performance(ROCR::prediction(score, bool), "auc")@y.values[[1]]
auroc(score, bool)
0.51371668847094
0.51371668847094
0.51371668847094
0.51371668847094
auroc()
pROC::auc()
およびよりも100倍高速ですcomputeAUC()
。
auroc()
mltools::auc_roc()
およびよりも10倍高速ですROCR::performance()
。
print(microbenchmark(
pROC::auc(bool, score),
computeAUC(score[bool], score[!bool]),
mltools::auc_roc(score, bool),
ROCR::performance(ROCR::prediction(score, bool), "auc")@y.values,
auroc(score, bool)
))
Unit: microseconds
expr min
pROC::auc(bool, score) 21000.146
computeAUC(score[bool], score[!bool]) 11878.605
mltools::auc_roc(score, bool) 5750.651
ROCR::performance(ROCR::prediction(score, bool), "auc")@y.values 2899.573
auroc(score, bool) 236.531
lq mean median uq max neval cld
22005.3350 23738.3447 22206.5730 22710.853 32628.347 100 d
12323.0305 16173.0645 12378.5540 12624.981 233701.511 100 c
6186.0245 6495.5158 6325.3955 6573.993 14698.244 100 b
3019.6310 3300.1961 3068.0240 3237.534 11995.667 100 ab
245.4755 253.1109 251.8505 257.578 300.506 100 a
@JとともにISL9.6.3ROC曲線からのコードを組み合わせます。この質問と他のいくつかの場所に対するWon。の回答として、以下はROC曲線をプロットし、プロットの右下にAUCを印刷します。
以下probs
は、二項分類の予測確率の数値ベクトルでtest$label
あり、テストデータの真のラベルが含まれています。
require(ROCR)
require(pROC)
rocplot <- function(pred, truth, ...) {
predob = prediction(pred, truth)
perf = performance(predob, "tpr", "fpr")
plot(perf, ...)
area <- auc(truth, pred)
area <- format(round(area, 4), nsmall = 4)
text(x=0.8, y=0.1, labels = paste("AUC =", area))
# the reference x=y line
segments(x0=0, y0=0, x1=1, y1=1, col="gray", lty=2)
}
rocplot(probs, test$label, col="blue")
これにより、次のようなプロットが得られます。
私は通常、DiagnosisMedパッケージの関数ROCを使用します。私はそれが生成するグラフが好きです。AUCは、信頼区間とともに返され、グラフにも示されます。
ROC(classLabels,scores,Full=TRUE)
erikの応答に沿って、pos.scoresとneg.scoresのすべての可能な値のペアを比較することにより、ROCを直接計算することもできるはずです。
score.pairs <- merge(pos.scores, neg.scores)
names(score.pairs) <- c("pos.score", "neg.score")
sum(score.pairs$pos.score > score.pairs$neg.score) / nrow(score.pairs)
サンプルアプローチまたはpROC::aucよりも確かに効率は劣りますが、前者よりも安定しており、後者よりもインストールが少なくて済みます。
関連:これを試したところ、pROCの値と同様の結果が得られましたが、まったく同じではありませんでした(0.02程度の差)。結果は、非常に高いNを使用したサンプルアプローチに近くなりました。誰かがアイデアを持っている場合、それがなぜそうなるのか興味があります。
現在、上位投票の回答は、同点を無視しているため、正しくありません。正と負のスコアが等しい場合、AUCは0.5である必要があります。以下は修正例です。
computeAUC <- function(pos.scores, neg.scores, n_sample=100000) {
# Args:
# pos.scores: scores of positive observations
# neg.scores: scores of negative observations
# n_samples : number of samples to approximate AUC
pos.sample <- sample(pos.scores, n_sample, replace=T)
neg.sample <- sample(neg.scores, n_sample, replace=T)
mean(1.0*(pos.sample > neg.sample) + 0.5*(pos.sample==neg.sample))
}
Metricsパッケージを使用したAUCの計算 は、非常に簡単で簡単です。
library(Metrics)
actual <- c(0, 0, 1, 1)
predicted <- c(.1, .3, .3, .9)
auc(actual, predicted)
0.875