1. 程式人生 > >基於Naive Bayes算法的文本分類

基於Naive Bayes算法的文本分類

二進制 貝葉斯分類 根據 分詞 步驟 矩陣 get choose 類型

理論

技術分享圖片

什麽是樸素貝葉斯算法?

樸素貝葉斯分類器是一種基於貝葉斯定理的弱分類器,所有樸素貝葉斯分類器都假定樣本每個特征與其他特征都不相關。舉個例子,如果一種水果其具有紅,圓,直徑大概3英寸等特征,該水果可以被判定為是蘋果。盡管這些特征相互依賴或者有些特征由其他特征決定,然而樸素貝葉斯分類器認為這些屬性在判定該水果是否為蘋果的概率分布上獨立的。

樸素貝葉斯分類器很容易建立,特別適合用於大型數據集,眾所周知,這是一種勝過許多復雜算法的高效分類方法。

貝葉斯公式提供了計算後驗概率P(X|Y)的方式:

技術分享圖片

其中,

  • P(c|x)是已知某樣本(c,目標),(x,屬性)的概率。稱後驗概率。

  • P(c)是該樣本“c”的概率。稱先驗概率。

  • P(x|c)是已知該樣本“x”,該樣本“c”的概率。

  • P(x)是該樣本“x”的概率。

樸素貝葉斯算法的分類流程

舉一個例子。下面設計了一個天氣和響應目標變量“玩”的訓練數據集(計算“玩”的可能性)。我們需要根據天氣條件進行分類,判斷這個人能不能出去玩,以下是步驟:

步驟1:將數據集轉換成頻率表;

步驟2:計算不同天氣出去玩的概率,並創建似然表,如陰天的概率是0.29;

技術分享圖片

步驟3:使用貝葉斯公式計算每一類的後驗概率,數據最高那欄就是預測的結果。

問題:如果是晴天,這個人就能出去玩。這個說法是不是正確的?

P(是|晴朗)=P(晴朗|是)×P(是)/P(晴朗)

在這裏,P(晴朗|是)= 3/9 = 0.33,P(晴朗)= 5/14 = 0.36,P(是)= 9/14 = 0.64

現在,P(是|晴朗)=0.33×0.64/0.36=0.60,具有較高的概率。

樸素貝葉斯適合預測基於各屬性的不同類的概率,因此在文本分類上有廣泛應用。

樸素貝葉斯的優缺點

優點:

  • 既簡單又快速,預測表現良好;

  • 如果變量獨立這個條件成立,相比Logistic回歸等其他分類方法,樸素貝葉斯分類器性能更優,且只需少量訓練數據;

  • 相較於數值變量,樸素貝葉斯分類器在多個分類變量的情況下表現更好。若是數值變量,需要正態分布假設。

缺點:

  • 如果分類變量的類別(測試數據集)沒有在訓練數據集總被觀察到,那這個模型會分配一個0(零)概率給它,同時也會無法進行預測。這通常被稱為“零頻率”。為了解決這個問題,我們可以使用平滑技術,拉普拉斯估計是其中最基礎的技術。

  • 樸素貝葉斯也被稱為bad estimator,所以它的概率輸出predict_proba不應被太認真對待。

  • 樸素貝葉斯的另一個限制是獨立預測的假設。在現實生活中,這幾乎是不可能的,各變量間或多或少都會存在相互影響。

樸素貝葉斯的4種應用

實時預測:毫無疑問,樸素貝葉斯很快。

多類預測:這個算法以多類別預測功能聞名,因此可以用來預測多類目標變量的概率。

文本分類/垃圾郵件過濾/情感分析:相比較其他算法,樸素貝葉斯的應用主要集中在文本分類(變量類型多,且更獨立),具有較高的成功率。因此被廣泛應用於垃圾郵件過濾(識別垃圾郵件)和情感分析(在社交媒體平臺分辨積極情緒和消極情緒的用戶)。

推薦系統:樸素貝葉斯分類器和協同過濾結合使用可以過濾出用戶想看到的和不想看到的東西。

關於樸素貝葉斯分類器的幾個黑科技

