一、算法介紹https://www.cnblogs.com/love528/p/10125089.html
二、實現過程
實驗步驟
(1)收集數據:提供文本文件。
(2)准備數據:將文本文件解析成詞條向量。
(3)分析數據:檢查詞條確保解析的正確性。
(4)訓練算法:計算不同的獨立特征的條件概率。
(5)測試算法:計算錯誤率。
(6)使用算法:構建一個完整的程序對一組文檔進行分類。
主要代碼解析
(1) 分詞
使用正則表達式將郵件文本其划分成一個個單詞的形式
import re
def textParse(bigString):
listOfTokens = re.split(r'\W*', bigString)
return [tok.lower() for tok in listOfTokens if len(tok) > 2]
(2) 生成詞匯表
將所有的郵件進行分詞后生成一個dataSet,然后生成一個詞匯表,這個詞匯表是一個集合,即每個單詞只出現一次。
def createVocabList(dataSet):
vocabSet = set([]) # 創建一個空的不重復列表
for document in dataSet:
vocabSet = vocabSet | set(document) # 取並集
return list(vocabSet)
(3) 生成詞向量
每一封郵件的詞匯都存在了詞匯表中,因此將每一封郵件生成一個詞向量,若該詞匯存在於詞匯表中,對應位置則為1,不存在為0,這里詞向量的維度與詞匯表相同。
def setOfWords2Vec(vocabList, inputSet):
returnVec = [0] * len(vocabList) # 創建一個元素都為0的向量
for word in inputSet:
if word in vocabList: # 如果詞條存在於詞匯表中,則置1
returnVec[vocabList.index(word)] = 1 # 查找單詞索引
else:
print("the word: %s is not in my Vocabulary!" % word)
return returnVec # 返回文檔向量
(4) 訓練算法
計算Pr(W|S)、Pr(W|H),Pr( |S)表示在垃圾郵件的條件下第i個特征的概率,首先將所有的類別為1的詞向量相加,可以得到每個特征的個數,除以類別為1的單詞總數就是垃圾郵件中每個單詞的概率。
def trainNB0(trainMatrix, trainCategory):
numTrainDocs = len(trainMatrix) # 計算訓練的文檔數目
numWords = len(trainMatrix[0]) # 計算每篇文檔的詞條數
pAbusive = sum(trainCategory) / float(numTrainDocs) # 文檔屬於垃圾郵件類的概率
p0Num = np.ones(numWords)
p1Num = np.ones(numWords) # 創建numpy.ones數組,詞條出現數初始化為1,拉普拉斯平滑
p0Denom = 2.0
p1Denom = 2.0 # 分母初始化為2 ,拉普拉斯平滑
for i in range(numTrainDocs):
if trainCategory[i] == 1: # 統計屬於侮辱類的條件概率所需的數據,即P(w0|1),P(w1|1),P(w2|1)···
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else: # 統計屬於非侮辱類的條件概率所需的數據,即P(w0|0),P(w1|0),P(w2|0)···
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = np.log(p1Num / p1Denom)
p0Vect = np.log(p0Num / p0Denom) # 取對數,防止下溢出
return p0Vect, p1Vect, pAbusive # 返回屬於正常郵件類的條件概率數組,屬於侮辱垃圾郵件類的條件概率數組,文檔屬於垃圾郵件類的概率
完整代碼