使用朴素贝叶斯实现文本分类
一、实验目的
1. 理解朴素贝叶斯的基本原理和理论。
2. 学会使用朴素贝叶斯算法实现分类。
3. 学会分析朴素贝叶斯算法的优缺点。
4. 学会对朴素贝叶斯算法模型的准确率进行评估。
二、实验原理
朴素贝叶斯分类是一种十分简单的分类算法,叫它朴素贝叶斯分类是因为这种方法的思想真的很朴素,朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。通俗来说,就好比这么个道理,你在街上看到一个黑人,让你猜这哥们哪里来的,你十有八九猜非洲。为什么呢?因为黑人中非洲人的比率最高,当然人家也可能是美洲人或亚洲人,但在没有其它可用信息下,我们会选择条件概率最大的类别,这就是朴素贝叶斯的思想基础。
朴素贝叶斯,是一种简单但极为强大的预测建模算法。之所以称为朴素贝叶斯,一是因为它假设每个输入变量是独立的。二是这个假设通常现实生活中条件难以满足,但是这项技术对于绝大部分的复杂问题仍然非常有效。
朴素贝叶斯模型由两种类型的概率组成:
1、每个类别的概率P(Cj);
2、每个属性的条件概率P(Ai|Cj)。
![](https://i-blog.csdnimg.cn/direct/8434e2e40d1e4b14b5e976c59999d9cf.png)
三、实验内容
以在线社区留言为例。为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标志为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类型:侮辱类和非侮辱类,使用1和0分别表示。
我们把文本看成单词向量或者词条向量,也就是说将句子转换为向量。简单起见,我们先假设已经将本文切分完毕,存放到列表中,并对词汇向量进行分类标注。
判断测试数据分别属于哪一类文本?
四、实验步骤及结果
import numpy as np
def loadData():
postingData = [
['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmatian', '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]
return postingData, classVec
# 1.2 获取所有单词的集合
def createVocabList(dataSet):
vocabSet = set([])
for document in dataSet:
vocabSet = vocabSet | set(document)
return list(vocabSet)
# 1.3 遍历查看该单词是否出现,出现该单词则将该单词置1
def setofWord2VecMN(vocabList, inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] += 1
return returnVec
def trainNB0(trainMatrix, classVec):
numTrainDocs = len(trainMatrix)
pCi = sum(classVec) / numTrainDocs
numWords = len(trainMatrix[0])
p0Num = np.ones(numWords)
p1Num = np.ones(numWords)
p0Denom = 0.0
p1Denom = 0.0
for i in range(numTrainDocs):
if classVec[i] == 0:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
else:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
p0Vec = np.log(p0Num / p0Denom)
p1Vec = np.log(p1Num / p1Denom)
return p0Vec, p1Vec, pCi
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + np.log(pClass1)
p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0
def testClassifier():
# 加载数据集
postingData, classVec = loadData()
# 创建词汇表
vocabList = createVocabList(postingData)
# 将数据集转换为词向量
trainMat = []
for post in postingData:
trainMat.append(setofWord2VecMN(vocabList, post))
# 训练朴素贝叶斯分类器
p0Vec, p1Vec, pClass1 = trainNB0(trainMat, classVec)
# 测试数据集
testDocs = [
['stupid', 'garbage'],
['love', 'my', 'dalmatian'],
]
# 对测试数据集进行分类
for doc in testDocs:
newVec = setofWord2VecMN(vocabList, doc)
classification = classifyNB(newVec, p0Vec, p1Vec, pClass1)
print(f'Document: {doc}, Classified as: {classification}')
# 运行测试分类函数
testClassifier()
结语
本实验通过构建词向量和训练朴素贝叶斯分类器对文本数据进行分类,在实验中,我们通过创建数据集、生成词汇表、将文本转换为词向量,然后训练模型并对其进行分类测试。实验结果显示,朴素贝叶斯分类器能够在给定的训练数据集上进行有效的文本分类。
![](https://i-blog.csdnimg.cn/direct/771b98beb46b49f4953e7088a0cfe92b.jpeg)