引文:前面提到的K最近邻算法和决策树算法,数据实例最终被明确的划分到某个分类中,下面介绍一种不能完全确定数据实例应该划分到哪个类别,或者说只能给数据实例属于给定分类的概率。
主要是运用贝叶斯定理
下面做一个简单的留言板分类,自动判别留言类别:侮辱类和非侮辱类,分别使用1和0表示。下面来做一下这个实验。以下函数全部写在一个叫bayes.py文件中,后面的实验室通过导入bayes.py,调用里面的函数来做的。
导入numpy包
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] #1 is abusive, 0 not
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表示出现过,0表示没有出现,函数如下:
def setOfWords2Vec(vocabList, inputSet):
returnVec = [0]*len(vocabList)
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
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs) #计算某个类发生的概率
p0Num = ones(numWords); p1Num = 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 = log(p1Num/p1Denom) #计算类标签为1时的其它属性发生的条件概率
p0Vect = log(p0Num/p0Denom) #计算标签为0时的其它属性发生的条件概率
return p0Vect,p1Vect,pAbusive #返回条件概率和类标签为1的概率
说明:
该算法包含四个输入,vec2Classify表示待分类的样本在词库中的映射集合,p0Vec表示条件概率
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0
其中p1和p0表示的是
词袋模型主要修改上面的第三个步骤,因为有的词可能出现多次,所以在单个样本映射到词库的时候需要多次统计。
def bagOfWords2VecMN(vocabList, inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] += 1
return returnVec
下面给出一个测试函数,直接调用该测试函数就可以实现简单的分类,测试结果看下个部分。
def testingNB():
#step1:加载数据集和类标号
listOPosts,listClasses = loadDataSet()
#step2:创建词库
myVocabList = createVocabList(listOPosts)
# step3:计算每个样本在词库中的出现情况
trainMat=[]
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
#step4:调用第四步函数,计算条件概率
p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
# step5
# 测试1
testEntry = [‘love‘, ‘my‘, ‘dalmation‘]
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,‘classified as: ‘,classifyNB(thisDoc,p0V,p1V,pAb)
# 测试2
testEntry = [‘stupid‘, ‘garbage‘]
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,‘classified as: ‘,classifyNB(thisDoc,p0V,p1V,pAb)
首先导入库,然后导入bayes.py文件
import os
os.chdir(r"E:\3-CSU\Academic\Machine Leaning\机器学习实战\src\machinelearninginaction\Ch04")
import bayes
可以看出,贝叶斯算法将[‘love’, ‘my’, ‘dalmation’]分为“无侮辱”一类,将[‘stupid’, ‘garbage’]分为“侮辱”性质的一类。
[1]《Machine Learning in Action 》机器学习实战
原文地址:http://blog.csdn.net/dream_angel_z/article/details/46120867