700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 机器学习实战(三)朴素贝叶斯NB(Naive Bayes)

机器学习实战(三)朴素贝叶斯NB(Naive Bayes)

时间:2024-02-14 19:04:07

相关推荐

机器学习实战(三)朴素贝叶斯NB(Naive Bayes)

目录

0.前言

1.条件概率

2.朴素贝叶斯(Naive Bayes)

3.朴素贝叶斯应用于文本分类

4.实战案例

4.1. 垃圾邮件分类案例

学习完机器学习实战的朴素贝叶斯,简单的做个笔记。文中部分描述属于个人消化后的理解,仅供参考。

所有代码和数据可以访问我的 github

如果这篇文章对你有一点小小的帮助,请给个关注喔~我会非常开心的~

0.前言

贝叶斯算法,是一类基于概率论的分类方法。朴素贝叶斯(Naive Bayes),是采取了贝叶斯最原始、最简单的假设的算法。

朴素贝叶斯算法给出实例属于各个类别的概率,然后选择概率最大的一类。贝叶斯决策理论的核心思想是选择具有最高概率的决策。

优点:在数据较少的情况下,仍然十分有效果缺点:对于输入数据的准备方式比较敏感适用数据类型:标称型数据

朴素贝叶斯假设:

所有特征都是独立的(即每个特征出现的可能性与其他特征无关)每个特征都是同等重要的

1.条件概率

称为事件的概率。称为在事件发生的情况下,事件的概率,这就是条件概率。根据概率论,给出以下的定义:

为了计算,我们可以设法通过计算来得到。

2.朴素贝叶斯(Naive Bayes)

假设类别为,测试样本为,要计算,可以通过计算,因为假设各个特征独立,所以有:

其概率,等于各个特征在此类别前提下的概率之积。

:属于不同类别的计算公式中,为分母相同,可以不计算:为训练集中,第个类别的概率,即第个类别的频率(出现的样本数/总样本数):为训练集属于第个类别的样本中,第个特征的概率,即第个特征的频率(特征出现的次数/总特征数)

通过以上可得出朴素贝叶斯分类器,对于测试样本,只需将每个特征的特征值与对应特征的概率相乘,就可得到,特征值相当于一个权重。

3.朴素贝叶斯应用于文本分类

在文本分类中,特征值的选取可有两种:

词集模型(set-of-words model):只判断这个词汇是否出现,即只有和词袋模型(bag-of-words model):判断这个词汇出现的次数

算法可根据以下步骤进行,其他应用场合也可参考:

将训练集中所有文本的单词拆分出来,去重,获得词汇表根据词汇表(特征),对每个文本提取特征值,将文本转换为向量计算和将测试文本转换为向量将向量的每一个元素与对应的概率相乘,即第个元素的特征值乘以计算出每一个类别的 ,选择最大概率的类别,作为分类结果

4.实战案例

以下将展示书中案例的代码段,所有代码和数据可以在github中下载:

4.1. 垃圾邮件分类案例

# coding:utf-8from numpy import *import re"""垃圾邮件分类案例"""# 根据所有样本集合创建词汇表def createVocabList(dataSet):vocabSet = set()for document in dataSet:# 集合求并集vocabSet = vocabSet | set(document)return list(vocabSet)# 通过词汇表,文本转换为向量# 词集模型(每个词只记录是否有出现)def setOfWords2Vec(vocabList, inputSet):returnVec = [0] * len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] = 1return returnVec# 通过词汇表,文本转换为向量# 词袋模型(每个词记录出现的次数)def bagOfWords2VecMN(vocabList, inputSet):returnVec = [0] * len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] += 1return returnVec# 训练NB分类器def trainNB0(trainMatrix, trainCategory):# 文档数量numTrainDocs = len(trainMatrix)# 向量中特征(单词)的数量numWords = len(trainMatrix[0])# 类别1占总文档的比例pAbusive = sum(trainCategory) / float(numTrainDocs)# 为防止再之后计算过程中某一个特征的概率为0,导致总的概率为0,不采用以下# p0Num = zeros(numWords)# p1Num = zeros(numWords)# p0Denom = 0.0# p1Denom = 0.0p0Num = ones(numWords)p1Num = ones(numWords)p0Denom = 2.0p1Denom = 2.0# 遍历每一个文本向量for i in range(numTrainDocs):# 如果向量属于类别1if trainCategory[i] == 1:# 通过向量,计算文档每个词汇的出现次数p1Num += trainMatrix[i]# 计算类别1中,单词的总数量p1Denom += sum(trainMatrix[i])else:p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])# 类别1中,每个单词出现的次数/总单词数=每个单词的出现比例# 为防止数值太小,对其取Logp1Vect = log(p1Num / p1Denom)p0Vect = log(p0Num / p0Denom)return p0Vect, p1Vect, pAbusive# 分类算法def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):# 因为 p1Vec 取过对数,log(x1)+...+log(xn)=log(x1*...*xn) 等于乘积p1 = sum(vec2Classify * p1Vec) + log(pClass1)p0 = sum(vec2Classify * p0Vec) + log(1 - pClass1)if p1 > p0:return 1else:return 0# 文件解析def textParse(bigString):listOfTokens = re.split('\W+', bigString)return [tok.lower() for tok in listOfTokens if len(tok) > 2]# 获取高频的前30个词汇def calcMostFreq(vocabList, fullText):freqDict = {}# 遍历词汇表中的每一个词for token in vocabList:freqDict[token] = fullText.count(token)# 排序sortedFreq = sorted(freqDict.items(), key=lambda item: item[1], reverse=True)return sortedFreq[:30]# 垃圾邮件测试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)# 获取高频词汇top30Words = calcMostFreq(vocabList, fullText)# 去除高频词汇,因高频词汇很可能是冗余词汇for pairW in top30Words:if pairW[0] in vocabList:vocabList.remove(pairW[0])trainingSet = list(range(50))testSet = []# 选择测试向量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(bagOfWords2VecMN(vocabList, docList[docIndex]))trainClasses.append(classList[docIndex])# p0V: 类别0中,每个词汇出现的比例# p1V: 类别1中,每个词汇出现的比例# pSpam: 类别1的文本数量占总文本数量的比例p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))correctCount = 0for docIndex in testSet:wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])if classifyNB(array(wordVector), p0V, p1V, pSpam) == classList[docIndex]:correctCount += 1print('the correct rate is: ', float(correctCount) / len(testSet))return vocabList, p0V, p1V# 获取最具表征性的词汇def getTopWords(vocabList, p0V, p1V):top0 = []top1 = []for i in range(len(p0V)):if p0V[i] > -6.0:top0.append((vocabList[i], p0V[i]))if p1V[i] > -6.0:top1.append((vocabList[i], p1V[i]))sorted0 = sorted(top0, key=lambda pair: pair[1], reverse=True)print("***** 0 *****")for item in sorted0:print(item[0])sorted1 = sorted(top1, key=lambda pair: pair[1], reverse=True)print('***** 1 *****')for item in sorted1:print(item[0])if __name__ == '__main__':vocabList, p0V, p1V = spamTest()# getTopWords(vocabList, p0V, p1V)

如果这篇文章对你有一点小小的帮助,请给个关注喔~我会非常开心的~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。