日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

监督学习 | 朴素贝叶斯原理及Python实现

發布時間:2025/3/15 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 监督学习 | 朴素贝叶斯原理及Python实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1. 貝葉斯理論
    • 1.1 貝葉斯定理
    • 1.2 貝葉斯分類算法
    • 1.3 樸素貝葉斯分類算法
      • 1.3.1 樸素貝葉斯分類器實例
        • 學習過程
        • 預測過程
  • 2. Python實現
    • 2.1 拉普拉斯修正
    • 2.2 對數變換
  • 參考資料

相關文章:

機器學習 | 目錄

監督學習 | 樸素貝葉斯Sklearn實現

1. 貝葉斯理論

1.1 貝葉斯定理

貝葉斯定理旨在計算P(A∣B)P(A|B)P(AB)的值,也就是在已知B發生的條件下,A發生的概率是多少。大多數情況下,B是被觀察事件,比如“昨天下雨了”,A為預測結果“今天會下雨”。[1]

對數據挖掘來說,B通常通常是樣本個數,A為被預測個體所屬類別

貝葉斯定理公式入下:

P(A∣B)=P(B∣A)P(A)P(B)(1)P(A|B)=\frac{P(B|A)P(A)}{P(B)} \tag{1} P(AB)=P(B)P(BA)P(A)?(1)

舉例說明:我們想計算含有單詞money的郵件為垃圾郵件的概率。

  • P(A):在這里,A為“這是封垃圾郵件”。我們可以通過統計訓練集中垃圾郵件的比例,得到先驗概率(prior probability):P(A)P(A)P(A),如果我們的數據集每100封郵件有30封垃圾郵件,則P(A)=0.3P(A)=0.3P(A)=0.3

  • P(B):B表示“該郵件含有單詞money”。類似地,我們通過計算數據集中含有單詞money的郵件比例得到P(B)P(B)P(B)。如果每100封郵件中有10封郵件包含單詞money,則P(B)=0.1P(B)=0.1P(B)=0.1。計算P(B)P(B)P(B)時,我們不關注郵件是不是垃圾郵件。

  • P(B|A):指的是垃圾郵件中含有單詞money的概率,通過統計訓練集中所有垃圾郵件的數量以及其中含有單詞money的數量。30封垃圾郵件中,如果有6封含有單詞money,那么P(B∣A)=0.2P(B|A)=0.2P(BA)=0.2

  • P(A|B):因此可計算P(A∣B)=P(B∣A)P(A)P(B)=0.2×0.30.1=0.6P(A|B)=\frac{P(B|A)P(A)}{P(B)}=\frac{0.2\times 0.3}{0.1}=0.6P(AB)=P(B)P(BA)P(A)?=0.10.2×0.3?=0.6,即含有單詞money的郵件為垃圾郵件的概率為60%。

1.2 貝葉斯分類算法

貝葉斯分類算法,就是利用貝葉斯定理對數據進行分類。

其基本表達式為:

其中:
P(X=x∣Y=ck)P(Y=ck)=P(x(1),x(2),...,x(m)∣Y=ck),k=1,2,...,n(4)P(X=x|Y=c_k)P(Y=c_k)=P(x^{(1)}, x^{(2)},..., x^{(m)}|Y=c_k), k=1,2,...,n \tag{4}P(X=xY=ck?)P(Y=ck?)=P(x(1),x(2),...,x(m)Y=ck?),k=1,2,...,n(4)

1.3 樸素貝葉斯分類算法

對于貝葉斯算法,其適用于只用一個特征的分類。當有多個特征時,由于特征之間不獨立,因此P(X=x∣Y=ck)P(X=x|Y=c_k)P(X=xY=ck?)的計算非常復雜,假設xxx的第jjj特征x(j)x^{(j)}x(j)可取的值有SjS_jSj?個,YYY可取的值有nnn個,那么要計算的參數個數為n×∏j=1mSjn\times \prod_{j=1}^mS_jn×j=1m?Sj?,對這樣指數量級的參數進行估計是不實際的,所有有了樸素貝葉斯中的獨立性假設。[2]

