機器學習實戰---樸素貝葉斯演算法
阿新 • • 發佈:2020-07-06
一:準備資料
(一)載入原始資料
import numpy as np def loadDataSet(): postingList=[['my', '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']] classVec = [0,1,0,1,0,1] #標籤值 1 is abusive, 0 notreturn postingList,classVec
(二)建立詞彙列表 將多個文件單詞歸為一個
def createVocabList(dataSet): #建立詞彙列表 將多個文件單詞歸為一個 VocabSet = set([]) #使用集合,方便去重 for document in dataSet: VocabSet = VocabSet | set(document) #保持同類型 --- 這裡並集導致隨機序列出現,所以在下面進行排序,方便對比。 但是單獨測試得時候並沒有出現隨機現象,多次除錯,結果唯一,這裡每次都不唯一 VocabList= list(VocabSet) VocabList.sort() #列表資料排序 return VocabList
(三)根據我們上面得到的全部詞彙列表,將我們輸入得inputSet文件向量化
def WordSet2Vec(VocaList,inputSet): #根據我們上面得到的全部詞彙列表,將我們輸入得inputSet文件向量化 returnVec = [0]*len(VocaList) for word in inputSet: if word in VocaList: returnVec[VocaList.index(word)] = 1 else: print("the word: %s is not in my Vocabulary!"%word) return returnVec
(四)資料測試
DocData,classVec = loadDataSet() voclist = createVocabList(DocData) print(voclist) print(WordSet2Vec(voclist,DocData[0])) print(WordSet2Vec(voclist,DocData[3]))
二:根據訓練集訓練貝葉斯模型
(一)程式碼實現
def trainNB0(trainMatrix,trainCategory): #訓練樸素貝葉斯模型 傳入numpy陣列型別 trainMatrix所有文件詞彙向量矩陣(m*n矩陣 m個文件,每個文件都是n列,代表詞彙向量大小),trainCategory每篇文件得標籤 numTrainDoc = len(trainMatrix) #文件數量 pC1 = np.sum(trainCategory)/numTrainDoc #p(c1)得概率 p(c0)=1-p(c1) wordVecNum = len(trainMatrix[0]) #因為每個文件轉換為詞彙向量後都是一樣得長度 #初始化p1,p0概率向量 p1VecNum,p0VecNum = np.zeros(wordVecNum),np.zeros(wordVecNum) p1Sum,p0Sum = 0,0 #迴圈每一個文件 for i in range(numTrainDoc): if trainCategory[i] == 1: #侮辱性文件 p1VecNum += trainMatrix[i] #統計侮辱性文件中,每個單詞出現頻率 p1Sum += np.sum(trainMatrix[i]) #統計侮辱性文件中出現得全部單詞數 每個單詞出現概率就是單詞出現頻率/全部單詞 else: #正常文件 p0VecNum += trainMatrix[i] p0Sum += np.sum(trainMatrix[i]) p1Vect = p1VecNum / p1Sum #統計各類文件中的單詞出現頻率 p0Vect = p0VecNum / p0Sum return p1Vect,p0Vect,pC1
DocData,classVec = loadDataSet() voclist = createVocabList(DocData) #獲取全部文件詞彙向量矩陣 trainMulList = [] for doc in DocData: trainMulList.append(WordSet2Vec(voclist,doc)) #將我們需要的詞彙列表和標籤列表轉為numpy.ndarray型別 trainMat = np.array(trainMulList) trainClassVec = np.array(classVec) #獲取訓練模型 p1vec,p0vec,pc1 = trainNB0(trainMat,trainClassVec) print(p1vec) print(p0vec) print(pc1)
(二)全部程式碼
import numpy as np def loadDataSet(): postingList=[['my', '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']] classVec = [0,1,0,1,0,1] #標籤值 1 is abusive, 0 not return postingList,classVec def createVocabList(dataSet): #建立詞彙列表 將多個文件單詞歸為一個 VocabSet = set([]) #使用集合,方便去重 for document in dataSet: VocabSet = VocabSet | set(document) #保持同類型 VocabList = list(VocabSet) VocabList.sort() return VocabList def WordSet2Vec(VocaList,inputSet): #根據我們上面得到的全部詞彙列表,將我們輸入得inputSet文件向量化 returnVec = [0]*len(VocaList) for word in inputSet: if word in VocaList: returnVec[VocaList.index(word)] = 1 else: print("the word: %s is not in my Vocabulary!"%word) return returnVec def trainNB0(trainMatrix,trainCategory): #訓練樸素貝葉斯模型 傳入numpy陣列型別 trainMatrix所有文件詞彙向量矩陣(m*n矩陣 m個文件,每個文件都是n列,代表詞彙向量大小),trainCategory每篇文件得標籤 numTrainDoc = len(trainMatrix) #文件數量 pC1 = np.sum(trainCategory)/numTrainDoc #p(c1)得概率 p(c0)=1-p(c1) wordVecNum = len(trainMatrix[0]) #因為每個文件轉換為詞彙向量後都是一樣得長度 #初始化p1,p0概率向量 p1VecNum,p0VecNum = np.zeros(wordVecNum),np.zeros(wordVecNum) p1Sum,p0Sum = 0,0 #迴圈每一個文件 for i in range(numTrainDoc): if trainCategory[i] == 1: #侮辱性文件 p1VecNum += trainMatrix[i] #統計侮辱性文件中,每個單詞出現頻率 p1Sum += np.sum(trainMatrix[i]) #統計侮辱性文件中出現得全部單詞數 每個單詞出現概率就是單詞出現頻率/全部單詞 else: #正常文件 p0VecNum += trainMatrix[i] p0Sum += np.sum(trainMatrix[i]) p1Vect = p1VecNum / p1Sum #統計各類文件中的單詞出現頻率 p0Vect = p0VecNum / p0Sum return p1Vect,p0Vect,pC1 DocData,classVec = loadDataSet() voclist = createVocabList(DocData) #獲取全部文件詞彙向量矩陣 trainMulList = [] for doc in DocData: trainMulList.append(WordSet2Vec(voclist,doc)) #將我們需要的詞彙列表和標籤列表轉為numpy.ndarray型別 trainMat = np.array(trainMulList) trainClassVec = np.array(classVec) #獲取訓練模型 p1vec,p0vec,pc1 = trainNB0(trainMat,trainClassVec) print(p1vec) print(p0vec) print(pc1)View Code
三:實現預測函式
(一)更新訓練模型函式---拉普拉斯修正和對數防止下溢
def trainNB0(trainMatrix,trainCategory): #訓練樸素貝葉斯模型 傳入numpy陣列型別 trainMatrix所有文件詞彙向量矩陣(m*n矩陣 m個文件,每個文件都是n列,代表詞彙向量大小),trainCategory每篇文件得標籤 numTrainDoc = len(trainMatrix) #文件數量 pC1 = np.sum(trainCategory)/numTrainDoc #p(c1)得概率 p(c0)=1-p(c1) wordVecNum = len(trainMatrix[0]) #因為每個文件轉換為詞彙向量後都是一樣得長度 #初始化p1,p0概率向量---改進為拉普拉斯平滑 p1VecNum,p0VecNum = np.ones(wordVecNum),np.ones(wordVecNum) p1Sum,p0Sum = 2.0,2.0 #N*1 N表示分類數 #迴圈每一個文件 for i in range(numTrainDoc): if trainCategory[i] == 1: #侮辱性文件 p1VecNum += trainMatrix[i] #統計侮辱性文件中,每個單詞出現頻率 p1Sum += np.sum(trainMatrix[i]) #統計侮辱性文件中出現得全部單詞數 每個單詞出現概率就是單詞出現頻率/全部單詞 else: #正常文件 p0VecNum += trainMatrix[i] p0Sum += np.sum(trainMatrix[i]) p1Vect = np.log(p1VecNum / p1Sum) #統計各類文件中的單詞出現頻率 p0Vect = np.log(p0VecNum / p0Sum) #使用對數避免下溢 return p1Vect,p0Vect,pC1
(二)實現預測函式
def classifyNB(testVec,p0Vec,p1Vec,pC1): p1 = sum(testVec*p1Vec)+np.log(pC1) #使用對數之後變為求和 p0 = sum(testVec*p0Vec)+np.log(1-pC1) if p1 > p0: return 1 else: return 0
(三)設定測試集進行預測
DocData,classVec = loadDataSet() voclist = createVocabList(DocData) #獲取全部文件詞彙向量矩陣 trainMulList = [] for doc in DocData: trainMulList.append(WordSet2Vec(voclist,doc)) #將我們需要的詞彙列表和標籤列表轉為numpy.ndarray型別 trainMat = np.array(trainMulList) trainClassVec = np.array(classVec) #獲取訓練模型 p1vec,p0vec,pc1 = trainNB0(trainMat,trainClassVec) #設定測試集進行測試 testEntry01 = ["love","my","dalmation"] VecEntry01 = WordSet2Vec(voclist,testEntry01) clf = classifyNB(VecEntry01,p0vec,p1vec,pc1) print(clf) testEntry02 = ["stupid","garbage"] VecEntry02 = WordSet2Vec(voclist,testEntry02) clf = classifyNB(VecEntry02,p0vec,p1vec,pc1) print(clf)