朴素貝葉斯算法及實現


1、朴素貝葉斯算法介紹

一個待分類項x=(a,b,c...),判斷x屬於y1,y2,y3...類別中的哪一類。

貝葉斯公式:

算法定義如下:

(1)、設x={a1, a2, a3, ...}為一個待分類項,而a1, a2, a3...分別為x的特征

(2)、有類別集合C={y1, y2,  y3,  ..}

(3)、計算p(y1|x), p(y2|x), p(y3|x), ....

(4)、如果p(y(k)|x)=max{p(y1|x), p(y2|x), p(y3|x), ....},則x屬於p(y(k)|x)

 

計算:

(1)、找到一個已知分類的待分類項集合,也就是訓練集。

(2)、統計得到在各個類別下各個特征屬性的條件概率估計。即:

p(a1|y1).................... p(am|y1)

.

.

.

p(a1|yn).................... p(an|yn)

(3)、如果各個特征屬性是條件獨立的,則根據貝葉斯公式:

 

 2、病人分類的例子

讓我從一個例子開始講起,你會看到貝葉斯分類器很好懂,一點都不難。

某個醫院早上收了六個門診病人,如下表。

  症狀  職業   疾病

  打噴嚏 護士   感冒 
  打噴嚏 農夫   過敏 
  頭痛  建築工人 腦震盪 
  頭痛  建築工人 感冒 
  打噴嚏 教師   感冒 
  頭痛  教師   腦震盪

現在又來了第七個病人,是一個打噴嚏的建築工人。請問他患上感冒的概率有多大?

根據貝葉斯定理:

 P(A|B) = P(B|A) P(A) / P(B)

可得

   P(感冒|打噴嚏x建築工人) 
    = P(打噴嚏x建築工人|感冒) x P(感冒) 
    / P(打噴嚏x建築工人)

假定"打噴嚏"和"建築工人"這兩個特征是獨立的,因此,上面的等式就變成了

   P(感冒|打噴嚏x建築工人) 
    = P(打噴嚏|感冒) x P(建築工人|感冒) x P(感冒) 
    / P(打噴嚏) x P(建築工人)

這是可以計算的。

  P(感冒|打噴嚏x建築工人) 
    = 0.66 x 0.33 x 0.5 / 0.5 x 0.33 
    = 0.66

因此,這個打噴嚏的建築工人,有66%的概率是得了感冒。同理,可以計算這個病人患上過敏或腦震盪的概率。比較這幾個概率,就可以知道他最可能得什么病。

這就是貝葉斯分類器的基本方法:在統計資料的基礎上,依據某些特征,計算各個類別的概率,從而實現分類

 

3、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
    
def bagOfWords2VecMN(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec

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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM