1. 程式人生 > >機器學習之樸素貝葉斯(附垃圾郵件分類)

機器學習之樸素貝葉斯(附垃圾郵件分類)

樸素貝葉斯分類器介紹概述

 樸素貝葉斯分類器技術基於貝葉斯定理,特別適用於輸入維數較高的情況。儘管樸素貝葉斯方法簡單,但它通常比更復雜的分類方法更勝一籌。

                                                                    

 為了演示樸素貝葉斯分類的概念,請考慮上面插圖中顯示的示例。如前所述,這些物體可以分為綠色或紅色。我們的任務是對新事件進行分類,即根據當前物件,判定它們屬於哪個類標籤。

由於綠色樣本的數量是紅色樣本的兩倍,因此我們就可以知道,一個新例項(尚未觀察到)是綠色的可能性是2倍紅色的可能性。在貝葉斯分析中,這種概率預測被稱為先驗概率。先驗概率是基於之前的經驗,在這種情況下,綠色和紅色物體的百分比,通常用於實際發生之前的預測。

因此我們可以寫:

P(green)=\frac{greenNumber}{totalNumber}

P(red)=\frac{redNumber}{totalNumber}

因為總共有60個物件,其中40個是綠色的,20個是紅色的,所以類成員的先驗概率是

在闡述了我們的先驗概率之後,我們現在可以對一個新物件(白圈)進行分類了。由於物件是很好地聚集在一起的,因此可以合理地假設X附近的綠色(或紅色)物件越多,新的情況就越有可能屬於那個特定的顏色。為了度量這種可能性,我們在X周圍畫一個圓,它包含一個點的數字(要預先選擇),而不考慮它們的類標籤。然後我們計算屬於每個類標籤的圓中的點數。由此我們計算了可能性:

從上面式子中可以清楚地看出,給定綠色的X的可能性比給定紅色的X的可能性小,因為圓包含1個綠色物體和3個紅色物體。因此有

雖然先驗概率表明X可能屬於綠色(假設綠色的數量是紅色的兩倍),但可能性表明並非如此;X的類成員是紅色的(假設X附近的紅色物件比綠色物件多)。在貝葉斯分析中,最終的分類是將兩種資訊源結合起來得到的,即根據所謂的貝葉斯規則來形成後驗概率。

最後,我們將X分類為紅色,因為它的類隸屬度達到最大的後驗概率。

請注意。上述概率沒有標準化。但是,這並不影響分類結果,因為它們的標準化常數是相同的。

樸素貝葉斯理論

