1. 程式人生 > >分類演算法-----樸素貝葉斯原理和python實現

分類演算法-----樸素貝葉斯原理和python實現

本文主要介紹一下內容:1貝葉斯,2 樸素貝葉斯的推導,3 最大似然估計的推到過程,4樸素貝葉斯的計算步驟 ,5 貝葉斯估計

1 貝葉斯

 假設有兩類資料p1(x,y)表示(x,y)屬於類別1,用p2(x,y)表示(x,y)屬於類別2,那麼對於一個新的資料集(x,y),可以根據一下規則來判斷他的類別

1.如果p1(x,y)>p2(x,y),則(x,y)屬於類別1

2.如果p2(x,y)>p1(x,y),則(x,y)屬於類別2

也就是說,我們會選擇具有最高概率的決策,這就是貝葉斯決策理論的核心思想通常,事件A在事件B(發生)的條件下的概率,與事件B在事件A的條件下的概率是不一樣的;然而,這兩者是有確定的關係,貝葉斯法則就是這種關係的陳述。作為一個規範的原理,貝葉斯法則對於所有概率的解釋是有效的;然而,頻率主義者和貝葉斯主義者對於在應用中概率如何被賦值有著不同的看法:頻率主義者根據隨機事件發生的頻率,或者總體樣本里面的個數來賦值概率;貝葉斯主義者要根據未知的命題來賦值概率。一個結果就是,貝葉斯主義者有更多的機會使用貝葉斯法則。

2樸素貝葉斯

樸素貝葉斯是基於貝葉斯定理與特徵條件獨立假設的分類

3 最大似然估計推到

4 樸素貝葉斯演算法計算步驟

5 貝葉斯估計

用極大似然估計可能會出現所要估計的概率值為0的情況,這時會影響到後驗概率的影響結果,使分類產生誤差解決這一問題的方法是採用貝葉斯估計

等價於在隨機變數各個取值的頻數上賦予一個正數,值為0時為極大似然估計,值為1是為拉普拉斯平滑至此樸素貝葉斯的基本原理均介紹完成,後續會增加樸素貝葉斯的python實現

6 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)#生成一個包含所有單詞的列表
    
#數輸引數是文件,輸出引數是變數,vocabSet包含所有不重複的詞,把句子轉成詞向量,,詞集模型
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0]*len(vocabList)#生成一個列表長度為單詞長度,每個元素均為0
    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  #生成詞集向量

#原始的計算需要多項相乘,這樣如果其中一項為0 ,則影響整體,因此初始化資料分子為1分母為2
#令一種情況為下溢位問題,即一些很小的資料相乘四捨五入會得到0結果,因此一種處理方法為取對數
#def trainNB0(postingList,trainCategory):
#    trainMatrix=[]
#    for p in postingList:
#        trainMatrix.append(setOfWords2Vec(myVocablist, p))
#    print trainMatrix[2]
#    numTrainDocs = len(trainMatrix)#取行6
#    numWords = len(trainMatrix[0])#取列32
#    pAbusive = sum(trainCategory)/float(numTrainDocs)#出現侮辱性文件的概率,包含侮辱性句子/所有句子
#    p0Num = zeros(numWords)#生成一個包含單詞個數的列表,值均為0
#    p1Num = zeros(numWords)  #生成一個包含單詞個數的列表,值均為0    #change to ones() 
#    p0Denom = 0.0
#    p1Denom = 0.0                      #change to 2.0
#    for i in range(numTrainDocs):
#        if trainCategory[i] == 1:#類別為1
#            p1Num += trainMatrix[i]#各變數均增加1
#            p1Denom += sum(trainMatrix[i])#每次變數中發生的次數
#        else:
#            p0Num += trainMatrix[i]
#            p0Denom += sum(trainMatrix[i])
#    p1Vect = p1Num/p1Denom        #change to log()
#    p0Vect = p0Num/p0Denom         #change to log()
#    return p0Vect,p1Vect,pAbusive
#    