樸素貝葉斯算法在貝葉斯算法的基礎上,多了兩個默認的前提條件:

  • 各個特征之間相互獨立
  • 各個特征同等重要
  • 由獨立性假設:

    在獨立性假設下,將原本指數級的n×∏j=1mSjn\times \prod_{j=1}^mS_jn×j=1m?Sj?個變為常數級的nSjnS_jnSj?個。

    由此有:

    注意到,分母對于所有ckc_kck?都是相同的。

    因此得到樸素貝葉斯算法的基本表達式:

    1.3.1 樸素貝葉斯分類器實例

    預測某人是否拖欠貸款(Y:c1=yes,c2=noY: {c_1=yes,c_2=no}Y:c1?=yes,c2?=no)

    x(1)x^{(1)}x(1)有房x(2)x^{(2)}x(2)年收入YYY拖欠
    125kno
    100kno
    70kno
    120kno
    95kyes
    60kno
    220kno
    85kyes
    75kno
    90kyes

    學習過程

    • 計算先驗分布:

      P(Y=yes)=310P(Y=yes)= \frac{3}{10}P(Y=yes)=103?P(Y=no)=710P(Y=no)= \frac{7}{10}P(Y=no)=107?

    • 對于x(1)x^{(1)}x(1)有房,計算條件分布:

      P(有房=是∣Y=yes)=0P(有房 = 是 |Y=yes)= 0P(=Y=yes)=0P(有房=是∣Y=no)=37P(有房=是|Y=no)= \frac{3}{7}P(=Y=no)=73?

      P(有房=否∣Y=yes)=1P(有房 = 否 |Y=yes)= 1P(=Y=yes)=1P(有房=否∣Y=no)=47P(有房=否|Y=no)= \frac{4}{7}P(=Y=no)=74?

    • 對于x(2)x^{(2)}x(2)收入,計算條件分布:
      年收入可視為連續值,在此先離散化,后計算概率:
      低:年收入≤90k,中:年收入≤150k,高:年收入≥150k{低:年收入 \leq 90k,中:年收入 \leq 150k,高:年收入 \ge 150k}90k150k150k

      P(年收入=高∣Y=yes)=0P(年收入 = 高 |Y=yes)= 0P(=Y=yes)=0P(年收入=高∣Y=no)=17P(年收入 = 高|Y=no)= \frac{1}{7}P(=Y=no)=71?

      P(年收入=中∣Y=yes)=13P(年收入 = 中 |Y=yes)= \frac{1}{3}P(=Y=yes)=31?P(年收入=中∣Y=no)=37P(年收入 = 中|Y=no)= \frac{3}{7}P(=Y=no)=73?

      P(年收入=低∣Y=yes)=12P(年收入 = 低 |Y=yes)= \frac{1}{2}P(=Y=yes)=21?P(年收入=低∣Y=no)=37P(年收入 = 低|Y=no)= \frac{3}{7}P(=Y=no)=73?

    預測過程

    假設預測樣本x?=有房=否,年收入=110kx_*={有房=否,年收入=110k}x??===110k,預測x?x_*x??是否有可能拖欠貸款

    根據模型表達式:y=argmax?ckP(Y=ck)∏j=1mP(X(j)=x(j)∣Y=ck)y = arg \max \limits_{c_k} P(Y=c_k) \prod_{j=1}^mP(X^{(j)}=x^{(j)}|Y=c_k)y=argck?max?P(Y=ck?)j=1m?P(X(j)=x(j)Y=ck?)

    • 計算:

      P(Y=no∣X=x?)=P(Y=no)P(有房=否∣Y=no)P(年收入=中∣Y=no)=710×47×37=1270P(Y=no|X=x_*)=P(Y=no)P(有房=否|Y=no)P(年收入=中|Y=no)= \frac{7}{10} \times \frac{4}{7} \times \frac{3}{7}= \frac{12}{70}P(Y=noX=x??)=P(Y=no)P(=Y=no)P(=Y=no)=107?×74?×73?=7012?

      P(Y=yes∣X=x?)=P(Y=yes)P(有房=否∣Y=yes)P(年收入=中∣Y=yes)=310×1×13=770P(Y=yes|X=x_*)=P(Y=yes)P(有房=否|Y=yes)P(年收入=中|Y=yes)= \frac{3}{10} \times 1 \times \frac{1}{3}= \frac{7}{70}P(Y=yesX=x??)=P(Y=yes)P(=Y=yes)P(=Y=yes)=103?×1×31?=707?

      因此y=argmax?ck{P(Y=no∣X=x?),P(Y=yes∣X=x?)}=1270y = arg \max \limits_{c_k} \{P(Y=no|X=x_*), P(Y=yes|X=x_*)\} = \frac{12}{70}y=argck?max?{P(Y=noX=x??),P(Y=yesX=x??)}=7012?

      所以x?x_*x??的類別為no,即不會拖欠貸款。

    • P(Y=no∣X=x?),P(Y=yes∣X=x?)P(Y=no|X=x_*), P(Y=yes|X=x_*)P(Y=noX=x??),P(Y=yesX=x??) 和并不等于1,這是因為計算過程省略了分母P(X=x)P(X=x)P(X=x)

      歸一化后各自概率為:

      P(Y=no∣X=x?)=63.16%P(Y=no|X=x_*)=63.16 \%P(Y=noX=x??)=63.16%

      P(Y=yes∣X=x?)=36.84%P(Y=yes|X=x_*)=36.84 \%P(Y=yesX=x??)=36.84%

      即有63.16%的概率認為x?x_*x??的類別為no,不會拖欠貸款。

    2. Python實現

    2.1 拉普拉斯修正

    • 為什么需要修正:因為我們的樣本集有限,對于某些離散的值可能并沒有出現,這樣會導致概率的乘積為0,影響最終分類結果。

    • 拉普拉斯修正法:對于一個離散的值,我們在使用的時候不是直接輸出它的概率,而是對概率值進行“平滑”處理。即默認所有特征都出現過一次,將概率該為下面的形式:

      P(c)=∣Dc∣+1∣D∣+N(9)P(c)= \frac{|D_c|+1}{|D|+N} \tag{9}P(c)=D+NDc?+1?(9)

      P(xi∣c)=∣Dc,xi∣+1∣Dc∣+Ni(10)P(x_i|c)= \frac{|D_{c,x_i}|+1}{|D_c|+N_i} \tag{10}P(xi?c)=Dc?+Ni?Dc,xi??+1?(10)

      其中NNN是全體特征的總數,DDD為這一類的總數目,這就避免了概率值為0的情況。[3]

    但是也沒有特別的利用需要在計數結果上加1,可以使用一個很小的常數 μ\muμ 取代它:

    P(xi∣c)=∣Dc,xi∣+μpxi∣Dc∣+μ(11)P(x_i | c)=\frac{|D_{c,x_i}|+\mu p_{x_i}}{|D_c|+\mu} \tag{11}P(xi?c)=Dc?+μDc,xi??+μpxi???(11)

    其中 μ\muμ 為一個常數,大的 μ\muμ 值說明先驗值時非常重要的,而小的 μ\muμ 值說明先驗值的影響力較小;pxip_{x_i}pxi??xix_ixi? 的先驗概率。

    2.2 對數變換

    由于計算概率時需要對很多歌很小的概率值做乘法,所以有可能出現下溢的情況,所以我們可以對概率的乘積取自然對數,根據自然對數函數的單調性,不會改變最終的大小,同時也防止了下溢出現的問題。

    import numpy as np import math # 使用詞集法進行貝葉斯分類 # 構造數據集,分類是侮辱性 or 非侮辱性 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 createlist (dataset) :vovabset = set ([])for vec in dataset :vovabset = vovabset | set (vec)return list (vovabset) # 將詞條轉化為向量的形式 def changeword2vec (inputdata, wordlist) :returnVec = [0] * len (wordlist)for word in inputdata :if word in wordlist :returnVec[wordlist.index(word)] = 1return returnVec # 創建貝葉斯分類器 def trainNBO (dataset, classlebels) :num_of_sample = len (dataset)num_of_feature = len (dataset[0])pAusuive = sum (classlebels) / num_of_sample # 侮辱性語言的概率p0Num = np.ones (num_of_feature)p1Num = np.ones (num_of_feature)p0tot = num_of_featurep1tot = num_of_featurefor i in range (num_of_sample) :if classlebels[i] == 1 :p1Num += dataset[i]p1tot += sum (dataset[i])else :p0Num += dataset[i]p0tot += sum (dataset[i]) p0Vec = p0Num / p0totp1Vec = p1Num / p1totfor i in range (num_of_feature) :p0Vec[i] = math.log (p0Vec[i])p1Vec[i] = math.log (p1Vec[i])return p0Vec, p1Vec, pAusuive # 定義分類器 def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise multp0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else: return 0 # 測試代碼 dataset,classlebels = loadDataset () wordlist = createlist (dataset) print (wordlist) print (changeword2vec (dataset[0], wordlist)) trainmat = [] for temp in dataset :trainmat.append (changeword2vec (temp,wordlist)) p0V, p1V, pAb = trainNBO (trainmat, classlebels) print (p0V) print (p1V) print (pAb) ['please', 'problems', 'ate', 'is', 'flea', 'maybe', 'love', 'food', 'him', 'take', 'has', 'help', 'my', 'cute', 'stupid', 'dalmation', 'posting', 'worthless', 'steak', 'so', 'licks', 'quit', 'to', 'dog', 'not', 'how', 'park', 'garbage', 'mr', 'stop', 'buying', 'I'] [1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0] [-3.33220451 -3.33220451 -3.33220451 -3.33220451 -3.33220451 -4.02535169-3.33220451 -4.02535169 -2.9267394 -4.02535169 -3.33220451 -3.33220451-2.63905733 -3.33220451 -4.02535169 -3.33220451 -4.02535169 -4.02535169-3.33220451 -3.33220451 -3.33220451 -4.02535169 -3.33220451 -3.33220451-4.02535169 -3.33220451 -4.02535169 -4.02535169 -3.33220451 -3.33220451-4.02535169 -3.33220451] [-3.93182563 -3.93182563 -3.93182563 -3.93182563 -3.93182563 -3.23867845-3.93182563 -3.23867845 -3.23867845 -3.23867845 -3.93182563 -3.93182563-3.93182563 -3.93182563 -2.54553127 -3.93182563 -3.23867845 -2.83321334-3.93182563 -3.93182563 -3.93182563 -3.23867845 -3.23867845 -2.83321334-3.23867845 -3.93182563 -3.23867845 -3.23867845 -3.93182563 -3.23867845-3.23867845 -3.93182563] 0.5

    參考資料

    [1] Robert Layton,杜春曉. Python數據挖掘入門與實踐[M]. 北京: 人民郵電出版社, 2016: 93-103.

    [2] GoWeiXH.機器學習 - 樸素貝葉斯(下)- 樸素貝葉斯分類器[EB/OL].https://blog.csdn.net/weixin_37352167/article/details/84867145, 2018-02-06.

    [3] Glory_g.貝葉斯分類器以及Python實現[EB/OL].https://blog.csdn.net/zhelong3205/article/details/78659169, 2017-11-28.

    總結

    以上是生活随笔為你收集整理的监督学习 | 朴素贝叶斯原理及Python实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。