日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

朴素贝叶斯(naive bayes)

發布時間:2025/3/19 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 朴素贝叶斯(naive bayes) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

樸素貝葉斯(naive bayes)

標簽: Python 機器學習

主要參考資料:《機器學習實戰》《統計學習方法》


1.樸素貝葉斯分類原理

樸素貝葉斯法是基于貝葉斯定理特征條件獨立假設(稱為樸素的原因)的分類方法。先看看維基百科中貝葉斯定理的描寫敘述:

貝葉斯定理(維基百科)
通常,事件A在事件B(發生)的條件下的概率。與事件B在事件A的條件下的概率是不一樣的。然而,這兩者是有確定的關系,貝葉斯定理就是這樣的關系的陳述。


公式描寫敘述例如以下:

P(A|B)=P(B|A)P(A)P(B)
當中P(A|B)是在B發生的情況下A發生的可能性。

在機器學習中,經常常使用事件A表示屬于某個類別,事件B表示特征條件的集合。下面圖作為樣例解說:

圖中共同擁有兩類點。記為c1c2。p(ci|x,y)表示點(x,y)為類ci的概率。那么依據貝葉斯公式,能夠進行例如以下分類:

  • 假設P(c1|x,y)>P(c2|x,y)。則斷定該點屬于c1
  • 假設P(c1|x,y)<P(c2|x,y)。則斷定該點屬于c2

假設用P(x,y|ci)表示類ci中點(x,y)的概率(分布)。則:

P(ci|x,y)=P(x,y|ci)P(ci)P(x,y)
又由于假設了特征條件獨立。即xy之間沒有不論什么的關系。則:
P(ci|x,y)=P(x|ci)P(y|ci)P(ci)P(x,y)
分母同樣,僅僅須要比較分子就可以。樸素貝葉斯算法訓練的目的就是得到訓練集中P(x|ci)P(y|ci)P(ci),即不同獨立特征的條件概率。

2.樸素貝葉斯實現

2.1準備數據

由于是簡單的演示樣例,直接創建訓練集和類標簽向量:

# 訓練集:留言板的中的留言 def create_data_set(): 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

當前數據集中的數據是單詞,我們要依據單詞出現的頻率預計出條件概率。就必須知道每一個單詞出現的頻數。而統計單詞頻數,首先得創建單詞表,即全部單詞僅僅出現一次的列表(集合):

#創建單詞表 def create_vocablist(dataSet): vocabSet = set([]) #create empty setfor document in dataSet:vocabSet = vocabSet | set(document) #取并集return list(vocabSet)

有了單詞表就能夠將語句轉化為頻率矢量,首先將單詞表全部單詞的頻率初始化為0。然后遍歷每一條語句。將出現的單詞頻率置為1(0表示未出現該單詞,1表示出現該單詞):

#將輸入語句轉化為單詞頻率向量,表示單詞表中的哪些單詞出現過 def setOfWords2Vec(vocabList, inputSet):returnVec = [0]*len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] = 1else: print "the word: %s is not in my Vocabulary!" % wordreturn returnVec

利用上面生成的數據集生成一個單詞表,結果例如以下:

將語句”I buying cute dog”轉化為向量例如以下:

2.2訓練算法

先看看訓練的目標參數:P(w1|ci),P(w2|ci),...,P(wm|ci)P(ci),當中wi表示某一個單詞,由于一條語句是由若干單詞組成。且我們假設每一個單詞出現的事件是獨立的。故類ci有語句w的概率P(w??|ci)=P(w1|ci),P(w2|ci),...,P(wm|ci)。

訓練函數傳入的參數有兩個。各自是語句集合轉化的單詞表向量集合和類標簽向量。首先依據類標簽列表能夠計算出侮辱性語句和非侮辱性語句的頻率。然后再計算各個特征的條件概率。

計算特征的條件概率時使用了numpy中的矢量運算。極大的簡化了程序的編寫。先定義2個空的單詞表矢量,用來統計侮辱性單詞和非侮辱性單詞的頻數,再定義2個浮點型變量。用來統計侮辱性單詞和非侮辱性單詞的總數。遍歷單詞表向量集合。依據每一個向量的類別,統計侮辱性和非侮辱性單詞的頻數與總數。最后,將頻數除以總數,就能夠得到侮辱性或非侮辱性條件下某單詞的出現的概率。

