Naive Bayes Classification

Naive Bayes is an effective and commonly-used, machine learning classifier. It is a probabilistic classifier that makes classifications using the Maximum A Posteriori decision rule in a Bayesian setting. It can also be represented using a very simple Bayesian network. Naive Bayes classifiers have been especially popular for text classification, and are a traditional solution for problems such as spam detection.

An intuitive explanation for the Maximum A Posteriori Probability MAP is to think probabilities as degrees of belief. For example, how likely are we vote for a candidate depends on our prior belief. We can modify our stand based on the evidence. Our final decision, based on evidence, is the posterior belief, which is what happens after we sifted through the evidence.
MPA is simply the maximum posterior belief: after going through all the debates, what is your most likely decision.

We use Naive Bayes in an example to predict, based on some features (e.g. the rank of the school student come from), if a student is admitted or rejected.

library(naivebayes)
library(dplyr)
library(ggplot2)
library(psych)
data <- read.csv("C:/07 - R Website/dataset/ML/binary.csv")
data$rank <- as.factor(data$rank)
data$admit <- as.factor(data$admit)

# Visualization
pairs.panels(data[-1])

data %>%
  ggplot(aes(x=admit, y=gre, fill=admit)) + 
  geom_boxplot()

data %>%
  ggplot(aes(x=gre, fill=admit)) + 
  geom_density(alpha=0.8, color='black')

In order to develop a model, we have to make sure that the independent variables are not highly correlated.
We can see from the scatterplot above that the only numerical variables are gre and gpa, and they are not strogly correlated (R-squared=0.38). Moreover, looking at the boxplot that compare admit as a function of gre, there is a significant overlap between the two levels of admit. From the dnsity plot of gre as a function on admit, we can see that students not admitted (admit=1) have higher gre comapared to student admitr├Čted (admit=0). Anyway, there is a significat amount of overlap between the two distributioins.
The same is for gpa, here not shown.

# Data Preparation
set.seed(1234)
ind <- sample(2, nrow(data), replace=TRUE, prob = c(0.8, 0.2))
train <-data[ind == 1,]
test <-data[ind == 2,]

Now, the probability of a student admitted given he belongs to rank one: p(admit=1|rank=1) is equal to: **p(admit=1)*p(rank=1|admit=1)/p(rank=1)**

# Naive Bayes Model
model <- naive_bayes(admit ~ ., data = train)
model
================================ Naive Bayes ================================= 
Call: 
naive_bayes.formula(formula = admit ~ ., data = train)

A priori probabilities: 

        0         1 
0.6861538 0.3138462 

Tables: 
      
gre           0        1
  mean 578.6547 622.9412
  sd   116.3250 110.9240

      
gpa            0         1
  mean 3.3552466 3.5336275
  sd   0.3714542 0.3457057

    
rank          0          1
   1 0.10313901 0.24509804
   2 0.36771300 0.42156863
   3 0.33183857 0.24509804
   4 0.19730942 0.08823529
plot(model)

From the result above, we have A Priori probabilities to be admitted of 0.31: only 31% of the students were admitted to the program. Moreover, for numerical variables (gre, gpa) we have mean and standard deviation, and for categorical variables (rank) we have probabilities. For example, p(rank=1|admit=0)=0.103 and p(rank=1|admit=1)=0.245, as we can see from the result table above.
We have also three plots of the model that represent the density for the numerical variables and the bars for the categorical variable.

# Prediction
p <- predict(model, data=train, type="prob")
head(cbind(p, train))
          0         1 admit gre  gpa rank
1 0.8449088 0.1550912     0 380 3.61    3
2 0.6214983 0.3785017     1 660 3.67    3
3 0.2082304 0.7917696     1 800 4.00    1
4 0.8501030 0.1498970     1 640 3.19    4
6 0.6917580 0.3082420     1 760 3.00    2
7 0.6720365 0.3279635     1 560 2.98    1
# Confusion Matrix
p1 <- predict(model, data=train)
(tab1 <- table(p1, train$admit))
   
p1    0   1
  0 196  69
  1  27  33
# Missclassification
1 - sum(diag(tab1)) / sum(tab1)
[1] 0.2953846

From the table above, we can see that the first student has a probability of 0.84 to not be ammitted. If fact, admit=0, and he has low value of gre=380 and he came from a low rank=3. From the confusin matrix, we calculated a misclassification of 29%.
In order to reduce the misclassification rate we can use the *Kernel. In fact, kernel based densities may perform better when numerical variables are not normally distributed.

# Naive Bayes Model
model <- naive_bayes(admit ~ ., data = train, usekernel = TRUE)
p2 <- predict(model, data=train)
tab2 <- table(p2, train$admit) # confusion matrix
1 - sum(diag(tab2)) / sum(tab2) # missclasification
[1] 0.2738462

In fact, as we can see above, introducing the kernel based dentities the misclassification is reduced (from 29% to 27%).