以上,提供了一個使用樸素貝葉斯理解分類的直觀示例。接下來將進一步詳細介紹所涉及的技術問題。樸素貝葉斯分類器可以處理任意數量的自變數,無論是連續的還是分類的。給定一組變數,X = {x1,x2, X…,我們想在一系列可能的結果C = {c1,c2, C…,cd}中構造事件Cj的後驗概率。換句話說,X是預測因子,C是因變數中存在的類別級別的集合。使用貝葉斯規則

 p(Cj | x1,x2,x...,xd)是事件的後驗概率,也就是X屬於Cj的概率。

雖然對於預測器(獨立)變數是獨立的這一假設並不總是準確的,但它極大地簡化了分類任務,因為它允許對每個變數分別計算類的條件密度p(x_{k} | Cj),即它將一個多維任務簡化為多個一維任務。實際上,樸素貝葉斯將高維密度估計任務簡化為一維核密度估計。此外,該假設對後驗概率影響不大,尤其是在決策邊界附近的區域,因此分類任務不受影響。

樸素貝葉斯可以用幾種不同的方法建模,包括正規、對數正規、伽馬和泊松密度函式:

請注意!泊松變數在這裡被認為是連續的,因為它們是有序的,而不是真正的分類。對於分類變數,使用離散概率,分類級別的值與訓練資料中的條件頻率成正比。

垃圾郵件分類實現

我們將與scikit一起使用Python 3—學習為SMS訊息構建一個非常簡單的垃圾郵件檢測器(對於年輕人來說,這是我們在中世紀時用於訊息傳遞的工具)。您可以從這個連結找到並下載資料集。我們需要三個庫來簡化編碼:scikit-learn、pandas和nltk。您可以使用pip或conda來安裝它們。

簡訊垃圾郵件收集v.1是一組SMS標記的訊息,已收集用於SMS垃圾郵件研究。它包含一組英語簡訊,包含5574條簡訊,按照ham(合法)或spam標記。其中,簡訊合法資訊4827條(86.6%),垃圾簡訊747條(13.4%)。要載入資料,可以使用pandas的Dataframe read_table方法。這允許我們定義分隔符(在本例中是選項卡)並相應地重新命名列。 要載入資料,可以使用pandas的Dataframe read_table方法。這允許我們定義一個分隔符(在本例中是一個選項卡),並相應地重新命名列:

import pandas as pd 
df = pd.read_table('SMSSpamCollection', sep='\t', header=None, names=['label', 'message'])

一旦我們準備好了資料,就該做一些預處理了。我們將專注於為手頭的任務消除無用的差異。首先,我們必須為我們的分類器將標籤從字串轉換為二進位制值: 

df['label'] = df.label.map({'ham': 0, 'spam': 1})  

其次,將訊息中的所有字元轉換為小寫:

df['message'] = df.message.map(lambda x: x.lower()) 

第三,去掉標點符號:

df['message'] = df.message.str.replace('[^\w\s]', '')  

第四,使用nltk將訊息標記為單個單詞。首先,我們必須從控制檯匯入和下載記號賦予器:

import nltk  
nltk.download() 

將出現一個安裝視窗。轉到“Models”選項卡,從“Identifier”列中選擇“punkt”。然後點選“下載”,它將安裝必要的檔案。那它就應該工作了!現在我們可以應用記號化:

df['message'] = df['message'].apply(nltk.word_tokenize)  

第五,我們將執行詞幹提取。詞幹提取的思想是使我們的文字規範化,因為不管時態如何,詞的所有變體都具有相同的含義。最流行的詞幹提取演算法之一是PorterStemmer:

from nltk.stem import PorterStemmer

stemmer = PorterStemmer()

df['message'] = df['message'].apply(lambda x: [stemmer.stem(y) for y in x]) 

最後,我們將資料轉換為事件,這些特徵將被輸入到我們的模型中:

from sklearn.feature_extraction.text import CountVectorizer

# This converts the list of words into space-separated strings
df['message'] = df['message'].apply(lambda x: ' '.join(x))

count_vect = CountVectorizer()  
counts = count_vect.fit_transform(df['message'])  

我們可以讓它作為每條訊息的簡單字數,但最好使用術語頻率逆文件頻率,即tf-idf:


from sklearn.feature_extraction.text import TfidfTransformer

transformer = TfidfTransformer().fit(counts)

counts = transformer.transform(counts)  

模型訓練

現在我們已經從資料中執行了特徵提取,現在是構建模型的時候了。我們將從將我們的資料分割為訓練和測試集開始:


from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(counts, df['label'], test_size=0.1, random_state=69)  

然後,我們所要做的就是初始化樸素貝葉斯分類器並對資料進行擬合。對於文字分類問題,多項式樸素貝葉斯分類器非常適合:

from sklearn.naive_bayes import MultinomialNB

model = MultinomialNB().fit(X_train, y_train) 

模型評估

一旦我們把分類器放在一起,我們可以在測試集中評估它的效能:

import numpy as np

predicted = model.predict(X_test)

print(np.mean(predicted == y_test))  

我們簡單樸素的貝葉斯分類器有98.2%的準確性與這個具體的測試集!但是僅僅提供準確性是不夠的,因為我們的資料集在標籤方面是不平衡的(86.6%合法,而垃圾郵件佔13.4%)。我們的分類器可能在忽略垃圾郵件類的同時過於適合合法類。為了解決這個不確定性,讓我們來看看混淆矩陣:

from sklearn.metrics import confusion_matrix

print(confusion_matrix(y_test, predicted))  

confsion_matrix方法將列印如下內容:

[[478   4]
[   6  70]]

正如我們所看到的,錯誤的數量在合法和垃圾郵件之間是相當平衡的,4條合法訊息被分類為垃圾郵件,6條合法訊息被分類為垃圾郵件。總的來說,這些對於我們簡單的分類器來說都是非常好的結果。

本文從樸素貝葉斯分類器的理論和實踐兩個方面對樸素貝葉斯分類器進行了介紹。我們設計了一個簡單的多模態樸素貝葉斯分類器,該分類器對簡訊垃圾郵件的檢測準確率達到了98.2%。