資料探勘從入門到放棄(三):樸素貝葉斯

WindyQin發表於2020-09-25
樸素貝葉斯是一種常用的分類演算法,適用於維度非常高的資料集,具有速度快,可調引數少有點,非常適合為分類問題提供快速粗糙的基本方案,經常用於垃圾郵件分類等場景中。

樸素貝葉斯演算法

樸素貝葉斯演算法依據概率論中貝葉斯定理建立模型,前提假設各個特徵之間相互獨立(這也是正式“樸素”的含義),這個假設非常極端,因為實際場景中多個特徵一般存在相關性,特徵相對獨立的假設使得演算法變得簡單,因此在特徵值有強相關性的場景中容易出現分類不準的問題。

其數學原理很容易理解:如果你看到一個人總是做好事,則會推斷那個人多半會是一個好人。這就是說,當你不能準確判斷時候,可以依靠事物特定本質相關的事件出現的多少(概率)作為判斷依據,貝葉斯定理:

資料探勘從入門到放棄(三):樸素貝葉斯

該公式表示在B發生的條件下A發生的條件概率,等於A事件發生條件下B事件發生的條件概率乘以A事件的概率,再除以B事件發生的概率。公式中,P(A)叫做先驗概率,P(A/B)叫做後驗概率。

舉個例子:一個非常炎熱的夏天晚上,走在校園裡面,伸手不見五指.......lol,這個時候迎面走來一個人,太遠看不清楚ta的性別,但我們知道ta的特徵是“短褲+短髮”,而且事先有一些學生的調查樣本,需要你根據某些特性大致判斷Ta的性別,請問你應該怎麼分類?

 

資料探勘從入門到放棄(三):樸素貝葉斯

這樣分析,我們首先計算求得P(boy|短褲短髮)和P(girl|短褲短髮)然後比較兩者大小,作為依據判定性別,也就是我們根據以往資料中穿著短褲短髮的人中boy和girl的條件概率作為依據,來判斷當我們看見“短褲短髮”人的性別,在這個例子中我們很明顯把ta判定是個boy,核心思想就是這麼簡單:

資料探勘從入門到放棄(三):樸素貝葉斯

拉普拉斯修正

由於特徵空間較為稀疏,因此,常常會出現概率為0的情況,在這種情況下,需要對其進行一些修正。常用的修正方法是拉普拉斯修正法,就是使得計算條件概率時候分子+1,很容易理解;

蘑菇資料集

該資料集包含了8124個樣本和22個變數(如蘑菇的顏色、形狀、光滑度等),是機器學習分類演算法演算法不可多得的一個優質資料集。

資料探索

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
 
# 修改baseUrl的路徑即可完成資料讀取修改
baseUrl="C:\\Users\\71781\\Desktop\\2020\\ML-20200422\\bayes\\"
mushrooms=pd.read_csv(baseUrl+"mushrooms.csv")
mushrooms.columns=['class','cap-shape','cap-surface','cap-color','ruises','odor','gill-attachment','gill-spacing','gill-size','gill-color','stalk-shape','stalk-root','stalk-surface-above-ring','stalk-surface-below-ring','stalk-color-above-ring','stalk-color-below-ring','veil-type','veil-color','ring-number','ring-type','spore-print-color','population','habitat']
mushrooms.shape

pd.set_option("display.max_columns",100) #讓所有列都能載入出來
mushrooms.head()
# 可以發現,所有特徵都是離散的,都屬於分型別

# class標識有毒無毒
np.unique(mushrooms['cap-shape'])

fig,(ax1,ax2)=plt.subplots(1,2,figsize=(15,5))
# 探究 形狀和顏色對於是否有毒的貢獻度,發現形狀為b的無毒蘑菇比例大
sns.countplot(x='cap-shape',data=mushrooms,hue='class',ax=ax1)
sns.countplot(x='cap-surface',data=mushrooms,hue='class',ax=ax2)
資料探勘從入門到放棄(三):樸素貝葉斯
sns.countplot(x='cap-color',hue='class',data=mushrooms)

  


資料探勘從入門到放棄(三):樸素貝葉斯
# 把有毒無毒換成0/1型別,1標識無毒
mushrooms['class'].replace('e',1,inplace=True)
mushrooms['class'].replace('p',0,inplace=True)
# 計算每個顏色無毒的概率
perc = mushrooms[["cap-color", "class"]].groupby(['cap-color'],as_index=False).mean()
perc
sns.barplot(x='cap-color',y='class',data=perc)

  


資料探勘從入門到放棄(三):樸素貝葉斯
# 使用sklearn進行預處理
from sklearn.preprocessing import LabelEncoder
labelencoder=LabelEncoder()
for col in mushrooms.columns:
    mushrooms[col] = labelencoder.fit_transform(mushrooms[col])
 
mushrooms.head()

sns.countplot(x='cap-shape',data=mushrooms,hue='class',)

  

資料探勘從入門到放棄(三):樸素貝葉斯

建立模型

X=mushrooms.drop('class',axis=1) #Predictors
y=mushrooms['class'] #Response
#X.head()
 
#這裡採用用啞變數編碼,為的是後面能更好的計算特徵的各屬性的重要性,並且避免數值變數分類時偏向於數值大的屬性
X=pd.get_dummies(X,columns=X.columns,drop_first=True)
X.head()

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1234)

# 貝葉斯
from sklearn.naive_bayes import GaussianNB
from sklearn import metrics 
model2 = GaussianNB()
model2.fit(X_train, y_train)
prediction2 = model2.predict(X_test)
print('The accuracy of the Decision Tree is: {0}'.format(metrics.accuracy_score(prediction2,y_test)))

 

相關文章