朴素貝葉斯


朴素貝葉斯模型

朴素貝葉斯的應用

朴素貝葉斯模型是文本領域永恆的經典,廣泛應用在各類文本分析的任務上。只要遇到了文本分類問題,第一個需要想到的方法就是朴素貝葉斯,它在文本分類任務上是一個非常靠譜的基准(baseline)。

比如對於垃圾郵件的分類,朴素貝葉斯是一個極其有效且簡單的模型。

不要小看一個簡單的模型。實際上,我們真正需要的是既簡單同時又有效的模型,因為最終的目的是用最小成本來解決問題。一個簡單的模型既有利於短時間內訓練,也有助於后續的維護和管理。

朴素貝葉斯,這個名字里的“朴素”源自於概率統計里的“條件獨立”,因為在構造模型過程中做了一層基於條件獨立的簡化操作。 朴素貝葉斯模型作為分類算法,非常適合用在各類文本分類任務上,如:

  • 垃圾郵件分類: 自動判斷一個郵件是否為垃圾郵件或者正常郵件;
  • 文本主題分類: 把一個文本按照主題做分類如體育類、娛樂類;
  • 情感分析: 把給定的文本分類成正面或者負面情感;

朴素貝葉斯核心思想

垃圾郵件示例:

  您提交的#3152號工單:來自李先生的留言 有更新。

  請點擊以下鏈接查看工單處理進度:

  https://tingyun.kf5.com/hc/request/view/3152/

  要添加另外的工單評論,請回復此郵件

啟發: 有些單詞經常出現在垃圾郵件里;

朴素貝葉斯的核心思想極其簡單:  其實就是統計出不同文本類別中出現的單詞的詞頻。

  對於垃圾郵件的分類任務,我們需要統計出哪些單詞經常出現在垃圾郵件,哪些單詞經常出現在正常郵件就可以了。

如果在郵件里看到了“廣告”,“購買”,“鏈接”等關鍵詞,可以認為這個很可能是垃圾郵件,因為這些單詞經常出現在垃圾郵件中,其實很多郵件過濾系統是這樣過濾垃圾郵件的。當然,我們也可以自行設定一些規

則來過濾垃圾郵件。在這種規則里,我們通常也是指定哪些單詞跟垃圾郵件相關。

對於垃圾郵件的分類,  直接弄一份關鍵詞詞庫,  然后一旦郵件里包含了這些詞就認為是垃圾郵件, 

如果按照詞庫來判斷一個郵件是垃圾郵件還是正常郵件,這有點類似於通常說的“一刀切”的方法。其實更好的方案是加入一些概率的要素,把不確定性也加進來,比如雖然出現了“廣告”,“推銷”等關鍵詞,但同時也出現

了大量的沒有包含在詞庫里的單詞,最終按照概率的角度可以判定為是正常郵件,這實際上就是朴素貝葉斯模型的核心思想。

如果以詞庫為依據來直接判定郵件的種類是存在一定的問題的。它的問題在於,即便出現了一些廣告類單詞,但並不一定是垃圾郵件; 沒有出現任何廣告類單詞也不一定是正常郵件。所以每個單詞雖然有傾向性,但不能以偏概全。

如何把這些不同的單詞以概率統計的方式整合在一起呢? 答案就是朴素貝葉斯!

利用朴素貝葉斯識別垃圾郵件

 

 

使用朴素貝葉斯模型一般需要兩步驟:

首先,統計出每一個單詞對一個郵件成為垃圾郵件或正常郵件的貢獻。比如 p ( 廣告 | 垃圾 ) 、p廣告正常 )分別代表在 垃圾 / 正常郵件里出現 “廣告”這個關鍵詞的概率。

其次,用這些統計的結果對一個新的郵件做預測

朴素貝葉斯廣泛地應用在文本分類任務中,其中最為經典的場景為垃圾文本分類(如垃圾郵件分類: 給定一個郵件,把它自動分類為垃圾或者正常郵件)。這個任務本身是屬於文本分析任務,因為對應的數據均為文

本類型,所以對於此類任務我們首先需要把文本轉換成向量的形式,然后再帶入到模型當中。