#詞袋模型,每個詞可以多次出現   
def bagOfWords2VecMN(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    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  #避免其中一項為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
    
#計算屬於類別1和類別0的概率,把資料進行分類
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
#測試分類結果
def testingNB():
    listOPosts,listClasses = loadDataSet()#載入資料集
    myVocabList = createVocabList(listOPosts)#生成一個包含所有單詞的列表   
    trainMat=[]
    for postinDoc in listOPosts:#遍歷資料集
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
        
    p0V,p1V,pAb = trainNB0(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)  #測試結果

#文字解析,把大寫轉小寫,且去掉長度小於2的字元
def textParse(bigString):    #input is big string, #output is word list
    import re
    listOfTokens = re.split(r'\W*', bigString)
    return [tok.lower() for tok in listOfTokens if len(tok) > 2] 


####
def spamTest():
    docList=[]
    classList = []
    fullText =[]
    for i in range(1,26):
        wordList = textParse(open('email/spam/%d.txt' % i).read())#垃圾郵件
        docList.append(wordList)#詞向量
        fullText.extend(wordList)#文件向量
        classList.append(1)
        wordList = textParse(open('email/ham/%d.txt' % i).read())#非垃圾郵件
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
        
    vocabList = createVocabList(docList)#詞彙表
    trainingSet = range(50)#訓練集
    testSet=[]           #測試集
    for i in range(10):
        randIndex = int(random.uniform(0,len(trainingSet)))#生成隨機數
        testSet.append(trainingSet[randIndex])
        del(trainingSet[randIndex]) #刪除索引
        
    trainMat=[]
    trainClasses = []
    for docIndex in trainingSet:#train the classifier (get probs) trainNB0
        trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
        trainClasses.append(classList[docIndex])
        
    p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))
    errorCount = 0
    for docIndex in testSet:        #classify the remaining items
        wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
        if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
            errorCount += 1
            print "classification error",docList[docIndex]
    print 'the error rate is: ',float(errorCount)/len(testSet)
    #return vocabList,fullText
    
if  __name__=='__main__':
      spamTest()

相關推薦

分類演算法-----樸素原理python實現

本文主要介紹一下內容:1貝葉斯,2 樸素貝葉斯的推導,3 最大似然估計的推到過程,4樸素貝葉斯的計算步驟 ,5 貝葉斯估計 1 貝葉斯  假設有兩類資料p1(x,y)表示(x,y)屬於類別1,用p2(x,y)表示(x,y)屬於類別2,那麼對於一個新的資料集(x,y),可以

樸素原理python實現

一、貝葉斯演算法引入       樸素貝葉斯演算法是基於貝葉斯定理和特徵條件獨立假設的分類法,是一種基於概率分佈的分類演算法。       貝葉斯分類演算法,通俗的來講,在給定資料集的前提下,對於一個

大資料分類演算法——樸素演算法

七、零頻問題 注意table 2中有一個數據為0,這意味著在outlook為overcast的情況下,不打球和概率為0,即只要為overcast就一定打球,這違背了樸素貝葉斯的基本假設:輸出依賴於所有的屬性。 資料平滑的方法很多,最簡單最古老的是拉普拉斯估計(Laplace estimator)--即為t

文字分類演算法--樸素

貝葉斯定理 貝葉斯定理用公式表示: p(Y|X)=P(X|Y)P(Y)p(X) 其中,p(Y)是先驗概率,P(Y|X)是後驗概率,也就是要求的概率。 樸素貝葉斯演算法原理 樸素貝葉斯分類演算法是一種生成模型。訓練的過程是學習聯合概率分佈p(x,

常用分類問題的演算法-樸素分類器(Naive Bayes Classifiers)

樸素貝葉斯分類器是分類演算法集合中基於貝葉斯理論的一種演算法。它不是單一存在的,而是一個演算法家族,在這個演算法家族中它們都有共同的規則。例如每個被分類的特徵對與其他的特徵對都是相互獨立的。 樸素貝葉斯分類器的核心思想是: 1、將所有特徵的取值看成已經發生的

人工智慧演算法樸素分類

文/騰訊soso林世飛     以下是個人學習貝葉斯分類器—文字分類的學習筆記,和大家一起學習交流。 準備工作     監督學習型分類器特點 ,能夠從一個不確定度狀態開始,通過提供 正確和錯誤的樣本 ,不斷來確定哪些特徵(特徵由特徵提取函式,從樣本中提取 )對於分類更重

Scikit-Learn機器學習之監督學習模型案例集-新聞/郵件文字內容分類樸素演算法模型)

最簡單的辦法 下載'20news-bydate.pkz', 放到C:\\Users\[Current user]\scikit_learn_data 下邊就行. 2.1. 手動下載 檔案     存放到scikit_learn_data/20new

