贝叶斯公式:p(B|C)=p(C|B)*P(B)/P(C)
用伯努利算法,就是适用于0或者1,也就是给出是或者不是,B就是“是”或者“不是”,C是个集合,就代表各种原因。
所以P(B|c1c2c3...)=p(c1*c2*c3..|B)*p(B)/p(c1c2c3.....)的概率。
好了
下面开始训练。
给出样本
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
这6个样本里吧,肯定有重复的单词,找个函数,把不重复的记录到列表中,肯定用set()函数
def createVocabList(dataSet): vocabSet = set([]) #create empty set for document in dataSet: vocabSet = vocabSet | set(document) #union of the two sets,这里用了一个并集 return list(vocabSet)
上面这个函数,返回了有多少个不重复的单词。上面运行结果有32个不重复的,下面这个函数,结果是创建了【0.0.1.0.0.0.0.........】,这里比较难理解的是,你传入一行
['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],然后再returnVec中都是【0.0.0.0.....】,然后遍历找到你传入的input里的所有单词的位置,并且把0变成1
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
下面这个函数就是开始算P(c1c2c3....|B),B为是或者不是
def trainNB0(trainMatrix,trainCategory):#传入处理过的数据,传入对应的0,1值 numTrainDocs = len(trainMatrix)#得到6 numWords = len(trainMatrix[0])#这一行有32个, pAbusive = sum(trainCategory)/float(numTrainDocs)#这个是不符合的1所有的相加/总数,就是3/6tr p0Num = ones(numWords); p1Num = ones(numWords) #change to ones() (创建默认都为1,因为语法问题,如果多个小数相乘,最后取出约等于0) p0Denom = 2.0; p1Denom = 2.0 #change to 2.0 for i in range(numTrainDocs):#遍历6行,如果这个是1(不是),则把它归到p1Num,然后把它们相量相加,如果为0,则归为p0num,然后相量相加,在这里最终p0num为1,3,5的trainMatrix if trainCategory[i] == 1:#对应的相加 p1Num += trainMatrix[i] p1Denom += sum(trainMatrix[i])(为所有在“不是”里出现的个数的总和) else: p0Num += trainMatrix[i] p0Denom += sum(trainMatrix[i])(为所有在“是”里出现的个数的总和) p1Vect = log(p1Num/p1Denom) (p1为各单词在侮辱(“不是”)的概率,这还是【32】的一行的数字) #change to log() p0Vect = log(p0Num/p0Denom) (同理) #change to log() return p0Vect,p1Vect,pAbusive
好了,接下来就该正式统计概率了,也就是贝叶斯公式,你传入一个要测试的值,然后传入你训练出来的 侮辱性(“不是”)所对应的概率,非侮辱(“是”)所对应的概率,和训练得出的侮辱总P(B)
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
下面是总函数流程,首先划分数据,得到词汇表,然后得到词汇表在0和1所对应的概率,然后输入测试的数据。
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)
数据变化的流程图
本文仅作作者自己的笔记....有问题欢迎指导。。。