以下是一些小方法,可以提升樸素貝葉斯分類器的性能:

  • 如果連續特征不是正態分布的,我們應該使用各種不同的方法將其轉換正態分布。

  • 如果測試數據集具有“零頻率”的問題,應用平滑技術“拉普拉斯估計”修正數據集。

  • 刪除重復出現的高度相關的特征,可能會丟失頻率信息,影響效果。

  • 樸素貝葉斯分類在參數調整上選擇有限。我建議把重點放在數據的預處理和特征選擇。

  • 大家可能想應用一些分類組合技術 如ensembling、bagging和boosting,但這些方法都於事無補。因為它們的目的是為了減少差異,樸素貝葉斯沒有需要最小化的差異。

如何建立樸素貝葉斯的基本模型(Python和R)

scikit learn裏有3種樸素貝葉斯的模型:

高斯模型:適用於多個類型變量,假設特征符合高斯分布。

多項式模型:用於離散計數。如一個句子中某個詞語重復出現,我們視它們每個都是獨立的,所以統計多次,概率指數上出現了次方。

伯努利模型:如果特征向量是二進制(即0和1),那這個模型是非常有用的。不同於多項式,伯努利把出現多次的詞語視為只出現一次,更加簡單方便。

你可以根據特定數據集選取上述3個模型中的合適模型。下面我們以高斯模型為例,談談怎麽建立:

  • Python
  •   #Import Library of Gaussian Naive Bayes model
      from sklearn.naive_bayes import GaussianNB
      import numpy as np
    
      #assigning predictor and target variables
      x= np.array([[-3,7],[1,5], [1,2], [-2,0], [2,3], [-4,0], [-1,1], [1,1], [-2,2], [2,7], [-4,1], [-2,7]])
      Y = np.array([3, 3, 3, 3, 4, 3, 3, 4, 3, 4, 4, 4])
    
      #Create a Gaussian Classifier
      model = GaussianNB()
    
      # Train the model using the training sets 
      model.fit(x, y)
    
      #Predict Output 
      predicted= model.predict([[1,2],[3,4]])
      print predicted
    
      Output: ([3,4])
  • R
  •   require(e1071) #Holds the Naive Bayes Classifier
      Train <- read.csv(file.choose())
      Test <- read.csv(file.choose())
    
      #Make sure the target variable is of a two-class classification problem only
    
      levels(Train$Item_Fat_Content)
    
       model <- naiveBayes(Item_Fat_Content~., data = Train)
      class(model) 
      pred <- predict(model,Test)
      table(pred)
    

      

文本分類的主要流程

  1. 樣本數據的獲取
  2. 樣本數據清洗和分詞
  3. 建模與評估
  4. 部署運行


R實現

完整代碼及報告見另一篇博文

分詞

一個好用的包:chinese.misc。說明文檔:https://github.com/githubwwwjjj/chinese.misc

應用示例:

library(jiebaRD)
library(NLP)
library(chinese.misc)
library(jiebaR)
library(tm)
library(MASS)
library(klaR)
library(e1071)

##樣本數據
textData <- teld.ml.rQuery("NewsInformation4BDP")
textData$NewsContent <-as.character(textData$NewsContent)

#自定義分詞器,將需要特殊識別的納入分詞
myCutter<-worker(write=FALSE)
myWord<-c("XXX","XX","x","xxx","xx")
new_user_word(myCutter,myWord)

#去掉英文、字母
slimtextf<-function(x){
  x1<-slim_text(x,
                mycutter = myCutter, 
                rm_place = TRUE, 
                rm_time = TRUE,  
                rm_eng = TRUE,  
                rm_alpha = TRUE, 
                paste = TRUE 
  )
  return (x1)
}
textData$NewsContent <- sapply(as.list(textData$NewsContent),slimtextf,simplify = TRUE);

textData$TFlag <-sample(0:1,nrow(textData),replace=T,prob=c(0.7,0.3))#按7:3拆分訓練集和測試集
textData.Train <- textData[textData$TFlag==0,]
textData.Test <- textData[textData$TFlag==1,]
dim(textData.Train )
dim(textData.Test)
head(textData.Train)

