Một thời gian đã trôi qua và tôi nghĩ rằng tôi có thể có một giải pháp trong tay. Tôi sẽ mô tả ngắn gọn cách tiếp cận của tôi để cung cấp cho bạn ý tưởng chung. Mã phải đủ để tìm ra các chi tiết. Tôi thích đính kèm mã ở đây, nhưng nó rất nhiều và stackexchange làm cho nó không dễ dàng để làm như vậy. Tôi tất nhiên rất vui khi trả lời bất kỳ ý kiến, tôi cũng đánh giá cao bất kỳ lời chỉ trích.
Mã có thể được tìm thấy dưới đây.
Chiến lược:
- Xấp xỉ một đường cong ROC mượt mà bằng cách sử dụng hàm Logistic trong khoảng [0,6]
- fk(x)=1(1+exp(−k∗x))
- Bây giờ, với điều kiện bạn có đường cong roc phù hợp với AUC mong muốn, hãy xác định điểm theo mẫu từ [0,1]. Điều này thể hiện fpr ( Sai-dương-tỷ lệ ) trên đường cong ROC. Để đơn giản, điểm số được tính sau đó là 1 fpr.
- Bây giờ nhãn được xác định bằng cách lấy mẫu từ Phân phối Bernoulli với p được tính bằng độ dốc của ROC-Curve tại fpr này và độ chính xác tổng thể mong muốn của điểm số. Cụ thể: weight (nhãn = "1"): = dốc (fpr) bị thay đổi bởi tổng thểPrecision, weight (nhãn = "0"): = 1 nhân với (1-generalPrecision). Bình thường hóa các trọng số sao cho tổng của chúng lên tới 1 để xác định p và 1-p.
Dưới đây là ví dụ ROC-Curve cho AUC = 0,6 và độ chính xác tổng thể = 0,1 (cũng trong mã bên dưới)
Ghi chú:
- AUC kết quả không hoàn toàn giống với AUC đầu vào, trên thực tế, có một lỗi nhỏ (khoảng 0,02). Lỗi này bắt nguồn từ cách xác định nhãn của điểm. Một cải tiến có thể là thêm một tham số để kiểm soát kích thước của lỗi.
- điểm số được đặt là 1-fpr. Điều này là tùy ý vì ROC-Curve không quan tâm điểm số trông như thế nào miễn là chúng có thể được sắp xếp.
mã:
# This function creates a set of random scores together with a binary label
# n = sampleSize
# basePrecision = ratio of positives in the sample (also called overall Precision on stats.stackexchange)
# auc = Area Under Curve i.e. the quality of the simulated model. Must be in [0.5,1].
#
binaryModelScores <- function(n,basePrecision=0.1,auc=0.6){
# determine parameter of logistic function
k <- calculateK(auc)
res <- data.frame("score"=rep(-1,n),"label"=rep(-1,n))
randUniform = runif(n,0,1)
runIndex <- 1
for(fpRate in randUniform){
tpRate <- roc(fpRate,k)
# slope
slope <- derivRoc(fpRate,k)
labSampleWeights <- c((1-basePrecision)*1,basePrecision*slope)
labSampleWeights <- labSampleWeights/sum(labSampleWeights)
res[runIndex,1] <- 1-fpRate # score
res[runIndex,2] <- sample(c(0,1),1,prob=labSampleWeights) # label
runIndex<-runIndex+1
}
res
}
# min-max-normalization of x (fpr): [0,6] -> [0,1]
transformX <- function(x){
(x-0)/(6-0) * (1-0)+0
}
# inverse min-max-normalization of x (fpr): [0,1] -> [0,6]
invTransformX <- function(invx){
(invx-0)/(1-0) *(6-0) + 0
}
# min-max-normalization of y (tpr): [0.5,logistic(6,k)] -> [0,1]
transformY <- function(y,k){
(y-0.5)/(logistic(6,k)-0.5)*(1-0)+0
}
# logistic function
logistic <- function(x,k){
1/(1+exp(-k*x))
}
# integral of logistic function
intLogistic <- function(x,k){
1/k*log(1+exp(k*x))
}
# derivative of logistic function
derivLogistic <- function(x,k){
numerator <- k*exp(-k*x)
denominator <- (1+exp(-k*x))^2
numerator/denominator
}
# roc-function, mapping fpr to tpr
roc <- function(x,k){
transformY(logistic(invTransformX(x),k),k)
}
# derivative of the roc-function
derivRoc <- function(x,k){
scalFactor <- 6 / (logistic(6,k)-0.5)
derivLogistic(invTransformX(x),k) * scalFactor
}
# calculate the AUC for a given k
calculateAUC <- function(k){
((intLogistic(6,k)-intLogistic(0,k))-(0.5*6))/((logistic(6,k)-0.5)*6)
}
# calculate k for a given auc
calculateK <- function(auc){
f <- function(k){
return(calculateAUC(k)-auc)
}
if(f(0.0001) > 0){
return(0.0001)
}else{
return(uniroot(f,c(0.0001,100))$root)
}
}
# Example
require(ROCR)
x <- seq(0,1,by=0.01)
k <- calculateK(0.6)
plot(x,roc(x,k),type="l",xlab="fpr",ylab="tpr",main=paste("ROC-Curve for AUC=",0.6," <=> k=",k))
dat <- binaryModelScores(1000,basePrecision=0.1,auc=0.6)
pred <- prediction(dat$score,as.factor(dat$label))
performance(pred,measure="auc")@y.values[[1]]
perf <- performance(pred, measure = "tpr", x.measure = "fpr")
plot(perf,main="approximated ROC-Curve (random generated scores)")