樸素(二)實現NBCorpus分類(附程式碼資料)

公式:(P(x)為常數,可忽略不考慮)平滑:Nyk是類別為yk的樣本個數,n是特徵的維數,Nyk,xi是類別為yk的樣本中,第i維特徵的值是xi的樣本個數,α是平滑值。在對NBCorpus詞分類時,帶入上面的公式可得:某詞屬於某類別的概率 = (該類別該詞的個數  + 1/

資料探勘十大演算法(九):樸素原理、例項與Python實現

一、條件概率的定義與貝葉斯公式 二、樸素貝葉斯分類演算法 樸素貝葉斯是一種有監督的分類演算法,可以進行二分類,或者多分類。一個數據集例項如下圖所示: 現在有一個新的樣本, X = (年齡:<=30, 收入:中, 是否學生:是, 信譽:中),目標是利用樸素貝

基於概率論的分類方法:樸素算法實踐學習

取出 對數 pri 場景 比例 pro ngs 什麽 inf 關於本文說明,本人原博客地址位於http://blog.csdn.net/qq_37608890,本文來自筆者於2017年12月12日 13:03:46所撰寫內容(http://blog.csdn.n

分類樸素分類方法

       樸素貝葉斯分類方法的特點是基於概率方法實現分類,這在諸多的分類方法中比較少見。貝葉斯方法都有所耳聞,之所以稱為“樸素”貝葉斯方法,是因為在分類時,假定了“各變數間相互獨立”的條件,這個條件算是比較強的了,大大簡化了分類時的計算,但同時也丟失了一些

斯坦福大學-自然語言處理入門 筆記 第六課 文字分類樸素

一、文字分類任務概述 1、應用領域 歸類 垃圾郵件識別 作者識別 性別/年齡識別 等等 2、定義 輸入:一個文件d,一系列固定的型別C={c1,c2,…,cj} 輸出:預測類別c ∈ C 3、分類方法

樸素原理及sklearn呼叫

一、原理 與其他大多數的分類演算法不同,如:決策樹、KNN、邏輯迴歸等,它們都是判別方法,直接學習出類別y和特徵x之間的關係。樸素貝葉斯屬於生成方法,它的理論基礎是貝葉斯公式: P

樸素原理

(1)全概率公式   如果事件組 B 1 ,

01 演算法 - 樸素

引子: 1、孩子的性別問題 已知一對夫妻生了2個孩子,其中一個是女孩,那麼另一個也是女孩的概率的多少?普遍大家會覺得生男生女都一樣,所以另一個也是女孩的概率是1/2。而另一部分稍微聰明一點的人認為:根據排列組合,兩個孩子生男生女一共有4種可能性,所以都是女生的概率是1/4。然而恭喜你們,完美得避開了正確答

機器學習演算法 樸素

一切盡在程式碼中 python自己下載資料集 是真的慢… from sklearn.datasets import fetch_20newsgroups from sklearn.model_selection import train_test_split from sklearn

機器學習----分類器(決策論極大似然估計)

貝葉斯決策論 貝葉斯決策論(Bayesian decision theory)是概率框架下實施決策的基本方法。在所有相關概率都已知的理想情況下,貝葉斯決策論考慮如何基於這些概率和誤判斷來選擇最優的類別標記。 假設有N種可能的類別標記,即Y={c1,c2,.

機器學習實戰 樸素原理及程式碼

#---------------------------從文字中構建詞條向量------------------------- #1 要從文字中獲取特徵,需要先拆分文字,這裡特徵是指來自文字的詞條,每個詞 #條是字元的任意組合。詞條可以理解為單詞,當然也可以是非單詞詞條,比如URL #IP地址或者其他任意字

【Kaggle筆記】新聞文字分類樸素

樸素貝葉斯模型適用場景 海量文字分類任務 假設資料特徵與目標之間存線上性關係 資料集 sklearn 中的 fetch_20newsgroups 程式碼 # -*- c

利用spark做文字分類樸素模型)

樸素貝葉斯模型 樸素貝葉斯法是基於貝葉斯定理與特徵條件獨立假設的分類方法。對於給定的訓練資料集,首先基於特徵條件獨立假設學習輸入/輸出的聯合概率分佈;然後基於此模型,對給定的輸入x,利用貝葉斯定理求出後驗概率最大的輸出y。至於樸素貝葉斯模型的原理部分,這裡就不