樸素貝葉斯是一種常用的分類演算法,適用於維度非常高的資料集,具有速度快,可調引數少有點,非常適合為分類問題提供快速粗糙的基本方案,經常用於垃圾郵件分類等場景中。
樸素貝葉斯演算法
樸素貝葉斯演算法依據概率論中貝葉斯定理建立模型,前提假設各個特徵之間相互獨立(這也是正式“樸素”的含義),這個假設非常極端,因為實際場景中多個特徵一般存在相關性,特徵相對獨立的假設使得演算法變得簡單,因此在特徵值有強相關性的場景中容易出現分類不準的問題。
其數學原理很容易理解:如果你看到一個人總是做好事,則會推斷那個人多半會是一個好人。這就是說,當你不能準確判斷時候,可以依靠事物特定本質相關的事件出現的多少(概率)作為判斷依據,貝葉斯定理:
該公式表示在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)))