本人原創,轉載請注明來自 http://www.cnblogs.com/digging4/p/3884385.html
1、引子
朴素貝葉斯方法是一種使用先驗概率去計算后驗概率的方法,其中朴素的意思實際上指的是一個假設條件,后面在舉例中說明。本人以為,純粹的數學推導固然有其嚴密性、邏輯性的特點,但對我等非數學專業的人來說,對每一推導步驟的並非能透徹理解,我將從一個例子入手,類似於應用題的方式,解釋朴素貝葉斯分類器,希望能對公式的理解增加形象化的場景。
2、實例
最近“小蘋果”很火,我們就以蘋果來舉例說,假設可以用三個特征來描述一個蘋果,分別為“尺寸”、“重量”和“顏色”;其中“尺寸”的取值為小、大,“重量”的取值為輕、重,“顏色”取值為紅、綠。對這三個特征描述的蘋果中,對蘋果的按味道進行分類,可取的值為good、bad。
朴素貝葉斯分類器就要要解決如下一個問題,已知蘋果味道取good和bad的概率,那么如果給定一個一組蘋果的特征,那么這個蘋果味道取good和bad的概率是多少?這是個典型的逆概率的問題。
尺寸(size) 大 小 大 大 小 小
重量(weight) 輕 重 輕 輕 重 輕
顏色(color) 紅 紅 紅 綠 紅 綠
味道(taste) good good bad bad bad good
以上給出了6個蘋果的特征描述及其口味,那個一個大而重的紅蘋果,能否估計出它的味道是good還是bad?
這里我們先解釋下朴素的含義,朴素就是這樣一個假設:描述蘋果的三個特征是相互獨立的。這個假設會對后面的計算帶來極大的方便。但是肯定有人會想,對這個例子來說,這個假設就不成立嘛,大小和重量從直覺上我們都會感到是兩個正相關的特征。是的,朴素的假設在實際世界中是較難滿足的,但是實際使用中,基於這個假設作出預測的正確率是在一個可接受的范圍。
3、基本方法
(P(A|B)) 表示在確定B的情況下,事件A發生的概率,而在實際情況中,我們或許更關心(P(B|A))但是只能直接獲得(P(A|B)) ,此時我們需要一個工具可以把(P(A|B)) 和(P(B|A))相互轉化, 貝葉斯定理就是這樣一個公式,下面給出貝葉斯定理:
[P(B|A) = \frac{{P(A|B)P(B)}}{{P(A)}}]
對蘋果分類的問題,有三個特征(F = { {f_1},{f_2},{f_3}} ),兩種分類(C = { {c_1},{c_2}} ),根據貝葉斯公式有給定特征條件下,特征為({c_i})的概率
[P({c_i}|{f_1}{f_2}{f_3}) = \frac{{P({f_1}{f_2}{f_3}|{c_i})P({c_i})}}{{P({f_1}{f_2}{f_3})}}]
使得上式取得最大值的({c_i})即為分類結果,由於對給定訓練集來說,({P({f_1}{f_2}{f_3})})為常數,那么就轉為為求
[{P({f_1}{f_2}{f_3}|{c_i})P({c_i})}]
的最大值。
朴素貝葉斯的假設在這里就體現了,由於特征值相互獨立,那么上式可以轉化為
[P({f_1}|{c_i})P({f_2}|{c_i})P({f_3}|{c_i})P({c_i})]
整個問題就變為求使得上式取最大值的({c_i}),而上式中的每一項都可以從訓練集中得到。
最后討論下Laplace校准,如果某一個特性值在訓練集中出現的次數為0,那么以上我們討論的公式就沒有意義了,以為對所有的類型結果都是0。當然對訓練集進行選擇可以避免這種情況,但是如果避免不了就需要進行Laplace校准。其實很簡單,把所有出現特征出現的次數都加上1,即為Laplace校准。
4、R語言實現
################################
# 朴素貝葉斯分類器
################################
library(plyr)
library(reshape2)
#1、根據訓練集創建朴素貝葉斯分類器
#1.1、生成類別的概率
##計算訓練集合D中類別出現的概率,即P{c_i}
##輸入:trainData 訓練集,類型為數據框
## strClassName 指明訓練集中名稱為strClassName列為分類結果
##輸出:數據框,P{c_i}的集合,類別名稱|概率(列名為 prob)
class_prob <- function(trainData, strClassName){
#訓練集樣本數
length.train <- nrow(trainData)
dTemp <- ddply(trainData, strClassName, "nrow")
dTemp <- ddply(dTemp, strClassName, mutate, prob = nrow/length.train)
dTemp[,-2]
}
##1.2、生成每個類別下,特征取不同值的概率
##計算訓練集合D中,生成每個類別下,特征取不同值的概率,即P{fi|c_i}
##輸入:trainData 訓練集,類型為數據框
## strClassName 指明訓練集中名稱為strClassName列為分類結果,其余的全部列認為是特征值
##輸出:數據框,P{fi|c_i}的集合,類別名稱|特征名稱|特征取值|概率(列名為 prob)
feature_class_prob <- function(trainData, strClassName){
# 橫表轉換為縱表
data.melt <- melt(trainData,id=c(strClassName))
# 統計頻數
aa <- ddply(data.melt, c(strClassName,"variable","value"), "nrow")
# 計算概率
bb <- ddply(aa, c(strClassName,"variable"), mutate, sum = sum(nrow), prob = nrow/sum)
# 增加列名
colnames(bb) <- c("class.name",
"feature.name",
"feature.value",
"feature.nrow",
"feature.sum",
"prob")
# 返回結果
bb[,c(1,2,3,6)]
}
#feature_class_prob(iris,"Species")
## 以上創建完朴素貝葉斯分類器
## 2、使用生成的朴素貝葉斯分類器進行預測
##使用生成的朴素貝葉斯分類器進行預測P{fi|c_i}
##輸入:oneObs 數據框,待預測的樣本,格式為 特征名稱|特征值
## pc 數據框,訓練集合D中類別出現的概率,即P{c_i} 類別名稱|概率
## pfc 數據框,每個類別下,特征取不同值的概率,即P{fi|c_i}
## 類別名稱|特征名稱|特征值|概率
##輸出:數據框,待預測樣本的分類對每個類別的概率,類別名稱|后驗概率(列名為 prob)
pre_class <- function(oneObs, pc,pfc){
colnames(oneObs) <- c("feature.name", "feature.value")
colnames(pc) <- c("class.name","prob")
colnames(pfc) <- c("class.name","feature.name","feature.value","prob")
# 取出特征的取值的條件概率
feature.all <- join(oneObs,pfc,by=c("feature.name","feature.value"),type="inner")
# 取出特征取值的條件概率連乘
feature.prob <- ddply(feature.all,.(class.name),summarize,prob_fea=prod(prob)) #prod為連乘函數
#取出類別的概率
class.all <- join(feature.prob,pc,by="class.name",type="inner")
#輸出結果
ddply(class.all,.(class.name),mutate,pre_prob=prob_fea*prob)[,c(1,4)]
}
##3、數據測試
##用上面蘋果的數據作為例子進行測試
#訓練集
train.apple <-data.frame(
size=c("大","小","大","大","小","小"),
weight=c("輕","重","輕","輕","重","輕"),
color=c("紅","紅","紅","綠","紅","綠"),
taste=c("good","good","bad","bad","bad","good")
)
#待預測樣本
oneObs<-data.frame(
feature.name =c("size", "weight", "color"),
feature.value =c("大","重","紅")
)
#預測分類
pc <- class_prob(train.apple,"taste")
pfc <- feature_class_prob(train.apple,"taste")
pre_class(oneObs, pc,pfc)
結果為
class.name pre_prob
1 bad 0.07407407
2 good 0.03703704
可見該蘋果的口味為bad
5、朴素貝葉斯分類小結
1、屬於有監督的學習(有訓練集);
2、主要處理離散類型的數據,如果為連續數據可先進行離散化;
3、訓練集的特征取值要盡量完備,如果有缺失需進行預處理(Laplace校准);
4、關於特征值相互獨立的假設,在實際問題中一般無法滿足,但基於此假設做的預測是可以接受的。
關於其他的朴素貝葉斯介紹可見:
http://www.ruanyifeng.com/blog/2013/12/naive_bayes_classifier.html
http://www.cnblogs.com/leoo2sk/archive/2010/09/17/1829190.html