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)