樸素貝葉斯之例項
阿新 • • 發佈:2018-12-16
樸素貝葉斯例項
目錄
1.言論過濾器程式碼
import numpy as np from functools import reduce #樸素貝葉斯之言論過濾器# """ 函式說明:建立實驗樣本 Parameters: 無 Returns: postingList - 實驗樣本切分的詞條 classVec - 類別標籤向量 詞條與0,1對應。 """ def loadDataSet(): postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], #切分的詞條 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'], ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'], ['stop', 'posting', 'stupid', 'worthless', 'garbage'], ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'], ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']] classVec = [0,1,0,1,0,1] #類別標籤向量,1代表侮辱性詞彙,0代表不是 return postingList,classVec #返回實驗樣本切分的詞條和類別標籤向量 """ 函式說明:將切分的實驗樣本詞條整理成不重複的詞條列表,也就是詞彙表 Parameters: dataSet - 整理的樣本資料集 Returns: vocabSet - 返回不重複的詞條列表,也就是詞彙表 """ def createVocabList(dataSet): vocabSet = set([]) #建立一個空的不重複列表 for document in dataSet: vocabSet = vocabSet | set(document) #取並集 return list(vocabSet) """ 函式說明:根據vocabList詞彙表,將inputSet向量化,向量的每個元素為1或0 Parameters: vocabList - createVocabList返回的列表 inputSet - 切分的詞條列表 Returns: returnVec - 文件向量,詞集模型 """ 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 #返回文件向量 """ 函式說明:樸素貝葉斯分類器訓練函式 Parameters: trainMatrix - 訓練文件矩陣,即setOfWords2Vec返回的returnVec構成的矩陣 trainCategory - 訓練類別標籤向量,即loadDataSet返回的classVec Returns: p0Vect - 侮辱類的條件概率陣列 p1Vect - 非侮辱類的條件概率陣列 pAbusive - 文件屬於侮辱類的概率 """ def trainNB0(trainMatrix,trainCategory): numTrainDocs = len(trainMatrix) #計算訓練的文件數目 numWords = len(trainMatrix[0]) #計算每篇文件的詞條數 pAbusive = sum(trainCategory)/float(numTrainDocs) #文件屬於侮辱類的概率 p0Num = np.zeros(numWords); p1Num = np.zeros(numWords) #建立numpy.zeros陣列, p0Denom = 2.0; p1Denom = 2.0 #分母初始化為2.0 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 = p1Num/p1Denom #相除 p0Vect = p0Num/p0Denom return p0Vect,p1Vect,pAbusive #返回屬於侮辱類的條件概率陣列,屬於非侮辱類的條件概率陣列,文件屬於侮辱類的概率 """ 函式說明:樸素貝葉斯分類器分類函式 Parameters: vec2Classify - 待分類的詞條陣列 p0Vec - 侮辱類的條件概率陣列 p1Vec -非侮辱類的條件概率陣列 pClass1 - 文件屬於侮辱類的概率 Returns: 0 - 屬於非侮辱類 1 - 屬於侮辱類 """ def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): p1 = sum(vec2Classify * p1Vec) + np.log(pClass1) #對應元素相乘。logA * B = logA + logB,所以這裡加上log(pClass1) p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1) if p1 > p0: return 1 else: return 0 """ 函式說明:測試樸素貝葉斯分類器 Parameters: 無 Returns: 無 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """ def testingNB(): listOPosts,listClasses = loadDataSet() #建立實驗樣本 myVocabList = createVocabList(listOPosts) #建立詞彙表 trainMat=[] for postinDoc in listOPosts: trainMat.append(setOfWords2Vec(myVocabList, postinDoc)) #將實驗樣本向量化 p0V,p1V,pAb = trainNB0(np.array(trainMat),np.array(listClasses)) #訓練樸素貝葉斯分類器 testEntry = ['love', 'my', 'dalmation'] #測試樣本1 thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry)) #測試樣本向量化 if classifyNB(thisDoc,p0V,p1V,pAb): print(testEntry,'屬於侮辱類') #執行分類並列印分類結果 else: print(testEntry,'屬於非侮辱類') #執行分類並列印分類結果 testEntry = ['stupid', 'garbage'] #測試樣本2 thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry)) #測試樣本向量化 if classifyNB(thisDoc,p0V,p1V,pAb): print(testEntry,'屬於侮辱類') #執行分類並列印分類結果 else: print(testEntry,'屬於非侮辱類') #執行分類並列印分類結果 if __name__ == '__main__': testingNB()
2.過濾垃圾郵件程式碼
# -*- coding: UTF-8 -*- import numpy as np import random import re """ 函式說明:將切分的實驗樣本詞條整理成不重複的詞條列表,也就是詞彙表 Parameters: dataSet - 整理的樣本資料集 Returns: vocabSet - 返回不重複的詞條列表,也就是詞彙表 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """ def createVocabList(dataSet): vocabSet = set([]) #建立一個空的不重複列表 for document in dataSet: vocabSet = vocabSet | set(document) #取並集 return list(vocabSet) """ 函式說明:根據vocabList詞彙表,將inputSet向量化,向量的每個元素為1或0 Parameters: vocabList - createVocabList返回的列表 inputSet - 切分的詞條列表 Returns: returnVec - 文件向量,詞集模型 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """ 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 #返回文件向量 """ 函式說明:根據vocabList詞彙表,構建詞袋模型 Parameters: vocabList - createVocabList返回的列表 inputSet - 切分的詞條列表 Returns: returnVec - 文件向量,詞袋模型 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-14 """ def bagOfWords2VecMN(vocabList, inputSet): returnVec = [0]*len(vocabList) #建立一個其中所含元素都為0的向量 for word in inputSet: #遍歷每個詞條 if word in vocabList: #如果詞條存在於詞彙表中,則計數加一 returnVec[vocabList.index(word)] += 1 return returnVec #返回詞袋模型 """ 函式說明:樸素貝葉斯分類器訓練函式 Parameters: trainMatrix - 訓練文件矩陣,即setOfWords2Vec返回的returnVec構成的矩陣 trainCategory - 訓練類別標籤向量,即loadDataSet返回的classVec Returns: p0Vect - 侮辱類的條件概率陣列 p1Vect - 非侮辱類的條件概率陣列 pAbusive - 文件屬於侮辱類的概率 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """ 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 #返回屬於侮辱類的條件概率陣列,屬於非侮辱類的條件概率陣列,文件屬於侮辱類的概率 """ 函式說明:樸素貝葉斯分類器分類函式 Parameters: vec2Classify - 待分類的詞條陣列 p0Vec - 侮辱類的條件概率陣列 p1Vec -非侮辱類的條件概率陣列 pClass1 - 文件屬於侮辱類的概率 Returns: 0 - 屬於非侮辱類 1 - 屬於侮辱類 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """ def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): p1 = sum(vec2Classify * p1Vec) + np.log(pClass1) #對應元素相乘。logA * B = logA + logB,所以這裡加上log(pClass1) p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1) if p1 > p0: return 1 else: return 0 """ 函式說明:樸素貝葉斯分類器訓練函式 Parameters: trainMatrix - 訓練文件矩陣,即setOfWords2Vec返回的returnVec構成的矩陣 trainCategory - 訓練類別標籤向量,即loadDataSet返回的classVec Returns: p0Vect - 侮辱類的條件概率陣列 p1Vect - 非侮辱類的條件概率陣列 pAbusive - 文件屬於侮辱類的概率 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """ 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 #返回屬於侮辱類的條件概率陣列,屬於非侮辱類的條件概率陣列,文件屬於侮辱類的概率 """ 函式說明:接收一個大字串並將其解析為字串列表 Parameters: 無 Returns: 無 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-14 """ def textParse(bigString): #將字串轉換為字元列表 listOfTokens = re.split(r'\W*', bigString) #將特殊符號作為切分標誌進行字串切分,即非字母、非數字 return [tok.lower() for tok in listOfTokens if len(tok) > 2] #除了單個字母,例如大寫的I,其它單詞變成小寫 """ 函式說明:測試樸素貝葉斯分類器 Parameters: 無 Returns: 無 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-14 """ def spamTest(): docList = []; classList = []; fullText = [] for i in range(1, 26): #遍歷25個txt檔案 wordList = textParse(open('email/spam/%d.txt' % i, 'r').read()) #讀取每個垃圾郵件,並字串轉換成字串列表 docList.append(wordList) fullText.append(wordList) classList.append(1) #標記垃圾郵件,1表示垃圾檔案 wordList = textParse(open('email/ham/%d.txt' % i, 'r').read()) #讀取每個非垃圾郵件,並字串轉換成字串列表 docList.append(wordList) fullText.append(wordList) classList.append(0) #標記非垃圾郵件,1表示垃圾檔案 vocabList = createVocabList(docList) #建立詞彙表,不重複 trainingSet = list(range(50)); testSet = [] #建立儲存訓練集的索引值的列表和測試集的索引值的列表 for i in range(10): #從50個郵件中,隨機挑選出40個作為訓練集,10個做測試集 randIndex = int(random.uniform(0, len(trainingSet))) #隨機選取索索引值 testSet.append(trainingSet[randIndex]) #新增測試集的索引值 del(trainingSet[randIndex]) #在訓練集列表中刪除新增到測試集的索引值 trainMat = []; trainClasses = [] #建立訓練集矩陣和訓練集類別標籤系向量 for docIndex in trainingSet: #遍歷訓練集 trainMat.append(setOfWords2Vec(vocabList, docList[docIndex])) #將生成的詞集模型新增到訓練矩陣中 trainClasses.append(classList[docIndex]) #將類別新增到訓練集類別標籤系向量中 p0V, p1V, pSpam = trainNB0(np.array(trainMat), np.array(trainClasses)) #訓練樸素貝葉斯模型 errorCount = 0 #錯誤分類計數 for docIndex in testSet: #遍歷測試集 wordVector = setOfWords2Vec(vocabList, docList[docIndex]) #測試集的詞集模型 if classifyNB(np.array(wordVector), p0V, p1V, pSpam) != classList[docIndex]: #如果分類錯誤 errorCount += 1 #錯誤計數加1 print("分類錯誤的測試集:",docList[docIndex]) print('錯誤率:%.2f%%' % (float(errorCount) / len(testSet) * 100)) if __name__ == '__main__': spamTest()