1. 程式人生 > >機器學習實戰-基於概率論的分類方法:

機器學習實戰-基於概率論的分類方法:

條件概率:

如果各個特徵屬性是條件獨立的,則根據貝葉斯定理有如下推導:

計算條件概率的方法:貝葉斯準則
可以交換條件概率中的條件與結果

使用條件概率來分類:

規則:

  • 如果p1(x,y) > p2(x,y),那麼屬於類別1
  • 如果p1(x,y) < p2(x,y),那麼屬於類別2

使用貝葉斯準則,可以通過已知的三個概率值來計算未知的概率值。

使用樸素貝葉斯進行文件分類:

樸素貝葉斯是貝葉斯分類器的一個拓展,是用於文件分類的常用演算法。

我們可以觀察文件中出現的詞,並把每個詞的出現或者不出現作為一個特徵,這樣得到的特徵數目就會跟詞彙表中的詞目一樣多。

樸素貝葉斯的一般過程:

  1. 收集資料:可以使用任何方法
  2. 準備資料:數字型或布林型
  3. 分析資料:有大量特徵時,繪製特徵作用不大,此時使用直方圖效果更好
  4. 訓練演算法:計算不同的獨立特徵的條件概率
  5. 測試演算法:計算錯誤率
  6. 使用演算法:可以在任意的分類場景中使用樸素貝葉斯分類器,不一定非要是文字

樣本數:

由統計學知,如果每個特徵需要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。除了 版本差異,程式碼裡的部分函式以及程式碼正規化也和原書不一樣(因為作者的程式碼實在讓人看的彆扭,我改過後看起來舒服多了)

機器學習實戰》讀書筆記2K-近鄰(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 《機器學習實戰:基