1 #这个函数是用来统计得到一个总体单词向量的,就是:所有的文本一共有多少个不同的单词, 2 #由这些不同的单词组成一个单词向量,向量可以理解成为列表 3 #dataSet:是训练数据集 4 def createVocabList(dataSet): 5 #使用python内置set函数创建一个空的集合,用来保存数据集的单词向量,集合里面的元素都是独一无二的 6 vocabSet = set([]) 7 #使用for循环逐行逐行地读取数据集 8 for document in dataSet: 9 #set(document) :将当前这一行数据去重,得到这行数据的单词向量 10 #然后通过集合的或运算(和数学的集合或运算一样),把当前行的单词向量保存到集合vocabSet中 11 #在保存到集合vocabSet前,都要把当前的集合vocabSet与当前的行的单词向量set(document)做集合的或运算处理 12 #目的是为了保证每次最后保存到集合vocabSet中的单词都是独一无二的 13 vocabSet = vocabSet | set(document) 14 #最后将集合vocabSet变成为列表类型的数据返回 15 return list(vocabSet)
一、贝页斯算法理论原理
如图所示:
1 | 1 | 1 | 2 | 2 | 2 | 2 |
P(1):表示出现1在所有数字的概率
得:P(1)=3/7
如果,将着7个数字放进两个格子中,那么将如何计算出现1的概率呢?
A行:
1 | 1 | 2 | 2 |
B行:
1 | 2 | 2 |
已知:B行所有数字占(A+B)行数字的概率为:P(B|(A+B))=3/7,已知所有数字的总数为7,则第B行的1概率占A+B行所有数字的概率为:P(1/A+B)=1/7
未知:B行出现数字1占B行的概率,这个概率是多少呢?(我们口算可以知道是1/3,但下面我们用已知的数据求出这个1/3)
条件概率的计算公式:P(1/B)= P(1/A+B) / P(B|(A+B)) = 1/7 / 3/7 = 1/3
二、以在线社区的留言板为例,说明贝页斯算法的用法。
为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一 个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标识为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类别:侮辱类和非侮辱类,使用1和0分别表示。
朴素贝叶斯的一般过程
(1) 收集数据:可以使用任何方法。本章使用RSS源。
(2) 准备数据:需要数值型或者布尔型数据。
(3) 分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好。
(4) 训练算法:计算不同的独立特征的条件概率。
(5) 测试算法:计算错误率。
(6) 使用算法:一个常见的朴素贝叶斯应用是文档分类。可以在任意的分类场景中使用朴素贝叶斯分类器,不一定非要是文本。
1、准备数据:从文本中构建词向量
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] return postingList,classVec
1 dataSet,labels = loadDataSet() 2 3 #验证数据集规模和数据集标签 4 print('训练数据集规模:') 5 print(np.shape(dataSet)) 6 print('打印训练数据集:') 7 print(dataSet) 8 print('打印训练数据集标签:') 9 print(labels)
1 #这个函数是用来统计得到一个总体单词向量的,就是:所有的文本一共有多少个不同的单词, 2 #由这些不同的单词组成一个单词向量,向量可以理解成为列表 3 #dataSet:是训练数据集 4 def createVocabList(dataSet): 5 #使用python内置set函数创建一个空的集合,用来保存数据集的单词向量,集合里面的元素都是独一无二的 6 vocabSet = set([]) 7 #使用for循环逐行逐行地读取数据集 8 for document in dataSet: 9 #set(document) :将当前这一行数据去重,得到这行数据的单词向量 10 #然后通过集合的或运算(和数学的集合或运算一样),把当前行的单词向量保存到集合vocabSet中 11 #在保存到集合vocabSet前,都要把当前的集合vocabSet与当前的行的单词向量set(document)做集合的或运算处理 12 #目的是为了保证每次最后保存到集合vocabSet中的单词都是独一无二的 13 vocabSet = vocabSet | set(document) 14 #最后将集合vocabSet变成为列表类型的数据返回 15 return list(vocabSet)
1 #这个函数的作用是将原来文本的一条记录,转变成为与单词向量一样长度的,只有0和1两个值的一条数据记录 2 #vocabList:原数据集单词向量 3 #inputSet:数据集的一条文本记录 4 def setOfWords2Vec(vocabList, inputSet): 5 #生成一个长度与单词向量一样的列表,里面的元素默认都是零 6 returnVec = [0]*len(vocabList) 7 #逐个地把每条记录的单词读出来 8 for word in inputSet: 9 #判断这个单词在单词向量中存不存在 10 if word in vocabList: 11 #如果单词向量存在这个单词,那就获取这个单词所在单词向量的位置下标vocabList.index(word) 12 #然后根据这个下标,把returnVec的对应位置下标的值修改为1 13 returnVec[vocabList.index(word)] = 1 14 else: 15 #如果这个单词不存在单词向量中,打印一条提示的信息该单词不在单词向量中。(向量和列表是一样的) 16 print("the word: %s is not in my Vocabulary!" % word) 17 #将这条转换得到的数据返回 18 return returnVec 19 20 trainData = [] 21 22 for i in range(len(dataSet)): 23 returnVec = setOfWords2Vec(world,dataSet[i]) 24 trainData.append(returnVec)
1 #这个函数的作用是获取原数据集类别的概率和数据集每种类别对应的特征的概率 2 #trainMatrix:转换后的数据集 3 #trainCategory:数据集的标签 4 def trainNB0(trainMatrix,trainCategory): 5 #取得数据集行数 6 numTrainDocs = len(trainMatrix) 7 #取得列数 8 numWords = len(trainMatrix[0]) 9 #计算标签列1的概率 10 pAbusive = sum(trainCategory)/float(numTrainDocs) 11 #生成一个变量用来保存属于0这个类别的记录的所有特征对应位置累加的结果,现在默认里面的数值都是1 12 p0Num = np.ones(numWords) 13 #生成一个变量用来保存属于1这个类别的记录的所有特征对应位置累加的结果,现在默认里面的数值都是1 14 p1Num = np.ones(numWords) 15 #定义一个变量用来保存属于0这个类别的所有记录的所有元素的累加和,默认初始值是2 16 p0Denom = 2.0 17 #定义一个变量用来保存属于1这个类别的所有记录的所有元素的累加和,默认初始值是2 18 p1Denom = 2.0 19 #使用for循环按行读取转换后的数据集 20 for i in range(numTrainDocs): 21 #如果当前行的数据记录是属于1这个类别的 22 if trainCategory[i] == 1: 23 #那就把这一条数据记录中的各个元素对应累加到p1Num中 24 p1Num += trainMatrix[i] 25 #把这条数据记录中的所有元素都累加到p1Denom中 26 p1Denom += sum(trainMatrix[i]) 27 else: 28 #如果当前行的数据记录是属于0这个类别的 29 #那就把这一条数据记录中的各个元素对应累加到p0Num中 30 p0Num += trainMatrix[i] 31 #把这条数据记录中的所有元素都累加到p0Denom中 32 p0Denom += sum(trainMatrix[i]) 33 #求得1这个类别对应各个特征的概率p1Num/p1Denom,并且把这个概率取对数,使得每个特征属性对应的值绝对值不那么小 34 p1Vect = np.log(p1Num/p1Denom) 35 #求得0这个类别对应各个特征的概率p0Num/p0Denom,并且把这个概率取对数,使得每个特征属性对应的值绝对值不那么小 36 p0Vect = np.log(p0Num/p0Denom) 37 #p0Vect:零这个类别对应每个特征属性的概率取值,(使用log函数处理了一下) 38 #p1Vect:零这个类别对应每个特征属性的概率取值,(使用log函数处理了一下) 39 #pAbusive:标签列1的概率 40 return p0Vect,p1Vect,pAbusive
1 #vec2Classify:未知标签的数据记录 2 #p0Vec:零标签对应32个属性的概率 3 #p1Vec:1标签对应32个属性的概率 4 #pClass1:1标签所占的概率 5 def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): 6 #vec2Classify* p1Vec:将这个未知标签的记录中每个元素对应乘以一个概率, 7 #然后再使用sum函数求所有乘积的累加和sum(vec2Classify * p1Vec), 8 #最后再加上原数据集1这个类别标签概率的对数 9 #最后得到的p1就是:这条vec2Classify未知标签数据记录属于1这个类别的概率的大小 10 p1 = sum(vec2Classify * p1Vec) + np.log(pClass1) 11 #vec2Classify* p0Vec:将这个未知标签的记录中每个元素对应乘以一个概率, 12 #然后再使用sum函数求所有乘积的累加和sum(vec2Classify * p0Vec), 13 #最后再加上原数据集0这个类别标签概率的对数 14 #最后得到的p0就是:这条vec2Classify未知标签数据记录属于0这个类别的概率的大小 15 p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1) 16 #如果p1>p0 17 if p1 > p0: 18 #那么返回这个未知标签的记录的预测标签是1 19 return 1 20 else: 21 #否则预测标签就是0 22 return 0
1 #这个函数是用来测试算法的 2 def testingNB(): 3 #加载上面的训练数据集,对应的标签列 4 listOPosts,listClasses = loadDataSet() 5 #根据训练数据集得到数据集的单词向量,里面的每个单词都是独一无二的 6 myVocabList = createVocabList(listOPosts) 7 #定义一个列表,用来保存将原数据集转换之后的数据记录,然后就把这个列表数据集当成训练数据集 8 trainMat=[] 9 #使用for循环逐行地读取原数据集 10 for postinDoc in listOPosts: 11 #setOfWords2Vec(myVocabList, postinDoc:根据单词向量把当前这条原记录变成另一种数据记录形式 12 #然后把这条转换得到的数据集记录保存到trainMat中 13 trainMat.append(setOfWords2Vec(myVocabList, postinDoc)) 14 #np.array(trainMat):将数据集的数据集类型变成数组类型 15 #np.array(listClasses):将数据集的标签类型变成数组类型 16 #调用trainNB0函数获取新的训练数据集中 17 #零这个类别对应每个特征属性的概率取值p0V,(使用log函数处理了一下) 18 #1这个类别对应每个特征属性的概率取值p1V,(使用log函数处理了一下) 19 #标签列1的概率pAb 20 p0V,p1V,pAb = trainNB0(np.array(trainMat),np.array(listClasses)) 21 #testEntry:一条未知标签的原文本数据 22 testEntry = ['love', 'my', 'dalmation'] 23 #调用setOfWords2Vec函数根据单词列表来将这条测试文本数据转化一下数据形式 24 #最后把得到的这个数据记录再转变从数组类型的数据记录 25 thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry)) 26 #调用classifyNB函数来获取该测试数据记录的标签 27 #并且打印这条记录数据的最后预测标签类别 28 print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)) 29 #这是第二条文本测试记录 30 testEntry = ['stupid', 'garbage'] 31 #调用setOfWords2Vec函数根据单词列表来将这条测试文本数据转化一下数据形式 32 #最后把得到的这个数据记录再转变从数组类型的数据记录 33 thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry)) 34 #调用classifyNB函数来获取该测试数据记录的标签 35 #并且打印这条记录数据的最后预测标签类别 36 print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)) 37 38 #调用testingNB这个函数,开始测试性预测 39 testingNB()
以上就是我的拙见,非常感谢您能看到这里,有什么问题可以评论指正哦。