本文摘自《机器学习实战》,感兴趣者可回复获得资源!
问题描述
以在线社区留言板为例,为了不影响社区的发展,现构造一个快速过滤器,用以屏蔽侮辱性言论。
准备数据:从文本中构建词向量
(1)首先将所有文档中的单词组成词汇表
def loadDataSet():
postingList=[['my','dog','has','flea','problems','help','pleas'],
['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','to','stop',
'him'],
['quite','buying','worthless','dog','food','stupid']]
classVec=[0,1,0,1,0,1] #1表示侮辱性文档,0表示非侮辱性文档
return postingList,classVec
#将文档矩阵中的所有词构成词汇表
def creatVocabList(dataset):
vocabSet=set([])
for document in dataset:
vocabSet=vocabSet|set(document) #两个集合的并集
return list(vocabSet)
(2)将每一篇文档转换为词汇表上的向量,现有两种模型:词集模型与词袋模型
词集模型:文档转换成的向量中的每一元素为1或0,分别表示词汇表中的单词在输入文档中是否出现。
词袋模型:文档转换成的向量中的每一元素,表示词汇表中的单词在输入文档中出现的次数
#将某一文档转换成词向量,该向量中所含数值数目与词汇表中词汇数目相同
#词集模型
def setOfWords2Vec(vocabList,inputSet): #参数分别为词汇表,输入文档
returnVec=[0]*len(vocabList)
for word in inputSet:
if word in vocabList:
#1表示词向量该位置对应的词汇表中的单词,出现在inpust文档中
returnVec[vocabList.index(word)]=1
return returnVec
#将某一文档转换成词向量,该向量中所含数值数目与词汇表中词汇数目相同
#词袋模型
def bagOfWords2Vec(vocabList,inputSet): #参数分别为词汇表,输入文档
returnVec=[0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)]+=1
return returnVec
训练算法:从词向量计算概率
#朴素贝叶斯分类器训练函数
#trainMatrix为文档词向量矩阵,
#trainCategory为每篇文档的类标签构成的向量
def trainNB0(trainMatrix,trainCategory):
numTrainDocs=len(trainMatrix) #总文档数
numWords=len(trainMatrix[0]) #所有词的数目
pAbusive=sum(trainCategory)/float(numTrainDocs) #侮辱性概率,即P(1)
p0Num=np.ones(numWords); p1Num=np.ones(numWords)
p0Deom=2.0; p1Deom=2.0
for i in range(numTrainDocs):
if trainCategory[i]==1:
p1Num+=trainMatrix[i] #向量相加
p1Deom+=sum(trainMatrix[i]) #所有侮辱性文档中出现的词条的总计数值
else:
p0Num+=trainMatrix[i]
p0Deom+=sum(trainMatrix[i])
p1Vect=np.log(p1Num/p1Deom) #在侮辱文档条件下词汇表中单词的出现概率
p0Vect=np.log(p0Num/p0Deom)
#pAbusive就是人以文档属于侮辱性文档的概率
return p0Vect,p1Vect,pAbusive
测试算法:根据现实情况修改分类器
#朴素贝叶斯分类函数
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass): #参数分别为:要分类的向量以及使用trainNB0()计算得到的三个概率
p1=sum(vec2Classify*p1Vec)+np.log(pClass)
p0=sum(vec2Classify*p0Vec)+np.log(1-pClass)
if p1>p0:
return 1 #表示侮辱性文档
else:
return 0
def testingNB():
listOPosts, listClass = loadDataSet()
myVocabList = creatVocabList(listOPosts)
trainMatrix = []
for value in listOPosts:
trainMatrix.append(bagOfWords2Vec(myVocabList, value))
p0v, p1v, pAb = trainNB0(trainMatrix, listClass)
testEntry=['love','my','dalmation']
#将文档转换成向量
testEntry=bagOfWords2Vec(myVocabList,testEntry)
print(classifyNB(testEntry, p0v, p1v, pAb))
testEntry=['stupid','garbage']
testEntry=bagOfWords2Vec(myVocabList,testEntry)
print(classifyNB(testEntry,p0v,p1v,pAb))
if __name__=='__main__':
testingNB()