【机器学习】从一个风控案例讲起-古老而经典的朴素贝叶斯
今天給大家帶來的文章,關于樸素貝葉斯的,一個古老而經典的算法,充分的理解有利于對風控特征或者識別的開拓新的思路。
一、從一個案例講起
假如我們的目標是判斷郵件是否是垃圾郵件,郵件內容是【代開增值稅發票4533224】,那么我們要怎么做呢?
回憶下高中的數學知識,數學原理
貝葉斯公式:?P(Y|X) = P(X|Y) * P(Y) / P(X)
當X條件獨立時:P(X|Y) = P(X1|Y) * P(X2|Y) * ...*P(Xn|Y)
把該公式,應用到我們的風險識別上,可以得到如下的公式
垃圾郵件的概率
正常郵件的概率
到這一步,上面的 ?P(Text="代開增值稅發票4533224") 是算不出來的,我們進一步處理,這樣分母就自己約掉了
于是,我們只要計算分子的值就可以,下面的幾個值,都是可以根據訓練集進行計算的
樣本集中垃圾樣本的比例
P(Y=垃圾)
樣本集中正常樣本的比例
P(Y=正常)
黑樣本集中每個詞的比例然后相乘
P(Text="代開"|Y=垃圾 )
P(Text="增值稅"|Y=垃圾 )
P(Text="發票"|Y=垃圾 )
P(Text="4533224"|Y=垃圾 )
白樣本集中每個詞的比例然后相乘
P(Text="代開"|Y=正常 )
P(Text="增值稅"|Y=正常 )
P(Text="發票"|Y=正常 )
P(Text="4533224"|Y=正常 )
就這樣,我們把公式和實際的應用聯系起來了。并且每個指標都是可以計算的。
當然要計算上面的概率,需要我們有歷史數據,于是我從我的郵箱里面復制了一些垃圾郵件,以及一些正常的郵件,并對數據做了一下簡單的預處理處理,打上了垃圾郵件和正常郵件的標簽,我們就可以得到歷史數據,進行計算了。
首先我們計算垃圾郵件的概率
P(代開|垃圾) ? = 1/5 ?= 0.2
P(增值稅|垃圾)= 1/5 ?= 0.2
P(發票|垃圾) ? = 4/5 = 0.8
P(sep|垃圾) ? ?= 5/5 = 1.0
計算垃圾郵件的概率,一共10個樣本,5個垃圾郵件,5個正常郵件
P(垃圾)= 5/10 ? ?= 0.5
垃圾郵件的分子 = 0.2*0.2*0.8*1.0*0.5 = 0.0160000
現在我們計算正常郵件的概率
編號 | 郵件內容 | 清洗后內容 | 是否垃圾郵件 |
1 | 盡快完成工作 | 盡快,完成,工作 | 正常 |
4 | 明天一起約個飯 | 明天,一起,約個飯 | 正常 |
5 | 完成的非常棒 | 完成,的,非常,棒 | 正常 |
6 | 項目效果很好 | 項目,效果,很好 | 正常 |
9 | 賬單請查收 | 賬單,請,查收 | 正常 |
但是每個都是0,我們要做下拉普拉斯變換(分子分母分別加1,嚴格的拉普拉斯并不是這樣的,這里簡化計算了),采用拉普拉斯變換計算得到,具體定義見后文,專門解決0概率問題:
P(代開|正常) ? = 1/(5+1) ?= 0.167
P(增值稅|正常)= 1/(5+1) ?= ?0.167
P(發票|正常) ? ?= 1/(5+1) = ?0.167
P(sep|正常) ? ? = 1/(5+1) = ?0.167
計算垃圾郵件的概率,一共10個樣本,5個垃圾郵件,5個正常郵件
P(正常)= 5/10 = 0.5
正常郵件的分子 = 0.167*0.167*0.167*0.167*0.5 = 0.0003889
最后的結果(雖然拉普拉斯不大嚴謹,但是計算過程沒問題)
P(垃圾|代開,增值稅,發票,sep) = ??0.0160000/(0.0160000+0.0003889)?= 0.976271
P(正常|代開,增值稅,發票,sep) = ??0.0003889/(0.0160000+0.0003889) = 0.023729
我們計算下正常郵件的概率為多大,按公式直接計算,結果為0,但是直接計算,會導致很多樣本都為0,所以后面會引入拉普拉斯平滑。
P(正常|代開,增值稅,發票,sep) = 0
當然我,我們用Python內置的庫,就更簡單了,幾行代碼就搞定了。
data = ['盡快,完成,工作','可,代開,各,行業,發票,sep','可,開,發票,請聯系,sep','明天,一起,約個飯','完成,的,非常,棒','項目,效果,很好','有,發票,薇,sep','有,開票,微,sep','賬單,請,查收','正規,增值稅,發票,sep'] label=[0,1,1,0,0,0,1,1,0,1] vectorizer_word = TfidfVectorizer() vectorizer_word.fit(data,)#vectorizer_word.vocabulary_ train = vectorizer_word.transform(data) test = vectorizer_word.transform(['代開,增值稅,發票,sep']) from sklearn.naive_bayes import BernoulliNB clf = BernoulliNB() clf.fit(train.toarray(), label) clf.predict(test.toarray(),) clf.predict_proba(test.toarray(),) array([[0.00154805, 0.99845195]]) 算出來的概率也是0.99845195左右,和我們手動計算的差不多二、貝葉斯定理概述
貝葉斯定理由英國數學家貝葉斯 ( Thomas Bayes 1702-1761 ) 發展,用來描述兩個條件概率之間的關系,比如 P(A|B) 和 P(B|A)。主要用于文本分類。樸素貝葉斯法是基于貝葉斯定理與特征條件獨立假設的分類方法。貝葉斯定理太有用了,不管是在投資領域,還是機器學習,或是日常生活中高手幾乎都在用到它。
生命科學家用貝葉斯定理研究基因是如何被控制的,教育學家意識到,學生的學習過程其實就是貝葉斯法則的運用,基金經理用貝葉斯法則找到投資策略,谷歌用貝葉斯定理改進搜索功能,幫助用戶過濾垃圾郵件,無人駕駛汽車接收車頂傳感器收集到的路況和交通數據運用貝葉斯定理更新從地圖上獲得的信息,人工智能、機器翻譯中大量用到貝葉斯定理,比如肝癌的檢測、垃圾郵件的過濾。
樸素貝葉斯分類(NBC)是以貝葉斯定理為基礎并且假設特征條件之間相互獨立的方法,先通過已給定的訓練集,以特征詞之間獨立作為前提假設,學習從輸入到輸出的聯合概率分布,再基于學習到的模型,輸入X求出使得后驗概率最大的輸出Y 。?
設有樣本數據集D={d1,d2,...,dn},對應樣本數據的特征屬性集為X={x1,x2,...,xd}類變量為Y={y1,y2,...ym}?,即D可以分為ym類別。其中{x1,x2,...,xd}?相互獨立且隨機,則Y的先驗概率P(Y)?,Y的后驗概率P(Y|X)?,由樸素貝葉斯算法可得,后驗概率可以由先驗概率P(Y) ,證據P(X) ,類條件概率P(X|Y)計算出
樸素貝葉斯基于各特征之間相互獨立,在給定類別為y的情況下,上式可以進一步表示為下式:
由以上兩式可以計算出后驗概率為:
由于P(X)的大小是固定不變的,因此在比較后驗概率時,只比較上式的分子部分即可,因此可以得到一個樣本數據屬于類別yi的樸素貝葉斯計算:
對于上述例題,就得到如下的表達式
?
三、零概率問題連乘操作
零概率問題:即測試樣例的標簽屬性中,出現了模型訓練過程中沒有記錄的值,或者某個分類沒有記錄的值,從而出現該標簽屬性值的出現概率?P(wi|Ci) = 0?的現象。因為 P(w|Ci) 等于各標簽屬性值 P(wi|Ci) 的乘積,當分類 Ci 中某一個標簽屬性值的概率為 0,最后的 P(w|Ci) 結果也為 0。很顯然,這不能真實地代表該分類出現的概率
解決方法:拉普拉斯修正,又叫拉普拉斯平滑,這是為了解決零概率問題而引入的處理方法。其修正過程:
浮點數溢出問題:在計算 P(w|Ci) 時,各標簽屬性概率的值可能很小,而很小的數再相乘,可能會導致浮點數溢出。解決方法:對 P(w|Ci) 取對數,把概率相乘轉換為相加。
四、連續型變量概率計算
對于離散型變量,直接統計頻數分布就可以了。對于連續型的變量,為了計算對應的概率,此時又引入了一個假設,假設特征的分布為正態分布,計算樣本的均值和方差,然后通過密度函數計算取值時對應的概率
示例如下
從上面的例子可以看出,樸素貝葉斯假設樣本特征相互獨立,而且連續型的特征分布符合正態分布,這樣的假設前提是比較理想化的,所以稱之為"樸素"貝葉斯,因為實際數據并不一定會滿足這樣的要求。
五、Python庫中的貝葉斯
在scikit-learn庫,根據特征數據的先驗分布不同,給我們提供了5種不同的樸素貝葉斯分類算法(sklearn.naive_bayes: Naive Bayes模塊),分別是伯努利樸素貝葉斯(BernoulliNB),類樸素貝葉斯(CategoricalNB),高斯樸素貝葉斯(GaussianNB)、多項式樸素貝葉斯(MultinomialNB)、補充樸素貝葉斯(ComplementNB) 。
naive_bayes.BernoulliNB | Naive Bayes classifier for multivariate Bernoulli models. |
naive_bayes.CategoricalNB | Naive Bayes classifier for categorical features |
naive_bayes.ComplementNB | The Complement Naive Bayes classifier described in Rennie et al. |
naive_bayes.GaussianNB | Gaussian Naive Bayes (GaussianNB) |
naive_bayes.MultinomialNB | Naive Bayes classifier for multinomial models |
這5種算法適合應用在不同的數據場景下,我們應該根據特征變量的不同選擇不同的算法,下面是一些常規的區別和介紹。
GaussianNB
高斯樸素貝葉斯,特征變量是連續變量,符合高斯分布,比如說人的身高,物體的長度。
這種模型假設特征符合高斯分布。
MultinomialNB
特征變量是離散變量,符合多項分布,在文檔分類中特征變量體現在一個單詞出現的次數,或者是單詞的 TF-IDF 值等。不支持負數,所以輸入變量特征的時候,別用StandardScaler進行標準化數據,可以使用MinMaxScaler進行歸一化。
這個模型假設特征復合多項式分布,是一種非常典型的文本分類模型,模型內部帶有平滑參數。
ComplementNB
是MultinomialNB模型的一個變種,實現了補碼樸素貝葉斯(CNB)算法。CNB是標準多項式樸素貝葉斯(MNB)算法的一種改進,比較適用于不平衡的數據集,在文本分類上的結果通常比MultinomialNB模型好,具體來說,CNB使用來自每個類的補數的統計數據來計算模型的權重。CNB的發明者的研究表明,CNB的參數估計比MNB的參數估計更穩定。
BernoulliNB
模型適用于多元伯努利分布,即每個特征都是二值變量,如果不是二值變量,該模型可以先對變量進行二值化,在文檔分類中特征是單詞是否出現,如果該單詞在某文件中出現了即為1,否則為0。在文本分類的示例中,統計詞語是否出現的向量(word occurrence vectors)(而非統計詞語出現次數的向量(word count vectors))可以用于訓練和使用這個分類器。BernoulliNB 可能在一些數據集上表現得更好,特別是那些更短的文檔。如果時間允許,建議對兩個模型都進行評估。
CategoricalNB
對分類分布的數據實施分類樸素貝葉斯算法,專用于離散數據集, 它假定由索引描述的每個特征都有其自己的分類分布。對于訓練集中的每個特征 X,CategoricalNB估計以類y為條件的X的每個特征i的分類分布。樣本的索引集定義為J=1,…,m,m作為樣本數。
案例測試 from sklearn.naive_bayes import MultinomialNB,GaussianNB,BernoulliNB,ComplementNB from sklearn.datasets import load_breast_cancer from sklearn.model_selection import cross_val_score X,y = load_breast_cancer().data,load_breast_cancer().target nb1= GaussianNB() nb2= MultinomialNB() nb3= BernoulliNB() nb4= ComplementNB() for model in [nb1,nb2,nb3,nb4]:scores=cross_val_score(model,X,y,cv=10,scoring='accuracy')print("Accuracy:{:.4f}".format(scores.mean())) Accuracy:0.9368 Accuracy:0.8928 Accuracy:0.6274 Accuracy:0.8928from sklearn.naive_bayes import MultinomialNB,GaussianNB,BernoulliNB,ComplementNB ,CategoricalNB from sklearn.datasets import load_iris from sklearn.model_selection import cross_val_score X,y = load_iris().data,load_iris().target gn1 = GaussianNB() gn2 = MultinomialNB() gn3 = BernoulliNB() gn4 = ComplementNB() gn5 = CategoricalNB(alpha=1) for model in [gn1,gn2,gn3,gn4,gn5]:scores = cross_val_score(model,X,y,cv=10,scoring='accuracy')print("Accuracy:{:.4f}".format(scores.mean())) Accuracy:0.9533 Accuracy:0.9533 Accuracy:0.3333 Accuracy:0.6667 Accuracy:0.9267進行one-hot變化,可以發現BernoulliNB分類準確率還是很高的
from sklearn import preprocessing enc = preprocessing.OneHotEncoder() # 創建對象 from sklearn.datasets import load_iris X,y = load_iris().data,load_iris().targetenc.fit(X) array = enc.transform(X).toarray() from sklearn.naive_bayes import MultinomialNB,GaussianNB,BernoulliNB,ComplementNB ,CategoricalNB from sklearn.datasets import load_iris from sklearn.model_selection import cross_val_score X,y = load_iris().data,load_iris().target gn1 = GaussianNB() gn2 = MultinomialNB() gn3 = BernoulliNB() gn4 = ComplementNB() for model in [gn1,gn2,gn3,gn4]:scores=cross_val_score(model,array,y,cv=10,scoring='accuracy')print("Accuracy:{:.4f}".format(scores.mean())) Accuracy:0.8933 Accuracy:0.9333 Accuracy:0.9333 Accuracy:0.9400往期精彩回顧適合初學者入門人工智能的路線及資料下載(圖文+視頻)機器學習入門系列下載中國大學慕課《機器學習》(黃海廣主講)機器學習及深度學習筆記等資料打印《統計學習方法》的代碼復現專輯 AI基礎下載機器學習交流qq群955171419,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【机器学习】从一个风控案例讲起-古老而经典的朴素贝叶斯的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: can总线报文是固定的吗_新能源汽车CA
- 下一篇: java在控制台输出sql_logger