先上代码(代码也是自己为了理解该分类器去找的别人的),在看得过程中的问题。
import numpy
#创建数据集
def LoadDataSet():
#文档列表
dataSet=[['my','dog','has','flea','problems','help','please'],
['maybe','not','him','to','dog','park','stupid'],
['my','dalmation','is','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 dataSet,classVec
#创建一个在所有文档中出现的不重复词的列表
def creatVocabList(dataSet): #dataset为文档列表
vocabSet=set([])
for document in dataSet:
vocabSet=vocabSet | set(document) #将单词唯一化,以交集方式加入保存词汇的集合
return list(vocabSet)
##将文档转换为词向量
def setOfWords2Vec(vocabList,inputSet): #(词汇表,待转换文档)
returnVec=[0]*len(vocabList) #词向量矩阵到底有多少个元素?????????
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)]=1
else: print("单词:%s不在词汇表中"%word)
return returnVec
# def test():
# listOPosts,listClasses=LoadDataSet()
# myVocabList=creatVocabList(listOPosts)
# print(setOfWords2Vec(myVocabList,listOPosts[0]))
def trainNBD(trainMatrix,trainCategory): #(词向量矩阵/一个二维数组,分类标签集/一个一维数组)
numTrainDocs=len(trainMatrix) #文档个数 #len(二维数组)=行数
numWords=len(trainMatrix[0]) #文档词数
pAbusive=sum(trainCategory)/float(numTrainDocs) #文档属于分类1的概率????
p0Num=numpy.zeros(numWords) #属于分类0的词向量求和,返回的是一个1行numwords列全是0的数组
p1Num=numpy.zeros(numWords)
p0Denom=2.0
p1Denom=2.0
for i in range(numTrainDocs): #遍历个文档
if trainCategory[i]==1: #若文档属于分类1
p1Num+=trainMatrix[i] #词向量累加,是两个一维数组在相加,得到所有标签为1的单词总数(trainMatrix[i]是一个行,一整行)
p1Denom+=sum(trainMatrix[i]) #分类1文档单词数累加
else:
p0Num+=trainMatrix[i]
p0Denom+=sum(trainMatrix[i])
p1Vect=p1Num/p1Denom #各单词在分类1的条件下出现的概率,数组形式的除法?????????每个元素除以对应位置元素??
p0Vect=p0Num/p0Denom
return p0Vect,p1Vect,pAbusive
# def test():
# listOPosts, listClasses = LoadDataSet()
# myVocabList = creatVocabList(listOPosts)
#
# trainMat=[]
# for postinDoc in listOPosts:
# trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
# p0V,p1V,pAb=trainNBD(trainMat,listClasses)
# print(p0V)
#得到最终分类
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #(目标对象的词向量数组)
p1=sum(vec2Classify*p1Vec)+numpy.log(pClass1) #为分类1的概率,做平滑处理后,乘积变相加
p0=sum(vec2Classify*p0Vec)+numpy.log(1.0-pClass1) #为分类0的概率
if p1>p0:
return 1
else:
return 0
def test():
listOPosts, listClasses = LoadDataSet()
myVocabList = creatVocabList(listOPosts)
trainMat=[] #创建词向量矩阵
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb=trainNBD(numpy.array(trainMat),numpy.array(listClasses)) #对词向量矩阵分类并返回各单词在各分类条件下的概率
testEntry=['my','cute','dog']
thisDoc=numpy.array(setOfWords2Vec(myVocabList,testEntry)) #返回词向量列表
print(testEntry,'分类结果:',classifyNB(thisDoc,p0V,p1V,pAb))
testEntry = ['stupid','garbage']
thisDoc = numpy.array(setOfWords2Vec(myVocabList, testEntry))
print(testEntry, '分类结果:', classifyNB(thisDoc, p0V, p1V, pAb))
test()
问题1:vocabSet=vocabSet | set(document),python中的交集 “ | ",
“|”既可以用于集合求并集,也可以按位求或。
问题2:returnVec=[0]*len(vocabList)
python中数组a=[x]*n,表示创建了一个有n个元素的,每个元素都为x的数组
问题3:numTrainDocs=len(trainMatrix) numWords=len(trainMatrix[0]) 对比
对于二维数组a[m][n],len(a)=行数,len(a[0])=列数
问题4:numpy.zeros(numWords)
numpy.zeros(shape,dtype=float,order = 'C')用法:
上一行是他的默认参数,第一个可自己设定,用于确定数组大小,第二个有int和float两种类型,第三个有'C','F'两种类型,分别表示以行存储和列存储。
numpy.zeros(4)输出:[0.,0.,0.,0.]
numpy.zeros((4,),int) 输出:[0,0,0,0]
numpy.zeros((2,3),int) 输出:[[0,0,0]
[0,0,0]]
即shape中当只有一个数字时,默认其为列数(默认行存储);当为(a,b)时,默认为a行b列;当为(a,)此时默认a为列数!!!
问题5:体会append和extend的区别:
List 的两个方法 extend 和 append 看起来类似,但实际上完全不同。extend 接受一个参数,这个参数总是一个 list,并且把这个 list 中的每个元素添加到原 list 中。append 接受一个参数,这个参数可以是任何数据类型,并且简单地追加到 list 的尾部。
贝叶斯公式详细理解(什么是先验概率、后验概率、似然估计):