數據挖掘算法和實踐(三):樸素貝葉斯(mushrooms蘑菇數據集)

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

樸素貝葉斯適用於維度非常高的數據集,速度快,可調參數少,非常適合爲分類問題提供快速粗糙的基本方案,經常用於垃圾郵件分類等類似場景中,其數學原理很容易理解:如果你看到一個人總是做好事,則會推斷那個人多半會是一個好人。這就是說,當你不能準確判斷時候,可以依靠事物特定本質相關的事件出現的多少(概率)作爲判斷依據,貝葉斯定理:

該公式表示在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)))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章