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))