此文旨在把 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]
可以看到, 246 句标红部分, 存在侮辱性词条, 第 135 个句子, 不存在侮辱性词条, 所以, 对应的类别标签设置为
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]
来源: http://www.bubuko.com/infodetail-2506891.html