《机器学习实战》程序清单4-2 朴素贝叶斯分类器训练函数

Posted 王明辉的部落

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《机器学习实战》程序清单4-2 朴素贝叶斯分类器训练函数相关的知识,希望对你有一定的参考价值。

 此文旨在把trainNB0这个函数详细讲清楚。

def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory)/float(numTrainDocs)
    #? (以下两行)初始化概率 
    p0Num = zeros(numWords); p1Num = zeros(numWords)
    p0Denom = 0.0; p1Denom = 0.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 = p1Num/p1Denom #change to log()
    #? 对每个元素做除法
    p0Vect = p0Num/p0Denom #change to log()
    return p0Vect,p1Vect,pAbusive

下面把这个函数逐步分解:

1.参数

此函数的参数有两个,一个是trainMatrix,另一个是trainCategory,这两个参数是一步一步的数据处理产生的结果,过程如下:

1.1第一步 创建实验样本


可能是为了简化操作,突出重点,作者在这里设置了手工设置类别,在应用场景中,应当是自动判断自动生成的。
listOPosts,listClasses = bayes.loadDataSet()

这一句产生了listOPosts和listClasses

详细内容分别是:

listOPosts:

[[‘my‘,‘dog‘,‘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‘]
]

listClasses:
[0,1,0,1,0,1]

其中的
listOPosts即list Of Posts,文档列表,就是帖子列表、邮件列表等等。你可以认为列表中的一元素就是一个帖子或者回复,
在此例中一共6个文档、帖子、回复(以后统称文档)。
分别是:
[‘my‘,‘dog‘,‘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‘]

可以看到,2、4、6句标红部分,存在侮辱性词条,第1、3、5个句子,不存在侮辱性词条,所以,对应的类别标签设置为
listClasses = [0,1,0,1,0,1]


 

  1.2第二步 创建包含所有不重复词条的集合(词汇表)

这一步是为了产生一个大而全的集合,这个集合包括了所有文档(即第一步产生的6个文档)中的词条,但每个词条都不重复。

#创建一个所有文档中的不重复单词列表
def createVocabList(dataSet):
    vocabSet = set([]) #创建一个空集
    n = 0
    for document in dataSet:
        vocabSet = vocabSet | set(document) #创建两个集合的并集
        n += 1
        # print(‘vocabSet:‘,n,vocabSet)
        # print(‘文档集合的总长度:‘,len(vocabSet))

    a = list(vocabSet)
    a.sort()
return a

Python中的集合(set)具有消除重复元素的功能。

书中代码没有排序。为了看得更清楚,我加上了排序。

上述代码中的

vocabSet = vocabSet | set(document)

并集操作,相当于 += 操作

此函数的参数dataSet,即是上一步产生的listOPosts

调用方式:
myVocablList = createVocabList(listOfPosts)

运行结果是:
[‘I‘, ‘ate‘, ‘buying‘, ‘cute‘, ‘dalmation‘, ‘dog‘, ‘flea‘, ‘food‘, ‘garbage‘, ‘has‘, ‘help‘, ‘him‘, ‘how‘, ‘is‘, ‘licks‘, ‘love‘,
‘maybe‘, ‘mr‘, ‘my‘, ‘not‘, ‘park‘, ‘please‘, ‘posting‘, ‘problems‘, ‘quit‘, ‘so‘, ‘steak‘, ‘stop‘, ‘stupid‘, ‘take‘, ‘to‘, ‘worthless‘]

1.3第三步 文档向量

  获得词汇表后,便可以使用函数setOfWords2Vec(),该函数的输入参数为词汇表及某个文档,输出的是文档向量,向量的每一元素为1或0,分别表示词汇表中的单词在输入文档中是否出现。

def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)

  for word in inputSet: if word in vocabList: # print("word:",word) returnVec[vocabList.index(word)] = 1 else: print("the word:%s is not in my Vocabulary!" % word) return returnVec # 返回一个list
vocabList即上一步产生的词汇表,inputSet可以是任意一篇文档,此处为了简化操作,在6篇文档中选取。
调用方式:
    listOfPosts,listClasses = loadDataSet()
    print(listOfPosts)
    myVocablList = createVocabList(listOfPosts)
    print(myVocablList)

    l = listOfPosts[0]
    l.append("中华人民共和国")
    l.append("kk")
    print("listOfPosts:", listOfPosts[0])
    b = setOfWords2Vec(myVocablList, listOfPosts[0])
    print(b)

得到:

[0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]

 

 

 



 

 

以上是关于《机器学习实战》程序清单4-2 朴素贝叶斯分类器训练函数的主要内容,如果未能解决你的问题,请参考以下文章

机器学习实战读书笔记基于概率论的分类方法:朴素贝叶斯

《机器学习实战》基于朴素贝叶斯分类算法构建文本分类器的Python实现

机器学习实战教程:朴素贝叶斯实战篇之新浪新闻分类

机器学习实战 朴素贝叶斯

NBC朴素贝叶斯分类器 ————机器学习实战 python代码

实战|朴素贝叶斯分类对文档进行分类