import pandas as pd import numpy as np import matplotlib.mlab as mlab import matplotlib.pyplot as plt # 讀取spam.csv文件 df = pd.read_csv("/home/anaconda/data/Z_NLP/spam.csv", encoding='latin') df.head() # 重命名數據中的v1和v2列,使得擁有更好的可讀性 df.rename(columns={'v1':'Label', 'v2':'Text'}, inplace=True) df.head() # 把'ham'和'spam'標簽重新命名為數字0和1 df['numLabel'] = df['Label'].map({'ham':0, 'spam':1}) df.head() # 統計有多少個ham,有多少個spam print ("# of ham : ", len(df[df.numLabel == 0]), " # of spam: ", len(df[df.numLabel == 1])) print ("# of total samples: ", len(df)) # 統計文本的長度信息,並畫出一個histogram text_lengths = [len(df.loc[i,'Text']) for i in range(len(df))] plt.hist(text_lengths, 100, facecolor='blue', alpha=0.5) plt.xlim([0,200]) plt.show() # 導入英文的停用詞庫 from sklearn.feature_extraction.text import CountVectorizer # 構建文本的向量 (基於詞頻的表示) vectorizer = CountVectorizer() X = vectorizer.fit_transform(df.Text) y = df.numLabel # 把數據分成訓練數據和測試數據 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=100) print ("訓練數據中的樣本個數: ", X_train.shape[0], "測試數據中的樣本個數: ", X_test.shape[0]) # 利用朴素貝葉斯做訓練 from sklearn.naive_bayes import MultinomialNB from sklearn.metrics import accuracy_score clf = MultinomialNB(alpha=1.0, fit_prior=True) clf.fit(X_train, y_train) y_pred = clf.predict(X_test) print("accuracy on test data: ", accuracy_score(y_test, y_pred)) # 打印混淆矩陣 from sklearn.metrics import confusion_matrix confusion_matrix(y_test, y_pred, labels=[0, 1]) ======>>> # of ham : 4825 # of spam: 747 # of total samples: 5572 <Figure size 640x480 with 1 Axes> 訓練數據中的樣本個數: 4457 測試數據中的樣本個數: 1115 accuracy on test data: 0.97847533632287 array([[956, 14], [ 10, 135]])

 

 

朴素貝葉斯模型的訓練 

朴素貝葉斯的訓練過程,也是詞頻統計的過程。

計算單詞的概率

正如之前說過的一樣,朴素貝葉斯訓練的核心步驟就是統計各個單詞在不同類別中的概率。 舉個例子,當我們去分析一個文件是否為垃圾郵件或者正常郵件時,一個判斷的依據是如果很多跟垃圾郵件相關的關鍵

詞出現在了文本里,我們即可以把它歸類為垃圾郵件,這些決策最終基於概率統計的方式來實現。

總體來講,朴素貝葉斯分為兩個階段:

  • 計算每個單詞在不同分類中所出現的概率,這個概率是基於語料庫(訓練數據)來獲得的。
  • 利用已經計算好的概率,再結合貝葉斯定理就可以算出對於一個新的文本,它屬於某一個類別的概率值,並通過這個結果做最后的分類決策。

 

 

 

 

 

 

 

 

 

 

 

 

 

利用計算好的概率來預測

目前為止我們已經算好了每一個單詞在不同類別中的概率,以及垃圾郵件和正常郵件在整個數據中的占比,后者也稱之為先驗概率(prior)。統計完這些概率之后,如何使用它們來預測一個郵件是否為垃圾或者正常郵件呢?

 

Bayes_Theorem

為了表示兩個條件概率值 p(垃圾|郵件內容)和 p(正常|郵件內容),需要用到一個著名的概率公式-貝葉斯定理。利用貝葉斯定理可以把上述條件概率做進一步的分解,最終可以計算出它們的值

 

 

計算預測概率

 

 

 

 

 

 

 

 

在預測過程中我們使用一個叫作條件獨立(conditional independence)的假設。簡單來講,基於這個性質可以把條件概率p(x,y|z)p(xyz)寫成p(x,y|z)=p(x|z)p(y|z)p(xyz)=p(xz)p(yz)的形式,

這時候可以說變量xx和變量yy是條件獨立於變量zz的。

這也是為什么把朴素貝葉斯說成“朴素”的主要原因,因為做了一層計算上的簡化。如果不使用條件獨立的假設,我們是不能把概率p(x,y|z)p(xyz)寫成上述形式的,這樣一來問題就變得格外地復雜。

條件獨立的性質可以延展到更多的變量,如p(x_1,x_2,x_3|y)=p(x_1|y)p(x_2|y)p(x_3|y)p(x1x2x3y)=p(x1y)p(x2y)p(x3y)。當我們把這里的每個變量x_ixi看作是每一個單詞的時候,就得到了朴素貝葉斯模型。

 

平滑操作

另外,在上述過程中可以看到分子的計算過程涉及到了很多概率的乘積,一旦遇到這種情形,就要知道可能會有潛在的風險。比如其中一個概率值等於0,那不管其他概率值是多少,最后的結果一定為0,有點類

