朴素贝叶斯分类器

来源:互联网 发布:京东云服务器绑定域名 编辑:程序博客网 时间:2024/05/16 18:33

kNN和决策树能给一条数据做出明确的分类,但是有时候不能明确给出,那我们就需要给出每个分类的概率估计值。

现在,假设我们有一条w向量,那么要判断它属于哪个分类,需要计算在w条件下,它属于ci分类的概率。只要把所有分类的概率计算出来了,按照贝叶斯决策伦的核心思想,概率最高的那个分类,就是这个w向量,也就是这段文本所属于的分类。那么,怎么计算分类的概率呢?用到的公式:
这里写图片描述
下面我们来讨论如何计算p(ci)和p(w|ci)

现假设有文档矩阵trainMatrix和以及其分类trainCategory。

trainMatrix里储存的是每段文档的词向量w,trainCategory存的是每一段文档的分类,这里只有两类,1表示是侮辱性文字,0表示正常言论。那么p(ci)计算非常简单,只要统计出一共有多少个文档,根据分类计算出属于侮辱性的有多少个,非侮辱性的有多少个,再分别用他们除以总文档数就是p(ci)的概率。
接下来计算p(w|ci),表示已知是ci分类的情况下,w出现的概率。w表示了哪些单词出现了,哪些单词没有出现。每个单词的出现与否都是特征值。朴素贝叶斯假设特征之间都是独立的,因此p(w|ci)的计算可以转化为p(w0|ci)*p(w0|ci)……*p(wn|ci)。p(w0|ci)表示在已知ci的情况下,第0个单词出现的概率。那么问题转化为求p(wj|ci),这也很好计算,只要统计出ci一共有多少个单词,并统计出属于ci的文档里第j个单词出现的次数,再用这个次数除以ci的单词总数就是p(wj|ci)的概率了。
算法步骤:
1. 根据训练集样本创建词汇表
2. 将训练集或者测试集转换成文档向量,表示词汇表中的单词在该文档中出现的次数
3. 根据转换后的文档向量集合进行朴素贝叶斯分类器训练,得到每个分类下的单词概率向量和属于每个分类的概率
4. 使用建立好的朴素贝叶斯分类器对测试样本分类
需要注意的是:
由于我们只需要比较不同分类的大小,因此p(w)是不需要计算的。
代码实现:

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 侮辱性文字 , 0 代表正常言论    return postingList,classVecdef createVocabList(dataSet):#创建词汇表    vocabSet = set([])    for document in dataSet:        vocabSet = vocabSet | set(document) #创建并集    return list(vocabSet)def bagOfWord2VecMN(vocabList,inputSet):#根据词汇表,讲句子转化为向量    returnVec = [0]*len(vocabList)    for word in inputSet:        if word in vocabList:            returnVec[vocabList.index(word)] += 1    return returnVecdef trainNB0(trainMatrix,trainCategory):###输入的文档信息和标签    numTrainDocs = len(trainMatrix)    numWords = len(trainMatrix[0])    pAbusive = sum(trainCategory)/float(numTrainDocs)    p0Num = ones(numWords)    p1Num = ones(numWords)    p0Denom = 2.0    p1Denom = 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)    p0Vect = log(p0Num/p0Denom)    return p0Vect,p1Vect,pAbusivedef classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):    p1 = sum(vec2Classify * p1Vec) + log(pClass1)#(vec2Classify * p1Vec)表示如果特征出现的概率**特征出现的次数(平方),没出现则是0次方(注意plVec是log)    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)    if p1 > p0:        return 1    else:        return 0def testingNB():    listOPosts,listClasses = loadDataSet()    myVocabList = createVocabList(listOPosts)    trainMat=[]    for postinDoc in listOPosts:        trainMat.append(bagOfWord2VecMN(myVocabList, postinDoc))    p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))    testEntry = ['love', 'my', 'dalmation']    thisDoc = array(bagOfWord2VecMN(myVocabList, testEntry))    print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))    testEntry = ['stupid', 'garbage']    thisDoc = array(bagOfWord2VecMN(myVocabList, testEntry))    print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))testingNB()

参考:
http://blog.csdn.net/fengsser/article/details/48056557

0 0