機器學習實戰-基於概率論的分類方法:
條件概率:
如果各個特徵屬性是條件獨立的,則根據貝葉斯定理有如下推導:
計算條件概率的方法:貝葉斯準則
可以交換條件概率中的條件與結果
使用條件概率來分類:
規則:
- 如果p1(x,y) > p2(x,y),那麼屬於類別1
- 如果p1(x,y) < p2(x,y),那麼屬於類別2
使用貝葉斯準則,可以通過已知的三個概率值來計算未知的概率值。
使用樸素貝葉斯進行文件分類:
樸素貝葉斯是貝葉斯分類器的一個拓展,是用於文件分類的常用演算法。
我們可以觀察文件中出現的詞,並把每個詞的出現或者不出現作為一個特徵,這樣得到的特徵數目就會跟詞彙表中的詞目一樣多。
樸素貝葉斯的一般過程:
- 收集資料:可以使用任何方法
- 準備資料:數字型或布林型
- 分析資料:有大量特徵時,繪製特徵作用不大,此時使用直方圖效果更好
- 訓練演算法:計算不同的獨立特徵的條件概率
- 測試演算法:計算錯誤率
- 使用演算法:可以在任意的分類場景中使用樸素貝葉斯分類器,不一定非要是文字
樣本數:
由統計學知,如果每個特徵需要N個樣本,那麼對於10個特徵將需要N^10 個樣本,對於包含1000個特徵的詞彙表將需要N^1000 個樣本。
所需要的樣本數會隨著特徵數目增大而迅速增長。
如果特徵之間相互獨立,那麼樣本數就可以從N^1000 個樣本減少到1000N。
所謂獨立(independence)指的是統計意義上的獨立,即一個特徵或者單詞出現的可能性與它和其他單詞相鄰沒有關係。
兩個假設:
- 樸素(naive)的含義:特徵之間獨立
- 每個特徵同等重要
使用python進行文字分類:
要從文字中獲取特徵,需要先拆分文字。
每一個文字片段表示為一個詞條向量,1表示詞條出現在文件中,0表示詞條未出現
- 特徵:來自文字的詞條(token)
- 一個詞條是字元的任意組合
- 詞條可以為單詞,也可以為非單詞(如URL、ip地址等)
準備資料:從文字中構建詞向量
'''
詞表到向量的轉換函式
'''
# 建立了一些實驗樣本
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 1為侮辱性文字
return postingList,classVec
def createVocabList(dataSet):
vocabSet = set([]) #create empty set
for document in dataSet:
vocabSet = vocabSet | set(document) #union of the two sets 建立並集,即獲得一個去重詞彙列表
return list(vocabSet)
def setOfWords2Vec(vocabList, inputSet): # vocabList詞彙表,inputSet需要檢查的所有單詞
returnVec = [0]*len(vocabList) # 與詞彙表相同的0值列表
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] = 1 # 如果需要檢查的單詞列表出現在vocabList詞彙表中,0值列表對應的位置設為1
else: print "the word: %s is not in my Vocabulary!" % word
return returnVec
if __name__ == '__main__':
postingList, classVec = loadDataSet()
print postingList
print '---------'
print classVec
print '---------'
myVocabList = createVocabList(postingList)
print myVocabList
print '--------'
print setOfWords2Vec(myVocabList, postingList[0])
# [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1]
訓練演算法:從詞向量到計算概率
重寫貝葉斯準則,將之前的 x, y 替換為 w. 粗體的 w 表示這是一個向量,即它由多個值組成。
在這個例子中,數值個數與詞彙表中的詞個數相同。
我們使用上述公式,對每個類計算該值,然後比較這兩個概率值的大小。
計算p(ci):
- 首先可以通過類別 i (侮辱性留言或者非侮辱性留言)中的文件數除以總的文件數來計算概率 p(ci) 。
計算 p(w | ci):
樸素貝葉斯假設。
如果將 w 展開為一個個獨立特徵,那麼就可以將上述概率寫作 p(w0, w1, w2…wn | ci) 。
這裡假設所有詞都互相獨立,該假設也稱作條件獨立性假設(例如 A 和 B 兩個人拋骰子,概率是互不影響的,也就是相互獨立的,A 拋 2點的同時 B 拋 3 點的概率就是 1/6 * 1/6),
它意味著可以使用 p(w0 | ci)p(w1 | ci)p(w2 | ci)…p(wn | ci) 來計算上述概率,這樣就極大地簡化了計算的過程。
from numpy import *
from machinelearninginaction.Ch04.bayes import loadDataSet,createVocabList,setOfWords2Vec
def trainNB0(trainMatrix,trainCategory): #trainMatrix文件矩陣,trainCategory每篇文件類別標籤所構成的向量
numTrainDocs = len(trainMatrix) # 訓練樣本集長度
numWords = len(trainMatrix[0]) # 每個樣本的詞數量
pAbusive = sum(trainCategory)/float(numTrainDocs) # 計算文件屬於侮辱性文件的概率
p0Num = zeros(numWords); p1Num = zeros(numWords) # 初始化分子
p0Denom = 0.0; p1Denom = 0.0 # 初始化分母
for i in range(numTrainDocs): # 對每篇訓練文件
if trainCategory[i] == 1: # 詞向量值為1 -> 侮辱性
p1Num += trainMatrix[i] # 矩陣,對應位置,出現侮辱性詞條 累加矩陣
p1Denom += sum(trainMatrix[i]) # 計算所有侮辱性詞條的總數
else: # 詞向量值為0 -> 非侮辱性
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = p1Num/p1Denom #change to log() 詞彙表對應位置上有侮辱性詞條的出現的總數 除以 總詞條數目得到條件概率 = 詞彙表每個位置上出現侮辱性詞條的概率
p0Vect = p0Num/p0Denom #change to log()
return p0Vect,p1Vect,pAbusive
# p0Vect 非侮辱性詞語在詞彙表每個位置出現的條件概率
if __name__ == '__main__':
postingList, classVec = loadDataSet()
myVocabList = createVocabList(postingList) # 獲得一個去重的詞彙表
trainMat = []
for postinDodc in postingList:
trainMat.append(setOfWords2Vec(myVocabList,postinDodc))
print 'trainMat: '
print trainMat
print '----------'
p0V,p1V,pAb = trainNB0(trainMat,classVec)
print p0V
print '---------'
print p1V
print '---------'
print pAb
p0Num :
- 矩陣,對應位置,出現非侮辱性詞條的話,則累加起來。
- 最後每個位置的數字為該位置(某個單詞)出現過多少次非侮辱性詞條
p0Denom:
- 侮辱性詞條的總數
p0Vect = p0Num/p0Denom
- 計算:詞彙表每個位置上出現侮辱性詞條的概率
測試演算法:根據現實情況修改分類器
在利用貝葉斯分類器對文件進行分類時,要計算多個概率的乘積以獲得文件屬於某個類別的概率,即計算 p(w0|1) * p(w1|1) * p(w2|1)。如果其中一個概率值為 0,那麼最後的乘積也為 0。
為降低這種影響,可以將所有詞的出現數初始化為 1,並將分母初始化為 2 (取1 或 2 的目的主要是為了保證分子和分母不為0,大家可以根據業務需求進行更改)。
另一個遇到的問題是下溢位,這是由於太多很小的數相乘造成的。當計算乘積 p(w0|ci) * p(w1|ci) * p(w2|ci)… p(wn|ci) 時,由於大部分因子都非常小,所以程式會下溢位或者得到不正確的答案。(用 Python 嘗試相乘許多很小的數,最後四捨五入後會得到 0)。一種解決辦法是對乘積取自然對數。在代數中有 ln(a * b) = ln(a) + ln(b), 於是通過求對數可以避免下溢位或者浮點數舍入導致的錯誤。同時,採用自然對數進行處理不會有任何損失。
下圖給出了函式 f(x) 與 ln(f(x)) 的曲線。可以看出,它們在相同區域內同時增加或者減少,並且在相同點上取到極值。它們的取值雖然不同,但不影響最終結果。
from numpy import *
from machinelearninginaction.Ch04.bayes import loadDataSet,createVocabList,setOfWords2Vec
def trainNB0(trainMatrix, trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory) / float(numTrainDocs)
p0Num = ones(numWords)
p1Num = ones(numWords) # change to ones()
p0Denom = 2.0
p1Denom = 2.0 # change to 2.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = log(p1Num / p1Denom) # change to log()
p0Vect = log(p0Num / p0Denom) # change to log()
return p0Vect, p1Vect, pAbusive
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): # p0Vec非侮辱性的條件概率、p1Vec侮辱性的條件概率, pClass1侮辱性文件的概率
temp = vec2Classify * p1Vec
temp1 = sum(vec2Classify * p1Vec)
p1 = sum(vec2Classify * p1Vec) + log(pClass1) # element-wise mult
# 測試向量矩陣 * p1條件概率矩陣 * pClass1侮辱性文件的概率
print '\n'
print 'p1: ' + str(p1)
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
print 'p0: ' + str(p0)
if p1 > p0:
return 1
else:
return 0
def testingNB():
listOPosts, listClasses = loadDataSet()
myVocabList = createVocabList(listOPosts)
trainMat = []
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
testEntry = ['love', 'my', 'dalmation']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print thisDoc
print '--------'
print testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb)
testEntry = ['stupid', 'garbage']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb)
if __name__ == '__main__':
testingNB()
準備資料:文件詞袋模型
我們將每個詞的出現與否作為一個特徵,這可以被描述為 詞集模型(set-of-words model)。
如果一個詞在文件中出現不止一次,這可能意味著包含該詞是否出現在文件中所不能表達的某種資訊,這種方法被稱為 詞袋模型(bag-of-words model)。
- 詞袋中,每個單詞可以出現多次,
- 而在詞集中,每個詞只能出現一次。
為適應詞袋模型,需要對函式 setOfWords2Vec() 稍加修改,修改後的函式為 bagOfWords2Vec() 。
如下給出了基於詞袋模型的樸素貝葉斯程式碼。它與函式 setOfWords2Vec() 幾乎完全相同,唯一不同的是每當遇到一個單詞時,它會增加詞向量中的對應值,而不只是將對應的數值設為 1 。
示例1:使用樸素貝葉斯過濾垃圾郵件
步驟:
- (1)收集資料:提供文字檔案。
- (2)準備資料:將文字檔案解析成詞條向量。
- (3)分析資料:檢查詞條確保解析的正確性。
- (4)訓練演算法:使用我們之前建立的trainNBO()函式。
- (5)測試演算法:使用classifyNB(),並且構建一個新的測試函式來計算文件集的錯誤率。
- (6)使用演算法:構建一個完整的程式對一組文件進行分類,將錯分的文件輸出到螢幕上。
準備資料:切分文字
測試演算法:使用樸素貝葉斯進行交叉驗證
隨機選擇資料的一部分作為訓練集,而剩餘部分作為測試集的過程稱為留存交叉驗證(hold-out cross validaiton)
示例2:使用樸素貝葉斯分類器從個人廣告中獲取區域傾向
使用樸素貝葉斯來發現地域相關的用詞
- (1)收集資料:從RSS源收集內容,這裡需要對RSS源構建一個介面。
- (2)準備資料:將文字檔案解析成詞條向量。
- (3)分析資料:檢查詞條確保解析的正確性。
- (4)訓練演算法:使用我們之前建立的trainNBO()函式。
- (5)測試演算法:觀察錯誤率,確保分類器可用。可以修改切分程式,以降低錯誤率,提高
分類結果。 - (6)使用演算法:構建一個完整的程式,封裝所有內容。給定兩個RSS源,該程式會顯示最
常用的公共詞。
參考:
相關推薦
機器學習實戰——基於概率論的分類方法:樸素貝葉斯(二)
使用貝葉斯過濾垃圾郵件 1.準備資料:切分文字 將字串切分為詞列表時,倘若沒有split引數,則標點符號也會被當成詞的一部分,可以使用正則表示式來切分句子,其中分隔符是除了單詞,數字之外的任意字串
機器學習實戰-基於概率論的分類方法:
條件概率: 如果各個特徵屬性是條件獨立的,則根據貝葉斯定理有如下推導: 計算條件概率的方法:貝葉斯準則 可以交換條件概率中的條件與結果 使用條件概率來分類: 規則: 如果p1(x,y) > p2(x,y),那麼屬於類別1
機器學習(3):基於概率論的分類方法:樸素貝葉斯
概述 優點:在資料較少的情況下仍然有效,可以處理多類別問題。 缺點:對於輸入資料的準備方式較為敏感。 使用資料型別:標稱型資料。 貝葉斯決策理論的核心思想:選擇具有最高概率的決策。 使用條件概率來分類 對於某個資料點x,y: 如果,那麼屬於類別 如果,那麼屬於類
機器學習實戰教程(五):樸素貝葉斯實戰篇之新浪新聞分類
原文連結: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_5_bayes_2.html 一、前言 上篇文章機器學習實戰教程(四):樸素貝葉斯基礎篇之言論過濾器講解了樸素貝葉斯的基礎知識。本篇文章將在此基礎上進行擴充套件,你將看到以下內容: 拉普拉
機器學習實戰教程(一):線性回歸基礎篇(上)
學習 reg style spa 目標 pub auto 機器 輸入 一 什麽是回歸? 回歸的目的是預測數值型的目標值,最直接的辦法是依據輸入,寫入一個目標值的計算公式。 假如你想預測小姐姐男友汽車的功率,可能會這麽計算: Ho
機器學習實戰——預測數值型資料:迴歸 實現記錄
關於利用資料集繪圖建立模型 >>> import regression >>> xArr, yArr= regression.loadDataSet('ex0.txt') >>> ws= regression.standRegres(xAr
分享《機器學習實戰基於Scikit-Learn和TensorFlow》中英文PDF原始碼+《深度學習之TensorFlow入門原理與進階實戰》PDF+原始碼
下載:https://pan.baidu.com/s/1qKaDd9PSUUGbBQNB3tkDzw 《機器學習實戰:基於Scikit-Learn和TensorFlow》高清中文版PDF+高清英文版PDF+原始碼 下載:https://pan.baidu.com/s/1IAfr-tigqGE_njrfSA
《機器學習實戰》第五章:Logistic迴歸(1)基本概念和簡單例項
最近感覺時間越來越寶貴,越來越不夠用。不過還是抽空看了點書,然後整理到部落格來。 加快點節奏,廢話少說。 Keep calm & carry on. ----------------------------------------------------------
機器學習實戰教程(三):決策樹實戰篇之為自己配個隱形眼鏡
原文連結:cuijiahua.com/blog/2017/1… 一、前言 上篇文章機器學習實戰教程(二):決策樹基礎篇之讓我們從相親說起講述了機器學習決策樹的原理,以及如何選擇最優特徵作為分類特徵。本篇文章將在此基礎上進行介紹。主要包括: 決策樹構建 決策樹視覺化 使用決
機器學習實戰系列(五):SVM支援向量機
課程的所有資料和程式碼在我的Github:Machine learning in Action,目前剛開始做,有不對的歡迎指正,也歡迎大家star。除了 版本差異,程式碼裡的部分函式以及程式碼正規化也和原書不一樣(因為作者的程式碼實在讓人看的彆扭,我改過後看起來舒服多了)
《機器學習實戰》讀書筆記2:K-近鄰(kNN)演算法 & 原始碼分析
宣告:文章是讀書筆記,所以必然有大部分內容出自《機器學習實戰》。外加個人的理解,另外修改了部分程式碼,並添加了註釋 1、什麼是K-近鄰演算法? 簡單地說,k-近鄰演算法採用測量不同特徵值之間距離的方法進行分類。不恰當但是形象地可以表述為近朱者赤,近墨者黑
機器學習實戰教程(四):樸素貝葉斯基礎篇之言論過濾器
word 最可 dog 一個 mac github上 開課 和數 基礎上 原文鏈接: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_4_bayes_1.html 一、前言 樸素貝葉斯算法是有監督的學習算法,解決的是分類問題,
機器學習中常見的優化方法:梯度下降法、牛頓法擬牛頓法、共軛梯度法、拉格朗日乘數法
機器學習中常見的優化方法: 梯度下降法、牛頓法擬牛頓法、共軛梯度法、拉格朗日乘數法 主要內容 梯度下降法 牛頓法擬牛頓法 共軛梯度法 拉格朗日乘數法 許多機器學習演算法,往往建立目標函式(損失函式+正則項),通過優化方法進行優化,根據訓練
《機器學習實戰》第三章:決策樹(1)基本概念
有半個月沒來了。 最近一段時間...大多在忙專案組的事(其實就是改一改現有程式碼的bug,不過也挺費勁的,畢竟程式碼不是自己寫的)。另外就是自己租了幾臺美帝的vps,搭了$-$的伺服器 ,效果還不錯。自己搭的話就不用去買別人的服務了,不過租vps畢竟還是要成本的,光用來番茄
【機器學習實戰】—KNN分類演算法
一、KNN演算法概述 kNN分類演算法本身簡單有效,既可以分類又可以進行迴歸。 核心原理:已知樣本資料集的每一個數據的特徵和所屬的分類,將新資料的特徵與樣本資料進行比較,找到最相似(最近鄰)的K(k
機器學習實戰之KNN分類演算法
示例:使用KNN改進約會網站配對效果(學習這一節把自己需要注意的和理解的記錄下來) 第零步:實現KNN演算法: 需注意: classCount[voteIlabel] = classCount.get(voteIlabel,0)+1 #Python 字典(
機器學習實戰基礎篇——分類篇
機器學習裡面最重要的兩類任務:分類(classification)與迴歸(regression)。我學習的這本書名叫《Python機器學習及實踐——從零開始通往Kaggle競賽之路》,清華大學出版社。這本書裡在基礎篇對演算法的原理沒有進行太多的論述,而是如書名所述,偏重實踐。
【機器學習實戰—第4章:基於概率論的分類方法:樸素貝葉斯】程式碼報錯(python3)
1、報錯:UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xae in position 199: illegal multibyte sequence 原因:這是檔案編碼的問題,檔案中有非法的多位元組字元。 解決辦法:開啟Ch04\
分享《機器學習實戰:基於Scikit-Learn和TensorFlow》高清中英文PDF+原始碼
下載:https://pan.baidu.com/s/1kNN4tDt58ckFoD_OWH5sGw 更多資料分享:http://blog.51cto.com/3215120 《機器學習實戰:基於Scikit-Learn和TensorFlow》高清中文版PDF+高清英文版PDF+原始碼 高清中文版PDF
分享《機器學習實戰:基於Scikit-Learn和TensorFlow》高清中英文PDF+源代碼
ESS alt mark 構建 image 機器學習實戰 dff com 化學 下載:https://pan.baidu.com/s/1kNN4tDt58ckFoD_OWH5sGw 更多資料分享:http://blog.51cto.com/3215120 《機器學習實戰:基