似於“功虧一簣“的情況,明明出現了很多垃圾郵件相關的單詞,就是因為其中的一個概率0,最后判定為屬於垃圾郵件的概率為0,這顯然是不合理的。為了處理這種情況,有一個關鍵性操作叫作平滑

(smoothing),其中最為常見的平滑方法為加一平滑(add-one smoothing)

 

 

 

 

 

 朴素貝葉斯的最大似然估計

從最大似然估計的角度來理解朴素貝葉斯模型。換句話說,首先根據最大似然估計來構造朴素貝葉斯的目標函數,接下來再通過優化手段來求解朴素貝葉斯的最優解。

朴素貝葉斯模型以及如何估算每個單詞的概率,並用這個概率來預測一個文本的分類。

但有沒有思考過: 為什么要計算這些單詞的概率? 它的依據是什么? 這個問題看似有點愚蠢,但實際上需要認真地思考才能發現其背后的奧妙之處。

計算語料庫中每個單詞的條件概率,這個過程實際上是模型訓練的過程。另外,模型的訓練過程其實就是尋找最優解的過程。

從另外一個更嚴謹的角度來學習朴素貝葉斯。首先,構造朴素貝葉斯的目標函數,之后再試着去尋找朴素貝葉斯的最優解。最終會發現,以這種方式得出來的最優解恰恰就是計算出的結果; 

為了推導出朴素貝葉斯的目標函數,仍需要從最大似然開始入手,並通過最大似然估計來獲得朴素貝葉斯的目標函數。

 

 

 

 

 投硬幣問題

 

 

 

 

 

 

有了朴素貝葉斯的目標函數之后,剩下的環節無非就是尋找最優解的過程了。從上述目標函數中可以發現它具有一個限制條件。那這樣的目標函數我們應該如何去優化呢?

這種優化問題也稱之為帶限制條件的優化(constrained optimization)。 

帶限制條件的優化

帶限制條件的優化相比無限制條件的優化稍微復雜一些。對於無限制條件的優化問題,在邏輯回歸中已經涉及到了。 回顧無限制條件的優化,同時重點來學習帶限制條件的優化問題如何解決。

 

 

朴素貝葉斯目標函數的優化

當理解了如何求解帶限制條件的優化問題之后,就可以試着來求解朴素貝葉斯目標函數的最優解了。 整個過程有一些繁瑣,但用到的基本知識都是上面提過的內容,只要細心去體會,應該都能看得懂。

 

 

 

通過這種方式得出來的結果恰好跟上節的結果是吻合的,所以從這個例子可以看出,任何一個計算結果實際上都是有背后的依據的。為了更好地理解每一個知識點,我們需要嘗試着去深挖底層的細節,這樣才能

達到打通知識體系的目的。

生成模型與判別模型

兩種模型直觀上的區別

生成模型和判別模型在機器學習領域是一個非常重要的概念。任意的機器學習模型我們均可以歸類為判別模型或者生成模型。那具體什么是生成模型,什么是判別模型呢?

從字面上來看, 生成模型模型可以生成數據;(生成模型的一大功能是,訓練好之后可以用來生成新的數據。)

   讓機器學習寫程序?讓機器學習學習畫畫?讓機器編一個曲子?這些事情生成模型都可以做,當然效果好不好是另一回事情了。

訓練一個生成模型通常不僅可以用來完成識別或者分類任務,也可以用來生成一些新的數據,包括圖片、文章、代碼、視頻、音頻等等。 雖然生成這些數據本身具有很大挑戰,但至少從理論的角度來講是一條可

行的道路。

從字面上來理解, 判別模型主要用來判別樣本的類別;(不同於生成模型,判別模型是沒有辦法用來生成新數據的。雖然生成即可以用來解決判別問題,也可以生成數據,但這不代表生成模型由於判別模型。實際上,

很多判別任務(如分類任務)上, 判別模型的表現要好於生成模型。)

判別模型的初衷是用來解決判別問題,而且只做一件事情(不像生成模型即可以解決分類問題也可以解決生成數據的問題),所以在分類問題上它的效果通常要優於生成模型的。接下來試着從另外一個角度來理解

它倆之間的區別。

 

 

 

 

 從數據的角度理解它倆的區別

 

 

 邏輯回歸的最大似然是基於條件概率來構造的,但朴素貝葉斯的最大似然是基於x和y的聯合概率來構造的;所以邏輯回歸是判別模型,朴素貝葉斯是生成模型;

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM