基于概率论的分类方法--朴素贝叶斯

来源:互联网 发布:mac怎么开机选择用户 编辑:程序博客网 时间:2024/05/21 17:23
  • 朴素贝叶斯法是基于贝叶斯定理特征条件独立假设(用于分类的特征在类确定的情况下是条件独立的)的分类方法
  • 对于给定的训练数据集,首先基于特征条件独立假设 学习输入、输出的联合概率分布;然后基于此模型,对给定的输入x,利用贝叶斯定理计算出后验概率最大的y(核心:高概率),并输出。
  • 朴素贝叶斯:学习、分类、贝叶斯法的参数估计算法
  • 朴素贝叶斯算法的应用:
    1、文档分类

  • 准备数据:从文本中构建词向量–构建一个不重复的包含所有文档出现的所有词汇的词汇列表,输出文档向量,如下例:该向量的值为0/1,表示文档中的词是否在词汇表中出现。(使用词袋模型,可以记录词汇出现的次数)

  • 训练算法:从词向量计算概率–使用贝叶斯定理计算词条在每个类别下出现的概率,贝叶斯准则
    伪代码:
    计算每个类别中的文档数目
    对每篇训练文档:
    对每个类别:
    如果词条出现在文档中–>增加该词条的计数值
    增加所有词条的计数值
    对每个类别:
    对每个词条:
    该词条的数目/总词条的数目–>得到条件概率
    返回每个类别的条件概率

  • 测试算法:要根据现实情况修改分类器
    朴素贝叶斯的应用:

  • 电子邮件垃圾过滤
    1、读取50封邮件(25封正常的,25封垃圾邮件),将每一封邮件都进行词划分,将这些词放入一个WordList列表中。在用extend()函数生成一份不含重复词汇的词汇列表。
    2、文本转换为向量
    3、在50封邮件中选10封作为测试集
    4、用训练集训练算法生成框架。
    5、用测试集测试,打印错误率。
  • 从个人广告中获取区域倾向
    1、输入文本(RSS源)
    2、划分文本
    3、去掉出现频率最高的30个词(从词汇表中)
    4、构建测试集(随机选取20个,并将这20条数据从训练集中移除)
    5、训练:将训练样本转换为向量,得到训练矩阵和类别,返回概率
    6、测试:将测试样本转换为向量,用训练得到的模型进行测试分类。
    7、输出错误率,返回概率
  • 分析数据:显示地域相关的用词
    排序,输出出现频率高的用词
