朴素贝叶斯文本分类代码(详解)
1 from numpy import zeros,array 2 from math import log 3 4 def loadDataSet(): 5 #词条切分后的文档集合,列表每一行代表一个email 6 postingList=[['your','mobile','number','is','award','bonus','prize'], 7 ['new','car','and','house','for','my','parents'], 8 ['my','dalmation','is','so','cute','I','love','him'], 9 ['today','voda','number','prize', 'receive','award'], 10 ['get','new','job','in','company','how','to','get','that'], 11 ['free','prize','buy','winner','receive','cash']] 12 #由人工标注的每篇文档的类标签 13 classVec=[1,0,0,1,0,1] #1-spam, 0-ham 14 return postingList,classVec 15 postingList,classVec = loadDataSet() 16 17 18 #统计所有文档中出现的词条列表 19 def createVocabList(dataSet): 20 vocabSet=set([]) 21 #遍历文档集合中的每一篇文档 22 for document in dataSet: 23 vocabSet=vocabSet|set(document) 24 return list(vocabSet) 25 vocabSet = createVocabList(postingList) 26 27 28 #根据词条列表中的词条是否在文档中出现(出现1,未出现0),将文档转化为词条向量 29 def setOfWords2Vec(vocabSet,inputSet): 30 #新建一个长度为vocabSet的列表,并且各维度元素初始化为0 31 returnVec=[0]*len(vocabSet) 32 #遍历文档中的每一个词条 33 for word in inputSet: 34 #如果词条在词条列表中出现 35 if word in vocabSet: 36 #通过列表获取当前word的索引(下标) 37 #将词条向量中的对应下标的项由0改为1 38 returnVec[vocabSet.index(word)]=1 39 else: print('the word: %s is not in my vocabulary! '%'word') 40 #返回inputet转化后的词条向量 41 return returnVec 42 43 trainMatrix = [setOfWords2Vec(vocabSet,inputSet) for inputSet in postingList] 44 45 46 #训练算法,从词向量计算概率p(w0|ci)...及p(ci) 47 #@trainMatrix:由每篇文档的词条向量组成的文档矩阵 48 #@trainCategory:每篇文档的类标签组成的向量 49 def trainNB0(trainMatrix,trainCategory): 50 #获取文档矩阵中文档的数目 51 numTrainDocs=len(trainMatrix) 52 #获取词条向量的长度 53 numWords=len(trainMatrix[0]) 54 #所有文档中属于类1所占的比例p(c=1) 55 pAbusive=sum(trainCategory)/float(numTrainDocs) 56 #创建一个长度为词条向量等长的列表 57 p0Num=zeros(numWords) #ham 58 p1Num=zeros(numWords) #spam 59 p0Denom=0.0 60 p1Denom=0.0 61 #遍历每一篇文档的词条向量 62 for i in range(numTrainDocs): 63 #如果该词条向量对应的标签为1 64 if trainCategory[i]==1: 65 #统计所有类别为1的词条向量中各个词条出现的次数 66 p1Num+=trainMatrix[i] 67 #统计类别为1的词条向量中出现的所有词条的总数 68 #即统计类1所有文档中出现单词的数目 69 p1Denom+=sum(trainMatrix[i]) 70 else: 71 #统计所有类别为0的词条向量中各个词条出现的次数 72 p0Num+=trainMatrix[i] 73 #统计类别为0的词条向量中出现的所有词条的总数 74 #即统计类0所有文档中出现单词的数目 75 p0Denom+=sum(trainMatrix[i]) 76 print(p1Num, p1Denom, p0Num,p0Denom ) 77 #利用NumPy数组计算p(wi|c1) 78 p1Vect=p1Num/p1Denom #为避免下溢出问题,需要改为log() 79 #利用NumPy数组计算p(wi|c0) 80 p0Vect=p0Num/p0Denom #为避免下溢出问题,需要改为log() 81 return p0Vect,p1Vect,pAbusive 82 83 p0Vect,p1Vect,pAbusive= trainNB0(trainMatrix,classVec) 84 85 86 #朴素贝叶斯分类函数 87 #@vec2Classify:待测试分类的词条向量 88 #@p0Vec:类别0所有文档中各个词条出现的频数p(wi|c0) 89 #@p0Vec:类别1所有文档中各个词条出现的频数p(wi|c1) 90 #@pClass1:类别为1的文档占文档总数比例 91 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): 92 #根据朴素贝叶斯分类函数分别计算待分类文档属于类1和类0的概率 93 p1=sum(vec2Classify*p1Vec)+log(pClass1) 94 p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1) 95 if p1>p0: 96 return 'spam' 97 else: 98 return 'not spam' 99 100 101 102 testEntry=['love','my','job'] 103 thisDoc=array(setOfWords2Vec(vocabSet,testEntry)) 104 print(testEntry,'classified as:',classifyNB(thisDoc,p0Vect,p1Vect,pAbusive))