今天完成了朴素贝叶斯预测的学习,其基本原理是利用条件概率进行预测
基本思路如下:
1.先生成一个库,库中包含了所有可能出现的元素。
2.库由先前的各种种类的对象构成,对象有种类和元素两种属性。
3.现在我们可以构建训练集,获取如下条件概率。
元素 i 在种类 J中出现的概率
实现过程为,计算种类J中出现的所有元素数量,以及元素i出现的数量,两者相除
表示为 P(i | J)
我们想要得到是,通过某一对象,出现的元素判断它属于哪一个种类
即计算各种类 P(J | i1,i2,i3…)的条件概率 (下用I表示)
用贝叶斯概率公式可以得到
P(J | I)= P(I | J)P(J)/ P(I)
对于同一个对象 P(I)相同,故只要比较分子即可判断出各J类的不同条件概率的大小关系
代码如下:
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 #此函数用于准备一些文本数据
def createVocabList(dataSet):#生成词汇库
vocabSet = set([])
for document in dataSet:#对问本数据的每一句话所表示的向量进行循环
vocabSet = vocabSet | set(document) #用并集的方式,吸纳不同的新的词汇
return list(vocabSet)
def setOfWords2Vec(vocabList, inputSet): #两个参数分别表示一个已有的词汇库和输入的文本数据
returnVec = [0]*len(vocabList) #做一个与词汇库等长的向量,并且默认值都设置为0
for word in inputSet: #对输入的文本的单词进行遍历,若出现,则设置对应的索引值为1
if word in vocabList:
returnVec[vocabList.index(word)] = 1
else:print ("the word:%s is not in my Vocabulary" % word)
return returnVec
import numpy as np
def trainNBO(trainMatrix,trainCategory):#trainMatrix 为文档矩阵,即setOfWords2Vec得到的向量构成的矩阵
numTrainDocs = len(trainMatrix)#确定训练的问本条目数
numWords = len(trainMatrix[0])#确认词库中包含的单词数
pAbusive = sum(trainCategory)/float(numTrainDocs)#带有侮辱性的标签为1,除以总文本条目数,即为侮辱性出现的概率
p0Num = np.ones(numWords);p1Num = np.ones(numWords) #这边用1不用0是为了防止数值过小不便于比较
p0Denom = 2.0; p1Denom = 2.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[i] #累计带侮辱性词句中,各单词出现的频数
p1Denom += sum(trainMatrix[i])#累计带侮辱性词句中出现的总单词数
else:
p0Num += trainMatrix[i]#累计正常语句中,各单词出现的频数
p0Denom += sum(trainMatrix[i])#累计正常词句中出现的单词总数
p1Vect = np.log(p1Num/p1Denom)#向量除以单词总数,得到在侮辱性词句中,各单词出现的概率(比如,侮辱性词句一共有50个单词,“dog”出现了20次,对应向量位置的值为20/50)
p0Vect = np.log(p0Num/p0Denom)#向量除以单词总数,得到在正常词句中,各单词出现的概率(取对数是为了后边方便计算)
return p0Vect,p1Vect,pAbusive#我们得到条件概率所需要的3个概率。
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify*p1Vec)+np.log(pClass1)#贝叶斯概率公式要求相乘,对原概率取对数可以将相加变为相乘
p0 = sum(vec2Classify*p0Vec)+np.log(1 - pClass1)
if p1 > p0:
return 1
else:
return 0
def testingNB(): #对以上函数进行了打包
listOPosts, listClasses = loadDataSet() #生成问本库
myVocabList = createVocabList(listOPosts)#导入文本库
trainMat=[]#先暂时设置训练集为空集
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))#将文本库中的文本转为数字矩阵,并导入到训练集中
p0V, p1V, pAb = trainNBO(np.array(trainMat),np.array(listClasses))#分别计算在侮辱性语言非侮辱性语言中文本库中单词出现的概率,以及出现侮辱性语句的概率
testEntry = ['love','my','dalmation']#生成待测试的文本
thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))#将待测试的文本转化为数字向量,表示其出现的各单词的频数
print (testEntry,'classified as: ',classifyNB(thisDoc, p0V, p1V, pAb))#进行区分
testEntry = ['stupid','garbage']
thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
print (testEntry,'classified as: ',classifyNB(thisDoc, p0V, p1V, pAb))
代码原出版书籍方已公开
https://www.manning.com/books/machine-learning-in-action