Pembentukan skor acak mirip dengan model klasifikasi

8

Halo sesama pengolah angka

Saya ingin menghasilkan n skor acak (bersama-sama dengan label kelas) seolah-olah mereka telah diproduksi oleh model klasifikasi biner. Secara rinci, diperlukan properti berikut:

  • setiap skor adalah antara 0 dan 1
  • setiap skor dikaitkan dengan label biner dengan nilai "0" atau "1" (yang terakhir adalah kelas positif)
  • ketelitian keseluruhan skor harus misalnya 0,1 (<- parameter generator)
  • rasio skor dengan label "1" harus lebih tinggi daripada presisi keseluruhan di bagian atas dan lebih rendah di bagian bawah (<- "kualitas model" juga harus menjadi parameter generator)
  • skor harus sedemikian rupa, sehingga kurva roc yang dihasilkan halus (dan bukan misalnya bahwa sekelompok skor dengan label "1" berada di bagian atas dan sisa skor dengan label "1" berada di bagian bawah Daftar).

Adakah yang punya ide bagaimana mendekati ini? Mungkin melalui pembuatan kurva-roc dan kemudian menghasilkan poin dari penyembuhan itu? Terima kasih sebelumnya!

steffen
sumber
menulis "ketepatan keseluruhan skor harus mis. 0,1" apakah maksud Anda Anda ingin skor menjadi variabel acak dengan rata-rata 0,1? mengapa Anda tidak menghasilkan masalah klasifikasi (katakanlah dengan variabel gaussian) dan gunakan sesuatu yang cepat dan sederhana (seperti LDA) untuk menyelesaikannya? dapatkah Anda memberi tahu kami lebih lanjut tentang motivasi Anda?
robin girard
@Robin: Tidak, saya berbicara tentang "presisi" sebagai ukuran kualitas model klasifikasi biner (lihat misalnya en.wikipedia.org/wiki/Sensitivity_and_specificity di sini). Mengenai pertanyaan kedua Anda: Saya membutuhkan skor untuk simulasi di mana beberapa model klasifikasi biner digabungkan (lebih banyak di bidang pemrosesan data daripada Penambangan Data). Sulit untuk menjelaskan tugas ini secara terperinci, tetapi saya cukup yakin saya membutuhkan skor ini: D
steffen

Jawaban:

4

Beberapa waktu telah berlalu dan saya pikir saya mungkin punya solusi. Saya akan menjelaskan pendekatan saya secara singkat untuk memberi Anda ide umum. Kode harus cukup untuk mengetahui detailnya. Saya suka melampirkan kode di sini, tetapi banyak dan stackexchange membuatnya tidak mudah untuk melakukannya. Saya tentu saja senang menjawab komentar apa pun, juga saya menghargai kritik apa pun.

Kode dapat ditemukan di bawah.

Strategi:

  1. Perkiraan kurva ROC-halus dengan menggunakan fungsi Logistik dalam interval [0,6]
  2. Dengan menambahkan parameter k seseorang dapat mempengaruhi bentuk kurva agar sesuai dengan kualitas model yang diinginkan, diukur dengan AUC (Area Di Bawah Kurva). Fungsi yang dihasilkan adalah . Jika k-> 0, AUC mendekati 0,5 (tanpa optimasi), jika k -> Inf, AUC mendekati 1 (model optimal). Sebagai pendekatan praktis, k harus dalam interval [0,0001,100]. Dengan beberapa kalkulus dasar, seseorang dapat membuat fungsi untuk memetakan k ke AUC dan sebaliknya.fk(x)=1(1+exhal(-kx))
  3. Sekarang, mengingat Anda memiliki kurva-roc yang cocok dengan AUC yang diinginkan, tentukan skor dengan sampel dari [0,1] secara seragam. Ini mewakili fpr ( False-Positive-Rate ) pada kurva ROC. Untuk kesederhanaan, skor dihitung kemudian sebagai 1-fpr.
  4. Label sekarang ditentukan dengan pengambilan sampel dari Distribusi Bernoulli dengan p dihitung menggunakan kemiringan ROC-Curve pada fpr ini dan ketepatan keseluruhan skor yang diinginkan. Secara detail: berat (label = "1"): = kemiringan (fpr) dimutilasi oleh overallPrecision, berat (label = "0"): = 1 dikalikan dengan (1-overallPrecision). Menormalkan bobot sehingga jumlahnya hingga 1 untuk menentukan p dan 1-p.

Berikut ini adalah contoh ROC-Curve untuk AUC = 0,6 dan presisi keseluruhan = 0,1 (juga dalam kode di bawah ini) teks alternatif teks alternatif

Catatan:

  • AUC yang dihasilkan tidak persis sama dengan input AUC, pada kenyataannya, ada kesalahan kecil (sekitar 0,02). Kesalahan ini berasal dari cara label skor ditentukan. Perbaikan bisa berupa menambahkan parameter untuk mengontrol ukuran kesalahan.
  • skor ditetapkan sebagai 1-fpr. Ini sewenang-wenang karena ROC-Curve tidak peduli bagaimana skor terlihat seperti selama mereka dapat diurutkan.

kode:

# 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)")
steffen
sumber
Saya akan menghargai jika ada orang yang memiliki lebih banyak keterampilan dalam lateks dapat mengedit perhitungan dalam 4. sehingga lebih mudah dibaca.
steffen
karena inilah yang saya inginkan, saya akan menandainya sebagai "jawabannya". Namun, saya masih terbuka untuk saran dan ide.
steffen