您好,登錄后才能下訂單哦!
小編給大家分享一下python怎么實現(xiàn)基于樸素貝葉斯的垃圾分類算法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
一、模型方法
本工程采用的模型方法為樸素貝葉斯分類算法,它的核心算法思想基于概率論。我們稱之為“樸素”,是因為整個形式化過程只做最原始、最簡單的假設。樸素貝葉斯是貝葉斯決策理論的一部分,所以講述樸素貝葉斯之前有必要快速了解一下貝葉斯決策理論。假設現(xiàn)在我們有一個數(shù)據(jù)集,它由兩類數(shù)據(jù)組成,數(shù)據(jù)分布如下圖所示。
我們現(xiàn)在用p1(x,y)表示數(shù)據(jù)點(x,y)屬于類別1(圖中用圓點表示的類別)的概率,用p2(x,y)表示數(shù)據(jù)點(x,y)屬于類別2(圖中用三角形表示的類別)的概率,那么對于一個新數(shù)據(jù)點(x,y),可以用下面的規(guī)則來判斷它的類別:
如果 p1(x,y) > p2(x,y),那么類別為1。
如果 p2(x,y) > p1(x,y),那么類別為2。
也就是說,我們會選擇高概率對應的類別。這就是貝葉斯決策理論的核心思想,即選擇具有最高概率的決策。
在本工程中我們可以使用條件概率來進行分類。其條件概率公式如下:
其中粗體w表示這是一個向量,它是有多個值組成。對于類別i表示分類的個數(shù),在本工程中i=0時,c0表示非垃圾郵件。i=1時,c1表示垃圾郵件。w展開為一個個獨立特征,那么就可以將上述概率寫作p(w0,w1,w2..wN|ci)。這里假設所有詞都互相獨立,該假設也稱作條件獨立性假設,它意味著可以使用p(w0|ci)p(w1|ci)p(w2|ci)...p(wN|ci)來計算上述概率,這就極大地簡化了計算的過程,這也是被稱為樸素貝葉斯的原因。在本工程中wj代表第i個單詞特征,而p(wj|ci)則代表了在垃圾郵件(或非垃圾郵件)中,第j個單詞出現(xiàn)的概率;而p(w|ci)則表示在垃圾郵件(或非垃圾郵件)中的全體向量特征(單詞向量特征)出現(xiàn)的概率;而p(ci| w)則表示在全體向量特征(單詞向量特征)下是垃圾郵件(或非垃圾郵件)的概率。本工程項目主要是計算p(ci|w);p(ci)則表示是垃圾郵件(或非垃圾郵件)的概率。
二、系統(tǒng)設計
數(shù)據(jù)的收集及保存
郵件的收集來源于網(wǎng)上,保存在email文件夾中。其中email分兩個子文件,一個為ham文件夾(保存非垃圾郵件),另一個為spam文件夾(保存垃圾郵件)。ham與spam中各保存25各郵件,保存格式為x.txt(x為1到25)。
訓練集和測試集的選取
由于收集的郵件個數(shù)有限,故選取80%的郵件作為訓練集,其方式為隨機選取。剩余20%郵件作為測試集。
特征向量構建
特征向量的構建分為兩種,一個為對訓練集的特征向量構建。一個為測試集的特征向量構建。對于訓練集特征向量只需要分為兩類,因為郵件只分為垃圾郵件和非垃圾郵件。特征向量分為對訓練集中所有垃圾郵件中構成的特征向量(記做w)和訓練集中所有非垃圾郵件構成特征向量(記做w')。對于w的計算實際就是統(tǒng)計所有訓練集中垃圾郵件中的每個單詞的出現(xiàn)情況,出現(xiàn)則次數(shù)加1。其計數(shù)初值為1,按照正常情況應為0,因為用的樸素貝葉斯算法,假設所有詞都互相獨立 ,就有p(w|ci) = p(w0|ci)p(w1|ci)p(w2|ci)...p(wN|ci)。所以當?shù)趇個單詞wi在其特征向量中沒有出現(xiàn),則有p(wi|ci) =0,這就導致了p(w|ci)導致結果的不正確性。所以我們索性將所有單詞默認出現(xiàn)1遍,所以從1開始計數(shù)。對于w'的計算和w的計算方法相同,這里就不在贅述。
對于測試集的特征向量構建就是對每個郵件中單詞出現(xiàn)的次數(shù)進行統(tǒng)計,其單詞表可以來源于50個郵件中的所有單詞。對于每一個郵件中單詞如果出現(xiàn)就加1,其計數(shù)初值為0。每個測試集的郵件都需構建特征向量。其特征向量在python中可用列表表示。
構建貝葉斯分類器
對于分類器的訓練其目的訓練三個參數(shù)為p1Vect(w中每個單詞出現(xiàn)的概率構成的特征向量)、p0Vect(w'中每個單詞出現(xiàn)的概率構成的特征向量)和pAbusive(訓練集中垃圾郵件的概率)。對于p1Vect、p0Vect計算可能會造成下溢出,這 是 由 于 太 多 很 小 的 數(shù) 相 乘 造 成 的 。 當 計 算 乘 積p(w0|ci)p(w1|ci)p(w2|ci)...p(wN|ci)時,由于大部分因子都非常小,所以程序會下溢出或者得到不正確的答案。一種解決辦法是對乘積取自然對數(shù)。在代數(shù)中有l(wèi)n(a*b) = ln(a)+ln(b),于是通過求對數(shù)可以避免下溢出或者浮點數(shù)舍入導致的錯誤。同時,采用自然對數(shù)進行處理不會有任何損失。圖1給出函數(shù)f(x)與ln(f(x))的曲線。檢查這兩條曲線,就會發(fā)現(xiàn)它們在相同區(qū)域內同時增加或者減少,并且在相同點上取到極值。它們的取值雖然不同,但不影響最終結果。
所以p1Vect = log(w/p1Denom),p0Vect = log(w'/p0Denom),其中p1Denom、p0Denom分別為垃圾郵件中單詞的總數(shù)和非垃圾郵件中單詞的總數(shù)。而pAbusive 就等于訓練集中垃圾郵件總數(shù)與訓練集中郵件總數(shù)之比。
測試集驗證與評估
對于判斷是否為垃圾郵件,只需對每個郵件判斷p(c0|w)(不是垃圾郵件的概率)與p(c1|w)(是垃圾郵件的概率)。
q如果p(c0|w) > p(c1|w),那么該郵件為非垃圾郵件。
q如果 p(c0|w) < p(c1|w),那么該郵件為垃圾郵件。
然而p(ci|w)(i=0或1)的計算則依賴于p(w|ci)與p(ci)的計算,p(w)無需計算。所以最終結果依賴于pi = p(w|ci)·p(ci)。由于p(w|ci)很小,可能向下溢出。所以我們取以10為底的對數(shù)得log(pi) = log(p(w|ci))+log(p(ci)),所以可得以下結論:
q如果log(p0) > log(p1),那么該郵件為非垃圾郵件。
q如果log(p0) < log(p1),那么該郵件為垃圾郵件。
其中p(w|ci)為在垃圾郵件(或非垃圾郵件)中的全體向量特征(單詞向量特征)出現(xiàn)的概率,p(ci)為訓練集中垃圾郵件(或非垃圾郵件)的概率。
三、系統(tǒng)演示與實驗結果分析對比
由訓練集(40個)和測試集(個)的樣本數(shù)目比較小,所以測試的分類結果正確性為90%-100%之間,如下圖所示:
本工程只是對郵件進行二分類,貝葉斯算法也可以處理多分類問題,如新聞的分類,如分成軍事、體育、科技等等。當然本工程只是對英文的垃圾郵件分類,但也可以對中文的垃圾郵件分類(可用python中的jieba的庫模塊進行對中文分詞)。
四、代碼實現(xiàn)
#coding=UTF-8 import random from numpy import * #解析英文文本,并返回列表 def textParse(bigString): #將單詞以空格劃分 listOfTokens = bigString.split() #去除單詞長度小于2的無用單詞 return [tok.lower() for tok in listOfTokens if len(tok)>2] #去列表中重復元素,并以列表形式返回 def createVocaList(dataSet): vocabSet = set({}) #去重復元素,取并集 for document in dataSet: vocabSet = vocabSet | set(document) return list(vocabSet) #統(tǒng)計每一文檔(或郵件)在單詞表中出現(xiàn)的次數(shù),并以列表形式返回 def setOfWordsToVec(vocabList,inputSet): #創(chuàng)建0向量,其長度為單詞量的總數(shù) returnVec = [0]*len(vocabList) #統(tǒng)計相應的詞匯出現(xiàn)的數(shù)量 for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] += 1 return returnVec #樸素貝葉斯分類器訓練函數(shù) def trainNB0(trainMatrix,trainCategory): #獲取訓練文檔數(shù) numTrainDocs = len(trainMatrix) #獲取每一行詞匯的數(shù)量 numWords = len(trainMatrix[0]) #侮辱性概率(計算p(Ci)),計算垃圾郵件的比率 pAbusive = sum(trainCategory)/float(numTrainDocs) #統(tǒng)計非垃圾郵件中各單詞在詞數(shù)列表中出現(xiàn)的總數(shù)(向量形式) p0Num = ones(numWords) #統(tǒng)計垃圾郵件中各單詞在詞數(shù)列表中出現(xiàn)的總數(shù)(向量形式) p1Num = ones(numWords) #統(tǒng)計非垃圾郵件總單詞的總數(shù)(數(shù)值形式) p0Denom = 2.0 #統(tǒng)計垃圾郵件總單詞的總數(shù)(數(shù)值形式) p1Denom = 2.0 for i in range(numTrainDocs): #如果是垃圾郵件 if trainCategory[i] == 1: p1Num += trainMatrix[i] p1Denom +=sum(trainMatrix[i]) #如果是非垃圾郵件 else: p0Num += trainMatrix[i] p0Denom +=sum(trainMatrix[i]) #計算每個單詞在垃圾郵件出現(xiàn)的概率(向量形式) p1Vect = log(p1Num/p1Denom) #計算每個單詞在非垃圾郵件出現(xiàn)的概率(向量形式) p0Vect = log(p0Num/p0Denom) return p0Vect,p1Vect,pAbusive #樸素貝葉斯分類函數(shù) def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): p1 = sum(vec2Classify*p1Vec)+log(pClass1) p0 = sum(vec2Classify*p0Vec)+log(1.0 - pClass1) if p1 > p0: return 1 else : return 0 #test def spamtest(): #導入并解析文本文件 docList =[];classList=[];fullText = [] for i in range(1,26): #讀取第i篇垃圾文件,并以列表形式返回 wordList = textParse(open('email/spam/{0}.txt'.format(i)).read()) #轉化成二維列表 docList.append(wordList) #一維列表進行追加 fullText.extend(wordList) #標記文檔為垃圾文檔 classList.append(1) #讀取第i篇非垃圾文件,并以列表形式返回 wordList = textParse(open('email/ham/{0}.txt'.format(i)).read()) #轉化成二維列表 docList.append(wordList) #一維列表進行追加 fullText.extend(wordList) #標記文檔為非垃圾文檔 classList.append(0) #去除重復的單詞元素 vocabList = createVocaList(docList) #訓練集,選40篇doc trainingSet = [x for x in range(50)] #測試集,選10篇doc testSet = [] #選出10篇doc作測試集 for i in range(10): randIndex = int(random.uniform(0,len(trainingSet))) testSet.append(trainingSet[randIndex]) del trainingSet[randIndex] trainMat = [];trainClasses=[] #選出40篇doc作訓練集 for docIndex in trainingSet: trainMat.append(setOfWordsToVec(vocabList, docList[docIndex])) trainClasses.append(classList[docIndex]) p0V,p1V,pSpam = trainNB0(array(trainMat), array(trainClasses)) #對測試集分類 errorCount = 0 for docIndex in testSet: wordVector = setOfWordsToVec(vocabList,docList[docIndex]) if classifyNB(array(wordVector), p0V, p1V, pSpam)!=classList[docIndex]: errorCount+=1 print("錯誤率為:{0}".format(float(errorCount)/len(testSet))) spamtest()
以上是“python怎么實現(xiàn)基于樸素貝葉斯的垃圾分類算法”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。