Naif Bayes pada variabel kontinu

8

Tolong izinkan saya untuk mengajukan pertanyaan dasar. Saya memahami mekanisme Naive Bayes untuk variabel diskrit, dan dapat mengulang perhitungan "dengan tangan". (kode HouseVotes84 semua jalan per di bawah ini).

Namun - Saya berjuang untuk melihat bagaimana mekanisme bekerja untuk variabel kontinu (contoh kode per di bawah). Bagaimana paket menghitung probabilitas bersyarat [, 1]dan [, 2]dalam tabel per di bawah ini? Karena setiap nilai X individu adalah unik, apakah ia membuat rentang di sekitar setiap titik, dan menghitung frekuensi relatif dalam rentang ini (misalnya jika titiknya adalah +0,311, apakah ia mengevaluasi timbulnya bintik-bintik biru dan oranye di misalnya rentang 0,1 dan +0.5?) Ini mungkin pertanyaan mendasar - permintaan maaf jika demikian.

Meja

A-priori probabilities:
Y
  blue orange 
   0.5    0.5 

Conditional probabilities:
        values
Y              [,1]      [,2]
  blue   0.08703793 0.9238799
  orange 1.33486433 0.9988389

Kode

blue=rep("blue",50); orange=rep("orange",50); colour=c(blue,orange); values1=rnorm(50,0,1); values2=rnorm(50,1,1); values=c(values1,values2)
df=data.frame(colour,values)

(model <- naiveBayes(colour ~ ., data = df))
(predict(model, df[1:10,]))
(predict(model, df[1:10,], type = "raw"))
(pred <- predict(model, df))
table(pred, df$colour)

## Categorical data only:
library(e1071)
data(HouseVotes84, package = "mlbench")
HouseVotes84=HouseVotes84[,1:3]
(model <- naiveBayes(Class ~ ., data = HouseVotes84))
(predict(model, HouseVotes84[1:10,]))
(predict(model, HouseVotes84[1:10,], type = "raw"))
(pred <- predict(model, HouseVotes84))
table(pred, HouseVotes84$Class)
Wouter
sumber

Jawaban:

5

Dari paket R (e1071) dan fungsi naifBayes yang Anda gunakan:

Pengklasifikasi naif Bayes standar (setidaknya implementasi ini) mengasumsikan independensi variabel prediktor, dan distribusi Gaussian (diberi kelas target) dari prediktor metrik. Untuk atribut dengan nilai yang hilang, entri tabel terkait dihilangkan untuk prediksi.

Ini cukup standar untuk variabel kontinu dalam Bayes naif bahwa distribusi normal dipertimbangkan untuk variabel-variabel ini dan rata-rata dan deviasi standar kemudian dapat dihitung dan kemudian menggunakan beberapa standar perhitungan z-tabel probabilitas dapat diperkirakan untuk setiap variabel kontinu Anda untuk membuat klasifikasi Bayes yang naif. Saya pikir mungkin untuk mengubah asumsi distribusi dalam paket ini, tetapi ternyata saya salah.

Ada paket R lain (klaR) di mana Anda dapat mengubah kernel density. (fungsinya adalah NaiveBayes). Dari paket:

NaiveBayes(x, grouping, prior, usekernel = FALSE, fL = 0, ...)

kernel Windows

jika TRUE estimasi kepadatan kernel (densitas) digunakan untuk estimasi denstity. Jika FALSE kepadatan normal diperkirakan.

density(x, bw = "nrd0", adjust = 1,
        kernel = c("gaussian", "epanechnikov", "rectangular",
                   "triangular", "biweight",
                   "cosine", "optcosine")
Eric Peterson
sumber
0

Saya sedang mengerjakan sebuah proyek belum lama yang lalu saya perlu menghitung classifier bayes naif (dari awal). Saya mulai di R, tapi begitu saya selesai prosesnya, saya memindahkan kodenya ke Python. Inilah kode saya yang saya mulai. Jangan berharap itu dipoles. Sebagian besar, saya mengikuti contoh Wikipedia ( https://en.wikipedia.org/wiki/Naive_Bayes_classifier#Examples ).

Langkah-langkahnya sederhana:

  1. menghitung probabilitas a priori yang merupakan proporsi kelas

  2. Untuk data berkelanjutan Anda, asumsikan distribusi normal dan hitung mean dan standar deviasi.

  3. Untuk mengklasifikasikan pengamatan, ambil input baru x, hitung dari dnorm(x, mu, sigma)mana mu dan sigma berasal dari langkah 2.

  4. Jumlah log (apriori) + log (dnorm (...)).

Pada titik ini, log(dnorm(...))harus mengandung dua nilai log (dalam contoh saya). Probabilitas bahwa mereka termasuk dalam kelas 0 dan probabilitas mereka termasuk dalam kelas 1. Ini adalah poin yang Eric Peterson buat dalam paragraf keduanya.

  1. Hitung probabilitas posterior

Saya juga membandingkan hasil saya dengan R library e1071. Hasil probabilitas saya tidak sejajar dengan mereka untuk kasus sederhana ini , meskipun klasifikasi tidak. Dalam predict.naiveBayesfungsinya, mereka memiliki sesuatu seperti log(apriori) + apply(log(sapply(...compute dnorm code here...)), 1, sum)yang mengembalikan log(apriori) + log(1) = log(apriori)yang merupakan kesalahan sehingga klasifikasi mereka semata-mata didasarkan pada probabilitas a priori (sebenarnya, mereka menggunakan jumlah bukan probabilitas).

Bagaimanapun, saya harap ini membantu Anda (dan orang lain) melihat apa yang ada di balik tudung karena tidak jelas bagi saya juga.

n=30 ## samples
set.seed(123)
x = c(rnorm(n/2, 10, 2), rnorm(n/2, 0, 2))
y = as.factor(c(rep(0, 20), rep(1, 10)))
y


#library(e1071)
#nb = naiveBayes(x, y, laplace = 0)
#nb

#nb_predictions = predict(nb, x[1], type='raw')
#nb_predictions



library(dplyr)

nbc <- function(x, y){
  df <- as.data.frame(cbind(x,y))
  a_priori <- table(y) #/length(y)

  cond_probs <- df %>% group_by(y) %>% summarise(means = mean(x), var = sd(x))

  print("A Priori Probabilities")
  print(a_priori/sum(a_priori))

  print("conditional probabilities \n")
  print(cond_probs)

  return(list(apriori = a_priori, tables = cond_probs))
}



predict_nbc <- function(model, new_x){
  apriori = as.matrix(model$apriori)
  a = log(apriori/sum(apriori))
  msd = as.matrix(model$tables)[,c(2,3)] ## creates 3 columsn; first is junk
  probs = sapply(new_x, function(v) dnorm(x = v, mean = msd[,1], sd = msd[,2]))
  b = log(probs)
  #L = a + b ## works for 1 new obs
  L = apply(X = b, MARGIN = 2, FUN = function(v) a + v)

  results <- apply(X = L, MARGIN = 2, function(x){
                   sapply(x, function(lp){ 1/sum(exp(x - lp)) }) ## numerically stable
  })
  return(results)
}



fit = nbc(x,y)

fit ## my naive bayes classifier model

myres = predict_nbc(fit, new_x = x[1:4])
myres
Jon
sumber