#樸素貝葉斯訓練函數,輸入為全部文檔的單詞頻率向量集合。類標簽向量 def trainNB(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix) #文檔數量numWords = len(trainMatrix[0]) #單詞表長度pAbusive = sum(trainCategory)/float(numTrainDocs) #侮辱性詞語的頻率p0Num = zeros(numWords); p1Num = zeros(numWords) #分子初始化為0p0Denom = 0.0; p1Denom = 0.0 #分母初始化為0for i in range(numTrainDocs):if trainCategory[i] == 1: #假設是侮辱性語句p1Num += trainMatrix[i] #矢量相加,將侮辱性語句中出現的詞語頻率全部加1p1Denom += sum(trainMatrix[i]) #屈辱性詞語的總量也添加else:p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])p1Vect = p1Num/p1Denom #對每一個元素做除法p0Vect = p0Num/p0Denomreturn p0Vect,p1Vect,pAbusive #返回全部詞語非侮辱性詞語中的頻率。全部詞語在侮辱性詞語中的頻率。侮辱性語句的頻率

可是這段程序有兩個問題,問題一為可能發生下溢出,問題二為某語句的某個單詞在侮辱性或非侮辱性集合中的頻率為0,這會導致連乘的積為0.

首先解決這個問題一:
頻率都是非常小的小數,這些小數連乘的結果終于也是非常小非常小的小數,在計算機中會發生下溢出或者為0,總之都不是正確的結果。

較為常見的解決方法是使用對數。將連乘變為連加。對應的程序改動例如以下:

p1Vect = log(p1Num/p1Denom) #變為對數,防止下溢出;對每一個元素做除法 p0Vect = log(p0Num/p0Denom)

然后解決這個問題二:
能夠通過分子全部初始化為1,分母初始化為2解決該問題,這樣的方法在統計學中叫做貝葉斯預計
條件概率P(wj|ci)的極大似然預計為:

P(wj|ci)=I(wj,ci)I(ci)
我們原先就是依照上面的公式計算P(wj|ci),可是該公式可能出現所要預計的概率值為0的情況,所以給分子分母添加一項,稱為條件概率的貝葉斯預計,詳細例如以下:
P(wj|ci)=I(wj,ci)+λI(ci)+Sjλ
當中λ>0Sj表示wj能夠取得不同值的個數。當λ=1時,稱為拉普拉斯平滑

在我們所討論的問題中。wj表示某個單詞是否出現,僅僅有0和1兩個值。故Sj=2。所以初始化時分子為1。分母為2,再依據遍歷結果添加分子和分母的值。對應的程序改動例如以下:

p0Num = ones(numWords); p1Num = ones(numWords) #分子初始化為1 p0Denom = 2.0; p1Denom = 2.0 #分母初始化為2

2.3測試算法

依據下面準則編寫分類函數:

  • 假設P(c0|x,y)>P(c1|x,y),則斷定為非侮辱性語句
  • 假設P(c0|x,y)<P(c1|x,y),則斷定為侮辱性語句
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1) #矢量相乘求出概率。log相加p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else: return 0

然后編寫測試函數,進行測試,須要注意的是python中的列表不提供矢量運算,要想進行矢量運算,就要將列表轉化為numpy中的array或者mat。

def testingNB():listOPosts,listClasses = create_data_set()myVocabList = create_vocablist(listOPosts)trainMat=[]for postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))p0V,p1V,pAb = trainNB(array(trainMat),array(listClasses))testEntry = ['love', 'my', 'dalmation']thisDoc = array(setOfWords2Vec(myVocabList, testEntry))print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)testEntry = ['stupid', 'garbage']thisDoc = array(setOfWords2Vec(myVocabList, testEntry))print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)

執行結果例如以下:

3.總結

  • 源代碼在我的GitHub中,MachineLearningAction倉庫里面有常見的機器學習算法處理常見數據集的各種實例,歡迎訪問
  • 樸素貝葉斯算法核心就兩個:
    • 貝葉斯定理
    • 樸素:假設各個特征之間是獨立的
  • 僅僅要牢記樸素貝葉斯的核心以及公式,那么編敲代碼就比較easy
  • 樸素貝葉斯經常常使用于文本分類。然而該方法對于英文等語言非常好用。對中文就不是非常好,由于中文是字組成詞。對于長句子要進行“分詞”操作,比方“黃金”和“金黃”的字全然一樣,可是意思截然不同
  • 樸素貝葉斯有非常多的改進方法,比方說用詞袋模型取代詞集模型,移除停用詞

總結

以上是生活随笔為你收集整理的朴素贝叶斯(naive bayes)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。