利用樸素貝葉斯(Navie Bayes)進行垃圾郵件分類
貝葉斯公式描寫敘述的是一組條件概率之間相互轉化的關系。
在機器學習中。貝葉斯公式能夠應用在分類問題上。
這篇文章是基於自己的學習所整理。並利用一個垃圾郵件分類的樣例來加深對於理論的理解。
這裏我們來解釋一下樸素這個詞的含義:
1)各個特征是相互獨立的,各個特征出現與其出現的順序無關;
2)各個特征地位同等重要;
以上都是比較強的如果
以下是樸素貝葉斯分類的流程:
這樣我們就分別求出了這些特征各個類別下的條件概率,非常直觀的,對於各個特征的聯合概率分布就是各個條件概率進行相乘。如上式。可是這樣會出現下面幾個問題:
1)若某一個詞未出如今字典中,那麽其條件概率就會為0。那麽總體的聯合概率也就為0。為了避免這樣的情況的
出現,這裏會引入 Laplace smoothing的操作:假定輸入樣本中各個特征出現的次數至少為1,這樣在求一個特征出
現的概率時對於分母。要加上其總的類別m;能夠表述為例如以下公式,
p(w|h)=(實際出現的次數+1)/(總的特征出現次數+m)
2)還有一個問題是,若一個樣本中特征個數非常多,那 麽可能會出現這種情況,單個特征出現的概率非常少,那麽聯合
概率相乘時。終於的值會很小。在計算機中可能出現下溢。為了避免這樣的情況出現,能夠對聯合概率取對數
log(a*b)=log(a)+log(b)
上式能夠轉換為:
以上都是訓練過程中會常常遇到的問題。
經過訓練後,就能夠得到非常多組這種公式。那麽對於一封新的郵件過來了
怎麽去判定其是否為垃圾郵件呢?
這裏就會涉及到怎麽樣將 單詞這種特征轉化成計算機能夠方便處理的數字,非常直觀的就是建立一個已知垃圾郵件中常常出現的單詞的字典(向量)。對於新郵件。就能夠將其轉換到一個與字典相同大小的向量,出現的單詞在對應的索引處標為‘1’,否則標 ‘0’。
下一步就是將得到的這個向量分別與訓練得到的對數概率進行相乘了。
以下是python代碼,來自機器學習實戰這本書。
from numpy import * 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 is abusive, 0 not return postingList,classVec def createVocabList(dataSet): vocabSet = set([]) #create empty set for document in dataSet: vocabSet = vocabSet | set(document) #union of the two sets return list(vocabSet) def setOfWords2Vec(vocabList, inputSet): returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] = 1 else: print "the word: %s is not in my Vocabulary!" % word return returnVec def trainNB0(trainMatrix,trainCategory): numTrainDocs = len(trainMatrix) numWords = len(trainMatrix[0]) pAbusive = sum(trainCategory)/float(numTrainDocs) p0Num = ones(numWords); p1Num = ones(numWords) #change to ones() p0Denom = 2.0; p1Denom = 2.0 #change to 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]) p1Vect = log(p1Num/p1Denom) #change to log() p0Vect = log(p0Num/p0Denom) #change to log() return p0Vect,p1Vect,pAbusive def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1) if p1 > p0: return 1 else: return 0
很多其它內容能夠參考下面博客:
樸素貝葉斯分類器的應用:
貝葉斯判斷及基互聯網應用:過濾垃圾郵件
利用樸素貝葉斯(Navie Bayes)進行垃圾郵件分類