机器学习实战第4章-朴素贝叶斯(bayes)
2017-12-10 09:39
375 查看
一、贝叶斯:
D:训练数据H:假设空间
h:假设
P(h):假设 h的先验概率 的先验概率 (Prior Probability)
即没有训练数据前假设拥有的初始概率
P(D):训练数据的先验概率
即在没有确定某一假设成立时的概率
p(D|h):似然度,在假设 h成立的情况下,观察到D的概率
p(h|D):后验概率,给定训练数据D时h成立的概率
后验概率正比于P(h)和P(D|h)
反比于P(D)
D独立于 h出现的概率越大,则出现的概率越大,则D对h的支持度越小
贝叶斯公式是学习的基础,它提供了根据先验概率 P(h)、P(D)以及观察概率 P(D|h) ,计算后验概率 P(h|D)的
二、朴素贝叶斯:
概念:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。独立性假设:假设所有特征都是相互独立的。
三、常见问题:
1、0概率:m-估计(因为假设是每个概率是独立的,如果某一项为0会导致乘积为0,所以默认加上一个数值)2、极小概率:取对数
平滑技术(m-估计):当样本的新属性值出现时,为了防止后验概率为0,需要对其先验概率做M估计(M-Estimate)
机器学习实战主要代码加注释:
from numpy import * import feedparser import operator #生成一个数据集和标签 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,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) #输入词汇表和文档,输出文档向量(跟词汇表一一对应),词汇出现就设置为1 def setOfWords2Vec(vocabList, inputSet): returnVec = [0]*len(vocabList) #每一次输入文档里的单词,看它在不在词汇表,在的话就在输出向量对应位置设置为1;不在输出他不在 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 #输入词汇表和文档,输出文档向量(跟词汇表一一对应),词汇出现就+1 def bagOfWords2VecMN(vocabList, inputSet): returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] += 1 return returnVec #朴素贝叶斯训练分类器计算p0Vect,p1Vect,pAbusive def trainNB0(trainMatrix,trainCategory): #获取矩阵里元素数目,词汇组数 numTrainDocs=len(trainMatrix) #获取矩阵里第一个列表元素里的词汇个数 numWords=len(trainMatrix[0]) #计算侮辱性文字的概率,trainCategory列表里元素和是侮辱性文字总组数 pAbusive=sum(trainCategory)/float(numTrainDocs) #生成元素个数与列表内元素相同的1矩阵;分子设置为1,分母为2防止概率相乘时候出现0使最后乘积也为0 p0Num=ones(numWords) p1Num=ones(numWords) p0Denom=2.0 p1Denom=2.0 #遍历矩阵里每个列表元素(每组词汇) for i in range(numTrainDocs): #只要出现词汇表里的词就把对应分类里的词汇+1,计算所有元素的和 if trainCategory[i]==1: p1Num+=trainMatrix[i] p1Denom+=sum(trainMatrix[i]) else: p0Num+=trainMatrix[i] p0Denom+=sum(trainMatrix[i]) #求出概率 求对数避免乘法时候下溢 log(ab)=loga+logb # p1Vect=p1Num/p1Denom # p0Vect=p0Num/p0Denom p1Vect=log(p1Num/p1Denom) p0Vect=log(p0Num/p0Denom) return p0Vect,p1Vect,pAbusive #朴素贝叶斯分类函数 #vec2Classify为要分类的向量,pClass1为侮辱性文字的概率 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #元素相乘(对应位置相乘) p1=sum(vec2Classify*p1Vec)+log(pClass1) p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1) if p1>p0: return 1 else: return 0 def testingNB(): #拿到数据集(几个列表,每个列表里有若干单词)和分类信息 listOPsts,listClasses=loadDataSet() #把数据集里的单词去重生成一个词汇表 myVocabList=createVocabList(listOPsts) #生成文档矩阵,矩阵中每个元素是个列表 trainMat=[] # 用每组输入文档转化成的词向量填充trainMat数组 for postingDoc in listOPsts: trainMat.append(setOfWords2Vec(myVocabList,postingDoc)) #生成侮辱性文字概率,词汇表中每个(非)侮辱性词汇在总(非)侮辱性词汇里出现概率 p0V,p1V,pAb=trainNB0(array(trainMat),array(listClasses)) testEntry=['love','my','dalmation'] #testEntry里的词汇在不在词汇表里,生成一个文档向量 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)) #4.6 # 文本解析 def textParse(bigString): import re # 用除单词,数字外的任意字符串划分 ,要用\\W listOfTokens = re.split(r'\\W*', bigString) # regEx=re.compile('\\W', flags=0) # listOfTokens=regEx.split(bigString) return [tok.lower() for tok in listOfTokens if len(tok) > 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.append(wordlist) classList.append(1) wordlist = textParse(open('email/ham/%d.txt' % i).read()) docList.append(wordlist) fullText.append(wordlist) classList.append(0) #生成去重词汇表 vocabList = createVocabList(docList) # trainingSet = range(50) # python3.x, 出现错误'range'object doesn't support item deletion # 原因:python3.x range返回的是range对象,不返回数组对象 # 解决方法:把 trainingSet = range(50)改为trainingSet = list(range(50)) #生成0到49的列表 trainingSet = list(range(50)) testSet=[] #随即选10封作为测试集 for i in range(10): randIndex=int(random.uniform(0,len(trainingSet))) testSet.append(trainingSet[randIndex]) del(trainingSet[randIndex]) trainMat=[] trainClasses=[] #生成文件向量 for docIndex in trainingSet: trainMat.append(setOfWords2Vec(vocabList,docList[docIndex])) trainClasses.append(classList[docIndex]) #求p0V,p1V,pSpam p0V,p1V,pSpam=trainNB0(array(trainMat),array(trainClasses)) errorCount=0 for docIndex in testSet: wordVector=setOfWords2Vec(vocabList,docList[docIndex]) if classifyNB(array(wordVector),p0V,p1V,pSpam)!=classList[docIndex]: errorCount+=1 print("classification error", docList[docIndex]) print('the error rate is: ',float(errorCount)/len(testSet)) #4.7 #计算词汇表里每个单词在全部文本里的出现频率,排序拿到频率前30的 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): docList=[] classList=[] fullText=[] minLen=min(len(feed1['entries']),len(feed0['entries'])) #每次访问一条rss源 for i in range(minLen): wordList=textParse(feed1['entries'][i]['summary']) docList.append(wordList) fullText.extend(wordList) classList.append(1) wordList=textParse(feed0['entries'][i]['summary']) docList.append(wordList) fullText.extend(wordList) classList.append(0) vocabList=createVocabList(docList) #去掉出现次数最高的那些词 top30Words=calcMostFreq(vocabList,fullText) for pairW in top30Words: if pairW[0] in vocabList: vocabList.remove(pairW[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,pSam=trainNB0(array(trainMat),array(trainClasses)) errorCount=0 for docIndex in testSet: wordVector=bagOfWords2VecMN(vocabList,docList[docIndex]) if classifyNB(array(wordVector),p0V,p1V,pSam)!=classList[docIndex]: errorCount+=1 print('the error rate is: ',float(errorCount)/len(testSet)) return vocabList,p0V,p1V #最具表征性的词汇显示函数 def getTopWords(ny,sf): vocabList,p0V,p1V=localWords(ny,sf) topNY=[]; topSF=[] for i in range(len(p0V)): if p0V[i] > -2.0 : topSF.append((vocabList[i],p0V[i])) if p1V[i] > -2.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**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**NY**NY**") for item in sortedNY: print(item[0])
相关文章推荐
- 机器学习实战python版第四章基于概率论的分类方法 朴素贝叶斯
- 机器学习实战 朴素贝叶斯分类器 python3实现
- 机器学习实战——朴素贝叶斯
- 机器学习实战笔记4(朴素贝叶斯)
- 机器学习实战学习笔记8——朴素贝叶斯
- 机器学习实战笔记(3.1)-朴素贝叶斯算法(原理分析)
- 机器学习实战(4)朴素贝叶斯学习笔记_20170707
- 读书笔记:机器学习实战(3)——章4的朴素贝叶斯分类代码和个人理解与注释
- 机器学习实战——python实现简单的朴素贝叶斯分类器
- 机器学习实战-4朴素贝叶斯-python3
- 机器学习实战_初识朴素贝叶斯算法_理解其python代码(二)
- 机器学习实战--基于概率论的分类方法:朴素贝叶斯
- 代码注释:机器学习实战第4章 基于概率论的分类方法:朴素贝叶斯
- 机器学习实战之朴素贝叶斯naive bayes
- 机器学习实战笔记4(朴素贝叶斯)
- 机器学习实战_初识朴素贝叶斯算法_理解其python代码(一)
- 机器学习实战 朴素贝叶斯原理及代码
- 机器学习实战之第四章 朴素贝叶斯
- 机器学习实战第四章朴素贝叶斯(1)
- 机器学习实战--chapter3 决策树