#!/usr/bin/python# -*- coding: UTF-8 -*-#http://blog.csdn.net/u011475210/article/details/77926012###;参考代码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 setOfWord2Vec(vocabList,inputSet):#输入参数:词汇表、文档    returnVec = [0]*len(vocabList)#创建一个和词汇表等长的向量    for word in inputSet:#遍历文档        if word in vocabList:#该词汇在词汇表中遍历            returnVec[vocabList.index(word)]=1#在词汇表中出现过,该词汇标记为1        else:print('the word:%s is not my vocabulary!'%word)    return returnVec#返回文档向量#listOPosts,listClasses=loadDataSet()#myVocabList=createVocabList(listOPosts)#print(myVocabList)#print(setOfWord2Vec(myVocabList,listOPosts[0]))#print(setOfWord2Vec(myVocabList,listOPosts[3]))#朴素贝叶斯分类器训练函数def trainNB0(trainMatrix,trainCategory):#输入为文档矩阵、文档类别标签组成的向量    numTrainDocs = len(trainMatrix)#计算训练的文档数目    numWords = len(trainMatrix[0])#计算每篇文档的词条数    pAbusive = sum(trainCategory)/float(numTrainDocs)#文档属于侮辱类的概率    p0Num = ones(numWords)#创建空矩阵,有侮辱性    p1Num = ones(numWords)    p0Denom = 2#分母初始化为2,防止有一个为0即结果为0    p1Denom = 2    for i in range(numTrainDocs):#遍历        if trainCategory[i] == 1:#统计属于侮辱类的条件概率所需的数据,即P(w0|1),P(w1|1),P(w2|1)···            p1Num+=trainMatrix[i]            p1Denom +=sum(trainMatrix[i])        else:            p0Num +=trainMatrix[i]            p0Denom +=sum(trainMatrix[i])    p1Vec = log(p1Num/p1Denom)#取自然对数,防止下溢出    p0Vec = log(p0Num/p0Denom)    return p0Vec,p1Vec,pAbusivelistOPosts,listClasses=loadDataSet()#创建样本myVocabList = createVocabList(listOPosts)#trainMat=[]for postinDoc in listOPosts:#循环填充    trainMat.append(setOfWord2Vec(myVocabList,postinDoc))p0V,p1V,pAb=trainNB0(trainMat,listClasses)#训练#print(pAb)#print(p0V)#print(p1V)#朴素贝叶斯分类函数def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):    p1 = sum(vec2Classify*p1Vec)+log(pClass1)#对应元素相乘。logA * B = logA + logB,所以这里加上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(setOfWord2Vec(myVocabList,postinDoc))    p0V,p1V,pAb=trainNB0(trainMat,listClasses)    testEntry = ['love','my','dalmation']    thisDoc = array(setOfWord2Vec(myVocabList,testEntry))    print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))    testEntry = ['stupid','garbage']    thisDoc = array(setOfWord2Vec(myVocabList,testEntry))    print(testEntry,'classifier as:',classifyNB(thisDoc,p0V,p1V,pAb))#testingNB()def bagOfWords2VecMN(vocabList,inputSet):    returnVec = [0]*len(vocabList)    for word in inputSet:        if word in vocabList:            returnVec[vocabList.index(word)]+=1    return returnVec#使用朴素贝叶斯过滤垃圾邮件mySent = 'This book is the best book or M.L I have ever laid eyes upon.'#mySent= mySent.split()#print(mySet)#import re#regEx = re.compile('\\W*')#???#listOfTokens = regEx.split(mySent)#print(listOfTokens)#print([tok.lower() for tok in listOfTokens if len(tok)>0])#将文本统一为小写#文本解析及完整的垃圾邮件测试函数def textParse(bigString):#接受大字符串并将解析为字符串列表    import re    listOfTokens = re.split(r'\W*',bigString)#\W表示非单词字符,*表示多个或0个    return [tok.lower() for tok in listOfTokens if len(bigString)>2]#过滤掉小于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 = list(range(50))    testSet = []    #初始化训练集和测试集    for i in range(10):#随机构建测试集,随机选取10个Index,从样本从剔除        randIndex = int(random.uniform(0,len(trainingSet)))        testSet.append(trainingSet[randIndex])#将选择的样本加入到测试集中        del(trainingSet[randIndex])#将选中的索引从训练样本中删除    trainMat=[]    trainClasses = []    for docIndex in trainingSet:#遍历训练集        trainMat.append(setOfWord2Vec(vocabList,docList[docIndex]))#文本转换为矩阵        trainClasses.append(classList[docIndex])#添加上述文本的对应标签    p0V,p1V,pSpam =  trainNB0(array(trainMat),array(trainClasses))#贝叶斯训练数据,返回概率    errorCount = 0    for docIndex in testSet:#遍历测试集        wordVector = setOfWord2Vec(vocabList,docList[docIndex])#文本转换为矩阵        if classifyNB(array(wordVector),p0V,p1V,pSpam)!=classList[docIndex]:#测试样本的分类结果与标签不一致            errorCount+=1#错误率加1    print('the error rate is:',float(errorCount)/len(testSet))#结果验证#spamTest()#RSS源分类器及高频词去除函数def calcMostFreq(vocabList,fullText):#辅助函数,统计词汇表中的词在文本中出现的次数并排序    import operator    freqDict={}    for token in vocabList:        freqDict[token] = fullText.count(token)    sortedFreq = sorted(freqDict.items(),key=operator.itemgetter(1),reverse=True)    return sortedFreq[:30]#返回字典def localWords(feed1,feed0):#参数是两个RSS源    import feedparser    docList=[]    classList=[]    fullText=[]    minLen = min(len(feed1['entries']),len(feed0['entries']))    for i in range(minLen):        wordList = textParse(feed1['entries'][i]['summary'])#每次访问一条RSS源        docList.append(wordList)        fullText.extend(wordList)        classList.append(1)#feed1的标签是1        wordList = textParse(feed0['entries'][i]['summary'])#feed0['entries']包含所有帖子        docList.append(wordList)        fullText.extend(wordList)        classList.append(0)    vocabList = createVocabList(docList)    top30Words = calcMostFreq(vocabList, fullText) #从词汇表中去除30个出现频率最高的词    for pariW in top30Words:        if pariW[0] in vocabList:vocabList.remove(pariW[0])    trainingSet=list(range(2*minLen))    testSet = []    for i in range(20):        randIndex = int(random.uniform(0,len(trainingSet)))        testSet.append(trainingSet[randIndex])        del(trainingSet[randIndex])    trainMat = []    trainClasses = []    for docIndex in trainingSet:        trainMat.append(bagOfWords2VecMN(vocabList,docList[docIndex]))        trainClasses.append(classList[docIndex])    p0V,p1V,pSpam=trainNB0(trainMat,trainClasses)    errorCount=0    for docIndex in testSet:        wordVector = bagOfWords2VecMN(vocabList,docList[docIndex])        if classifyNB(array(wordVector),p0V,p1V,pSpam)!=classList[docIndex]:            errorCount+=1    print('the error rate is:',float(errorCount)/len(testSet))    return vocabList,p0V,p1Vimport feedparserny=feedparser.parse('http://newyork.craigslist.org/stp/index.rss')sf=feedparser.parse('http://sfbay.craigslist.org/stp/index.rss')localWords(ny,sf)#最具表征性的词汇显示函数(显示地域相关的用词)def getTopWords(ny,sf):    import operator    vocabList,p0V,p1V= localWords(ny,sf)    topNY=[]    topSF=[]    for i in range(len(p0V)):#设定阈值。返回大于阈值的所有词,如果输出信息多就提高阈值,这里的阈值是取对数之后的概率,所以是负数        if p0V[i] > -6.0 : topSF.append((vocabList[i],p0V[i]))        if p1V[i] > -6.0 : topNY.append((vocabList[i],p1V[i]))    sortedSF = sorted(topSF,key=lambda pair:pair[1],reverse=True)    print('SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF')    for item in sortedSF:        print(item[0])    sortedNY = sorted(topNY,key=lambda pair:pair[1],reverse=True)    print('NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY')    for item in sortedNY:        print(item[0])getTopWords(ny,sf)
阅读全文
0 1
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果维修没发票怎么办 园林绿化资质取消后怎么办 出租车从业资格证到期怎么办 养老金认证身份证不符怎么办 硬盘指示灯不亮怎么办 做业务产品质量很差怎么办 没有户籍证明了怎么办 回执编号忘了怎么办 泳镜里面花了怎么办 网页打印预览空白怎么办 中专毕业证掉了怎么办 会计证年检忘了怎么办 会计准考证丢了怎么办 从业资格证没带怎么办 安全证过期了怎么办 安全员证掉了怎么办 局部抗浮不满足怎么办 职称代评被骗怎么办 租到了公租房怎么办 公租房不住了怎么办 公寓不退押金怎么办 找物业租房被骗怎么办 租房子被骗了怎么办 公租房怎么办入住手续 重庆公租房摇到号怎么办 重庆公租房摇到号后怎么办 我被网上起诉怎么办 摇号摇到了不买怎么办 保障房离婚了怎么办 深圳有房子户口怎么办 北京户口没有房怎么办 选房顺序号靠后怎么办 房子拖着不开盘怎么办 楼开盘人多怎么办 低保取消廉租房怎么办 航空公司病退审核慢怎么办 江里水流大跑线怎么办 js逻辑好难怎么办 怀孕了好无聊怎么办 做表率我们怎么办心得 晚上左转逆行了怎么办