樸素貝葉斯文本分類(詳解)
阿新 • • 發佈:2018-05-08
詞向量 列表 出現 下標 put The 標註 問題 else
from numpy import zeros,array from math import log def loadDataSet(): #詞條切分後的文檔集合,列表每一行代表一個email postingList=[[‘your‘,‘mobile‘,‘number‘,‘is‘,‘award‘,‘bonus‘,‘prize‘], [‘new‘,‘car‘,‘and‘,‘house‘,‘for‘,‘my‘,‘parents‘], [‘my‘,‘dalmation‘,‘is‘,‘so‘,‘cute‘,‘I‘,‘love‘,‘him‘], [‘today‘,‘voda‘,‘number‘,‘prize‘, ‘receive‘,‘award‘], [‘get‘,‘new‘,‘job‘,‘in‘,‘company‘,‘how‘,‘to‘,‘get‘,‘that‘], [‘free‘,‘prize‘,‘buy‘,‘winner‘,‘receive‘,‘cash‘]] #由人工標註的每篇文檔的類標簽 classVec=[1,0,0,1,0,1] #1-spam, 0-ham return postingList,classVec postingList,classVec = loadDataSet() #統計所有文檔中出現的詞條列表 def createVocabList(dataSet): vocabSet=set([]) #遍歷文檔集合中的每一篇文檔 for document in dataSet: vocabSet=vocabSet|set(document) return list(vocabSet) vocabSet = createVocabList(postingList) #根據詞條列表中的詞條是否在文檔中出現(出現1,未出現0),將文檔轉化為詞條向量 def setOfWords2Vec(vocabSet,inputSet): #新建一個長度為vocabSet的列表,並且各維度元素初始化為0 returnVec=[0]*len(vocabSet) #遍歷文檔中的每一個詞條 for word in inputSet: #如果詞條在詞條列表中出現 if word in vocabSet: #通過列表獲取當前word的索引(下標) #將詞條向量中的對應下標的項由0改為1 returnVec[vocabSet.index(word)]=1 else: print(‘the word: %s is not in my vocabulary! ‘%‘word‘) #返回inputet轉化後的詞條向量 return returnVec trainMatrix = [setOfWords2Vec(vocabSet,inputSet) for inputSet in postingList] #訓練算法,從詞向量計算概率p(w0|ci)...及p(ci) #@trainMatrix:由每篇文檔的詞條向量組成的文檔矩陣 #@trainCategory:每篇文檔的類標簽組成的向量 def trainNB0(trainMatrix,trainCategory): #獲取文檔矩陣中文檔的數目 numTrainDocs=len(trainMatrix) #獲取詞條向量的長度 numWords=len(trainMatrix[0]) #所有文檔中屬於類1所占的比例p(c=1) pAbusive=sum(trainCategory)/float(numTrainDocs) #創建一個長度為詞條向量等長的列表 p0Num=zeros(numWords) #ham p1Num=zeros(numWords) #spam p0Denom=0.0 p1Denom=0.0 #遍歷每一篇文檔的詞條向量 for i in range(numTrainDocs): #如果該詞條向量對應的標簽為1 if trainCategory[i]==1: #統計所有類別為1的詞條向量中各個詞條出現的次數 p1Num+=trainMatrix[i] #統計類別為1的詞條向量中出現的所有詞條的總數 #即統計類1所有文檔中出現單詞的數目 p1Denom+=sum(trainMatrix[i]) else: #統計所有類別為0的詞條向量中各個詞條出現的次數 p0Num+=trainMatrix[i] #統計類別為0的詞條向量中出現的所有詞條的總數 #即統計類0所有文檔中出現單詞的數目 p0Denom+=sum(trainMatrix[i]) print(p1Num, p1Denom, p0Num,p0Denom ) #利用NumPy數組計算p(wi|c1) p1Vect=p1Num/p1Denom #為避免下溢出問題,需要改為log() #利用NumPy數組計算p(wi|c0) p0Vect=p0Num/p0Denom #為避免下溢出問題,需要改為log() return p0Vect,p1Vect,pAbusive p0Vect,p1Vect,pAbusive= trainNB0(trainMatrix,classVec) #樸素貝葉斯分類函數 #@vec2Classify:待測試分類的詞條向量 #@p0Vec:類別0所有文檔中各個詞條出現的頻數p(wi|c0) #@p0Vec:類別1所有文檔中各個詞條出現的頻數p(wi|c1) #@pClass1:類別為1的文檔占文檔總數比例 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #根據樸素貝葉斯分類函數分別計算待分類文檔屬於類1和類0的概率 p1=sum(vec2Classify*p1Vec)+log(pClass1) p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1) if p1>p0: return ‘spam‘ else: return ‘not spam‘ testEntry=[‘love‘,‘my‘,‘job‘] thisDoc=array(setOfWords2Vec(vocabSet,testEntry)) print(testEntry,‘classified as:‘,classifyNB(thisDoc,p0Vect,p1Vect,pAbusive))
樸素貝葉斯文本分類(詳解)