#生成文檔-詞條矩陣DTM(document term matrix)
#stopPattern <- ‘(quot|app|ev|km|model|suv)‘,stop_pattern = stopPattern
#%>%是管道 函數,即將其左邊的值發送給右邊的表達 式,並作為右邊表達式函數的第一個參數,如x<-y %>% f(z) 等價於x<-f(y,z)
dtm.train<-textData.Train$NewsContent%>%
  corp_or_dtm(from="v",type="D",stop_word="jiebar",mycutter=myCutter,control = list(wordLengths=c(2,25)))%>%
  removeSparseTerms(0.99)%>%
  output_dtm(doc_name=textData.Train$SN)
#removeSparseTerms的Sparse參數越小,矩陣越稀疏

dim(dtm.train)#  737 382
#write.csv(dtm.train,‘dtm.train10.csv‘)

dtm.test<-textData.Test$NewsContent%>%
  corp_or_dtm(from="v",type="D",stop_word="jiebar",mycutter=myCutter,control = list(wordLengths=c(2,25)))%>%
  removeSparseTerms(0.99)%>%
  output_dtm(doc_name=textData.Test$SN)

dim(dtm.test)# 334 386

  

建模

有兩個包可用: e1071和klaR

e1071示例:

#訓練樸素貝葉斯模型
model <- naiveBayes(dtm.train,as.factor(textData.Train$AState),laplace = 1)

#預測測試集
pre<-predict(model,dtm.test)
#pre<-predict(model,dtm.test,type=c("raw")) #輸出概率,因為兩個概率懸殊太大,無意義,不采用(見理論篇的缺點部分)
#默認值type = c("class", "raw")

  

klaR示例:在建模時報錯,後帶分析說明

#訓練樸素貝葉斯模型
model <- NaiveBayes(dtm.train,as.factor(textData.Train$AState),usekernel=FALSE,fL = 1) 
#報錯:Zero variances for at least one class in variables: 保時捷, 比亞迪, 戴姆勒, 環保, 混合, 集團, 加快, 開發......

#預測測試集
pre<-predict(model,dtm.test)
報錯:Zero variances for at least one class in variables: 保時捷, 比亞迪, 戴姆勒, 環保, 混合, 集團, 加快, 開發.....
錯誤原因:存在0方差的變量
錯誤信息對應的源碼:

技術分享圖片

  解決方案:如果一定要使用這個包,那就修改源碼,把stop代碼幹掉,讓它繼續執行。然後自己編譯這個包。

評估

在應用案例中采用了10折交叉驗證,執行10次取均值。

相關指標的說明見https://www.cnblogs.com/xianhan/p/9277194.html

#性能評價
performance<-prop.table(table(textData.Test$AState,pre))
performance
#準確率:4和5預測正確的比例**
accuracyrate<-(performance[1,1]+performance[2,2])
accuracyrate # 0.5174603->0.5434783
#靈敏度(查全率\召回率):實際5,其中預測正確的比例*****
sensitivity <-performance[2,2]/(performance[2,1]+performance[2,2])
sensitivity #0.8791209->0.816092
#精密性:預測5,其中預測正確的比例**
precision <-performance[2,2]/(performance[1,2]+performance[2,2])
precision # 0.361991-> 0.3514851
#特異性:實際4,其中預測正確的比例*
specificity <-performance[1,1]/(performance[1,1]+performance[1,2])
specificity #0.3705357->0.4425532


  

參考

中文文本分析方便工具R包chinese.misc的中文說明

https://github.com/githubwwwjjj/chinese.misc

R語言-貝葉斯分類器-文本情感分析

https://zhuanlan.zhihu.com/p/26735328

R實戰——大眾點評-漢拿山(深國投店)評論情感淺析

https://mp.weixin.qq.com/s?__biz=MzUyNzU3MTgyOA==&mid=2247483690&idx=1&sn=9b8ea4b159e5885c0b99f3529a25c488&chksm=fa7ccf31cd0b4627d8f7321a392036686c1f59a0e365b3976c8ba4810a407f46b53cff4e63f0#rd

基於Naive Bayes算法的文本分類