【機器學習】6大監(jiān)督學習模型:毒蘑菇分類
公眾號:尤而小屋
作者:Peter
編輯:Peter
大家好,我是Peter~
本文是kaggle案例分享的第3篇,賽題的名稱是:Mushroom Classification,Safe to eat or deadly poison?
數(shù)據(jù)來自UCI:https://archive.ics.uci.edu/ml/datasets/mushroom
kaggle源碼地址:https://www.kaggle.com/nirajvermafcb/comparing-various-ml-models-roc-curve-comparison

排名
下面是kaggle上針對本題的排名。第一名側(cè)重點是特征選擇,沒有用到本題的數(shù)據(jù),我個人感覺跑偏了;第二名側(cè)重點是基于貝葉斯理論的分類,能力有限,貝葉斯這塊學習好了專門再說。
所以,選擇了第三名的notebook源碼來學習。作者將6種監(jiān)督學習的方法在本數(shù)據(jù)集上的建模、模型評估等過程進行了比較。

數(shù)據(jù)集
這份數(shù)據(jù)集是UCI捐獻給kaggle的。總樣本數(shù)為8124,其中6513個樣本做訓練,1611個樣本做測試;并且,其中可食用有4208樣本,占51.8%;有毒的樣本為3916,占48.2%。每個樣本描述了蘑菇的22個屬性,比如形狀、氣味等。
誤食野生蘑菇中毒事件時有發(fā)生,且蘑菇形態(tài)千差萬別,對于非專業(yè)人士,無法從外觀、形態(tài)、顏色等方面區(qū)分有毒蘑菇與可食用蘑菇,沒有一個簡單的標準能夠?qū)⒂卸灸⒐胶涂墒秤媚⒐絽^(qū)分開來。要了解蘑菇是否可食用,必須采集具有不同特征屬性的蘑菇是否有毒進行分析。
對蘑菇的22種特征屬性進行分析,從而得到蘑菇可使用性模型,更好的預測出蘑菇是否可食用。
下面是UCI顯示的具體數(shù)據(jù)信息:

屬性特征的解釋:

數(shù)據(jù)EDA
導入數(shù)據(jù)
import?pandas?as?pd
import?numpy?as?np
import?plotly_express?as?px
from?matplotlib?import?pyplot?as?plt
import?seaborn?as?sns
#?忽略警告
import?warnings
warnings.filterwarnings('ignore')

原始數(shù)據(jù)有8124條記錄,23個屬性;并且不存在缺失值

有無毒對比
統(tǒng)計有毒和無毒的數(shù)量對比:

可視化分析
菌蓋顏色
首先我們討論下菌蓋的顏色:每種菌蓋顏色的次數(shù)

fig?=?px.bar(cap,x="color",
?????????????y="number",
?????????????color="number",
?????????????text="number",
?????????????color_continuous_scale="rainbow")
#?fig.update_layout(text_position="outside")
fig.show()

到底有毒的蘑菇是哪幾種顏色較多了?統(tǒng)計有毒和無毒下的顏色分布:

?fig?=?px.bar(cap_class,x="color",
??????????????y="number",
??????????????color="class",
??????????????text="number",
??????????????barmode="group",
?????????????)
fig.show()

小結(jié):顏色n、g、e在有毒p情況是比較多的。
菌的氣味
統(tǒng)計每種氣味的數(shù)量:

fig?=?px.bar(odor,
?????????????x="odor",
?????????????y="number",
?????????????color="number",
?????????????text="number",
?????????????color_continuous_scale="rainbow")
fig.show()

上面是針對整體數(shù)據(jù)的情況,下面分有毒和無毒來繼續(xù)討論:

?fig?=?px.bar(odor_class,
??????????????x="odor",
??????????????y="number",
??????????????color="class",
??????????????text="number",
??????????????barmode="group",
?????????????)
fig.show()

小結(jié):從上面的兩張圖中,我們看出來:f這種氣味是最容易造成有毒
特征相關性
將特征之間的相關性系數(shù)繪制成熱力圖,查看分布情況:
corr?=?data.corr()
sns.heatmap(corr)
plt.show()

特征工程
特征轉(zhuǎn)換
原數(shù)據(jù)中的特征都是文本類型,我們將其轉(zhuǎn)成數(shù)值型,方便后續(xù)分析:
1、轉(zhuǎn)換前

2、實施轉(zhuǎn)換
from?sklearn.preprocessing?import?LabelEncoder??#?類型編碼
labelencoder?=?LabelEncoder()
for?col?in?data.columns:
????data[col]?=?labelencoder.fit_transform(data[col])
#?轉(zhuǎn)換后
data.head()

3、查看部分屬性的轉(zhuǎn)換結(jié)果

數(shù)據(jù)分布
查看數(shù)據(jù)轉(zhuǎn)換編碼后的數(shù)據(jù)分布情況:

ax?=?sns.boxplot(x='class',?
?????????????????y='stalk-color-above-ring',
?????????????????data=data)
ax?=?sns.stripplot(x="class",?
???????????????????y='stalk-color-above-ring',
???????????????????data=data,?
???????????????????jitter=True,
???????????????????edgecolor="gray")
plt.title("Class?w.r.t?stalkcolor?above?ring",fontsize=12)
plt.show()

分離特征和標簽
X?=?data.iloc[:,1:23]??#?特征
y?=?data.iloc[:,?0]??#?標簽
數(shù)據(jù)標準化
#?歸一化(Normalization)、標準化(Standardization)
from?sklearn.preprocessing?import?StandardScaler
scaler?=?StandardScaler()
X?=?scaler.fit_transform(X)
X

主成分分析PCA
PCA過程
原始數(shù)據(jù)中22個屬性可能并不是特征都是有效數(shù)據(jù),或者說某些屬性本身就存在一定的關系,造成了特征屬性的重疊。我們采用主成分分析,先找出關鍵的特征:
#?1、實施pca
from?sklearn.decomposition?import?PCA
pca?=?PCA()
pca.fit_transform(X)
#?2、得到相關系數(shù)
covariance?=?pca.get_covariance()
#?3、得到每個變量對應的方差值
explained_variance=pca.explained_variance_
explained_variance

通過繪圖來展示每個主成分的得分關系:
with?plt.style.context("dark_background"):??#?背景
????plt.figure(figsize=(6,4))??#?大小
????
????plt.bar(range(22),??#?主成分個數(shù)
???????????explained_variance,??#?方差值
????????????alpha=0.5,??#?透明度
????????????align="center",
????????????label="individual?explained?variance"??#?標簽
???????????)
????plt.ylabel('Explained?variance?ratio')??#?軸名稱和圖例
????plt.xlabel('Principal?components')
????plt.legend(loc="best")
????plt.tight_layout()??#?自動調(diào)整子圖參數(shù)

結(jié)論:從上面的圖形中看出來最后的4個主成分方差之和很小;前面的17個占據(jù)了90%以上的方差,可作為主成分。
We can see that the last 4 components has less amount of variance of the data.The 1st 17 components retains more than 90% of the data.
2個主成分下的數(shù)據(jù)分布
然后我們利用基于2個屬性的數(shù)據(jù)來實施K-means聚類:
1、2個主成分下的原始數(shù)據(jù)分布
N?=?data.values
pca?=?PCA(n_components=2)
x?=?pca.fit_transform(N)
plt.figure(figsize=(5,5))
plt.scatter(x[:,0],x[:,1])
plt.show()

2、實施聚類建模后的分布:
from?sklearn.cluster?import?KMeans
km?=?KMeans(n_clusters=2,random_state=5)
N?=?data.values??#?numpy數(shù)組形式
X_clustered?=?km.fit_predict(N)??#?建模結(jié)果0-1
label_color_map?=?{0:"g",??#?分類結(jié)果只有0和1,進行打標
??????????????????1:"y"}
label_color?=?[label_color_map[l]?for?l?in?X_clustered]
plt.figure(figsize=(5,5))
#?x?=?pca.fit_transform(N)
plt.scatter(x[:,0],x[:,1],?c=label_color)
plt.show()

基于17主成分下的建模
這個地方自己也沒有看懂:總共是22個屬性,上面選取了4個特征,為什么這里是基于17個主成分的分析??
先做了基于17個主成分的轉(zhuǎn)換:

數(shù)據(jù)集的劃分:訓練集和測試集占比為8-2
from?sklearn.model_selection?import?train_test_split
X_train,?X_test,?y_train,?y_test?=?train_test_split(X,?y,?test_size=0.2,?random_state=4)
下面開始是6種監(jiān)督學習方法的具體過程:
模型1:邏輯回歸
from?sklearn.linear_model?import?LogisticRegression??#?邏輯回歸(分類)
from?sklearn.model_selection?import?cross_val_score??#?交叉驗證得分
from?sklearn?import?metrics??#?模型評價
#?建立模型
model_LR?=?LogisticRegression()
model_LR.fit(X_train,?y_train)

查看具體的預測效果:
model_LR.score(X_test,y_pred)
#?結(jié)果
1.0??#?效果很好
邏輯回歸下的混淆矩陣:
confusion_matrix?=?metrics.confusion_matrix(y_test,?y_pred)
confusion_matrix
#?結(jié)果?
array([[815,??30],
???????[?36,?744]])
具體的auc值:
auc_roc?=?metrics.roc_auc_score(y_test,?y_pred)??#?測試紙和預測值
auc_roc
#?結(jié)果
0.9591715976331362
真假陽性
from?sklearn.metrics?import?roc_curve,?auc
false_positive_rate,?true_positive_rate,thresholds?=?roc_curve(y_test,?y_prob)
roc_auc?=?auc(false_positive_rate,true_positive_rate)
roc_auc
#?結(jié)果
0.9903474434835382
ROC曲線
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))
plt.title("ROC")??#?Receiver?Operating?Characteristic
plt.plot(false_positive_rate,
?????????true_positive_rate,
?????????color="red",
?????????label="AUC?=?%0.2f"%roc_auc
????????)
plt.legend(loc="lower?right")
plt.plot([0,1],[0,1],linestyle="--")
plt.axis("tight")
#?真陽性:預測類別為1的positive;預測正確True
plt.ylabel("True?Positive?Rate")?
#?假陽性:預測類別為1的positive;預測錯誤False
plt.xlabel("False?Positive?Rate")??

下面是對邏輯回歸模型進行校正。這里的校正主要就是采取網(wǎng)格搜索的方法來選取最佳的參數(shù),然后進行下一步的建模。網(wǎng)格搜索的過程:
from?sklearn.linear_model?import?LogisticRegression
from?sklearn.model_selection?import?cross_val_score
from?sklearn?import?metrics
#?未優(yōu)化的模型
LR_model=?LogisticRegression()
#?待確定的參數(shù)
tuned_parameters?=?{"C":[0.001,0.01,0.1,1,10,100,1000],
????????????????????"penalty":['l1','l2']??#?選擇不同的正則方式,防止過擬合
???????????????????}
#?網(wǎng)格搜索模塊
from?sklearn.model_selection?import?GridSearchCV
#?加入網(wǎng)格搜索功能
LR?=?GridSearchCV(LR_model,?tuned_parameters,cv=10)
#?搜索之后再建模
LR.fit(X_train,?y_train)
#?確定參數(shù)
print(LR.best_params_)
{'C':?100,?'penalty':?'l2'}
查看優(yōu)化后的預測情況:

混淆矩陣和AUC情況:

ROC曲線情況:
from?sklearn.metrics?import?roc_curve,?auc
false_positive_rate,?true_positive_rate,?thresholds?=?roc_curve(y_test,?y_prob)
#roc_auc?=?auc(false_positive_rate,?true_positive_rate)
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))
plt.title("ROC")??#?Receiver?Operating?Characteristic
plt.plot(false_positive_rate,
?????????true_positive_rate,
?????????color="red",
?????????label="AUC?=?%0.2f"%roc_auc
????????)
plt.legend(loc="lower?right")
plt.plot([0,1],[0,1],linestyle="--")
plt.axis("tight")
#?真陽性:預測類別為1的positive;預測正確True
plt.ylabel("True?Positive?Rate")?
#?假陽性:預測類別為1的positive;預測錯誤False
plt.xlabel("False?Positive?Rate")??

模型2:高斯樸素貝葉斯
建模
from?sklearn.naive_bayes?import?GaussianNB
model_naive?=?GaussianNB()
#?建模
model_naive.fit(X_train,?y_train)
#?預測概率
y_prob?=?model_naive.predict_proba(X_test)[:,1]??
y_pred?=?np.where(y_prob?>?0.5,1,0)
model_naive.score(X_test,y_pred)
#?結(jié)果
1
預測值和真實值不等的數(shù)量:111個

交叉驗證
scores?=?cross_val_score(model_naive,
????????????????????????X,
????????????????????????y,
????????????????????????cv=10,
????????????????????????scoring="accuracy"
???????????????????????)
scores

混淆矩陣和AUC

真假陽性
#?導入評價模塊
from?sklearn.metrics?import?roc_curve,?auc
#?評價指標
false_positive_rate,?true_positive_rate,?thresholds?=?roc_curve(y_test,?y_prob)
#?roc曲線面積
roc_auc?=?auc(false_positive_rate,?true_positive_rate)
roc_auc
#?結(jié)果
0.9592201486876043
ROC曲線
AUC的值才0.96
#?繪圖
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))
plt.title("ROC")
plt.plot(false_positive_rate,true_positive_rate,color="red",label="AUC=%0.2f"%roc_auc)
plt.legend(loc="lower?right")
plt.plot([0,1],[0,1],linestyle='--')
plt.axis("tight")
plt.xlabel('False?Positive?Rate')
plt.ylabel('True?Positive?Rate')
plt.show()

模型3:支持向量機SVM
默認參數(shù)下的支持向量機過程
建模過程
from?sklearn.svm?import?SVC
svm_model?=?SVC()
tuned_parameters?=?{
????'C':?[1,?10,?100,500,?1000],
????'kernel':?['linear','rbf'],
????'C':?[1,?10,?100,500,?1000],?
????'gamma':?[1,0.1,0.01,0.001,?0.0001],?
????'kernel':?['rbf']
}
隨機網(wǎng)格搜索-RandomizedSearchCV
from?sklearn.model_selection?import?RandomizedSearchCV
#?建立隨機搜索模型
model_svm?=?RandomizedSearchCV(
????svm_model,??#?待搜索模型
????tuned_parameters,??#?參數(shù)
????cv=10,??#?10折交叉驗證
????scoring="accuracy",??#?評分標準
????n_iter=20??#?迭代次數(shù)
????)
#?訓練模型
model_svm.fit(X_train,y_train)
RandomizedSearchCV(cv=10,?
???????????????????estimator=SVC(),?
???????????????????n_iter=20,
???????????????????param_distributions={'C':?[1,?10,?100,?500,?1000],
????????????????????????????????????????'gamma':?[1,?0.1,?0.01,?0.001,?0.0001],
????????????????????????????????????????'kernel':?['rbf']},
???????????????????scoring='accuracy')
#?最佳得分效果
print(model_svm.best_score_)
1.0
得分最佳匹配參數(shù):

#?預測
y_pred?=?model_svm.predict(X_test)
#?預測值和原始標簽值計算:分類準確率
metrics.accuracy_score(y_pred,?y_test)
#?結(jié)果
1
混淆矩陣
查看具體的混淆矩陣和預測情況:

ROC曲線
from?sklearn.metrics?import?roc_curve,?auc
false_positive_rate,?true_positive_rate,?thresholds?=?roc_curve(y_test,?y_pred)
roc_auc?=?auc(false_positive_rate,?true_positive_rate)
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))
plt.title('ROC')
plt.plot(false_positive_rate,true_positive_rate,?color='red',label?=?'AUC?=?%0.2f'?%?roc_auc)
plt.legend(loc?=?'lower?right')
plt.plot([0,?1],?[0,?1],linestyle='--')
plt.axis('tight')
plt.ylabel('True?Positive?Rate')
plt.xlabel('False?Positive?Rate')

模型5:隨機森林
建模擬合
from?sklearn.ensemble?import?RandomForestClassifier
#?建模
model_RR?=?RandomForestClassifier()
#?擬合
model_RR.fit(X_train,?y_train)
預測得分

混淆矩陣

ROC曲線
from?sklearn.metrics?import?roc_curve,?auc
false_positive_rate,?true_positive_rate,?thresholds?=?roc_curve(y_test,?y_prob)
roc_auc?=?auc(false_positive_rate,?true_positive_rate)
roc_auc??#?1
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))
plt.title('ROC')
plt.plot(false_positive_rate,true_positive_rate,?color='red',label?=?'AUC?=?%0.2f'?%?roc_auc)
plt.legend(loc?=?'lower?right')
plt.plot([0,?1],?[0,?1],linestyle='--')
plt.axis('tight')
plt.ylabel('True?Positive?Rate')
plt.xlabel('False?Positive?Rate')
plt.show()

模型6:決策樹(CART)
建模
from?sklearn.tree?import?DecisionTreeClassifier
#?建模
model_tree?=?DecisionTreeClassifier()
model_tree.fit(X_train,?y_train)
#?預測
y_prob?=?model_tree.predict_proba(X_test)[:,1]
#?預測的概率轉(zhuǎn)成0-1分類
y_pred?=?np.where(y_prob?>?0.5,?1,?0)
model_tree.score(X_test,?y_pred)
#?結(jié)果
1
混淆矩陣
各種評價指標的體現(xiàn):

ROC曲線
from?sklearn.metrics?import?roc_curve,?auc
false_positive_rate,?true_positive_rate,?thresholds?=?roc_curve(y_test,?y_prob)
roc_auc?=?auc(false_positive_rate,?true_positive_rate)
roc_auc??#?1
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))??#?畫布
plt.title('ROC')??#?標題
plt.plot(false_positive_rate,??#?繪圖
?????????true_positive_rate,?
?????????color='red',
?????????label?=?'AUC?=?%0.2f'?%?roc_auc)??
plt.legend(loc?=?'lower?right')?#??圖例位置
plt.plot([0,?1],?[0,?1],linestyle='--')??#?正比例直線
plt.axis('tight')
plt.xlabel('False?Positive?Rate')
plt.ylabel('True?Positive?Rate')
plt.show()

模型6:神經(jīng)網(wǎng)絡ANN
建模

混淆矩陣

ROC曲線
?#?真假陽性
from?sklearn.metrics?import?roc_curve,?auc
false_positive_rate,?true_positive_rate,?thresholds?=?roc_curve(y_test,?y_prob)
roc_auc?=?auc(false_positive_rate,?true_positive_rate)
roc_auc??#?1
#?繪制ROC曲線
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))
plt.title('ROC')
plt.plot(false_positive_rate,true_positive_rate,?color='red',label?=?'AUC?=?%0.2f'?%?roc_auc)
plt.legend(loc?=?'lower?right')
plt.plot([0,?1],?[0,?1],linestyle='--')
plt.axis('tight')
plt.ylabel('True?Positive?Rate')
plt.xlabel('False?Positive?Rate')
plt.show()

下面對神經(jīng)網(wǎng)絡的參數(shù)進行調(diào)優(yōu):
hidden_layer_sizes:隱藏層個數(shù) activation:激活函數(shù) alpha:學習率 max_iter:最大迭代次數(shù)
網(wǎng)格搜索
from?sklearn.neural_network?import?MLPClassifier
#?實例化
mlp_model?=?MLPClassifier()
#?待調(diào)節(jié)參數(shù)
tuned_parameters={'hidden_layer_sizes':?range(1,200,10),
??????????????????'activation':?['tanh','logistic','relu'],
??????????????????'alpha':[0.0001,0.001,0.01,0.1,1,10],
??????????????????'max_iter':?range(50,200,50)
}
model_mlp=?RandomizedSearchCV(mlp_model,
??????????????????????????????tuned_parameters,
??????????????????????????????cv=10,
??????????????????????????????scoring='accuracy',
??????????????????????????????n_iter=5,
??????????????????????????????n_jobs=?-1,
??????????????????????????????random_state=5)
model_mlp.fit(X_train,y_train)

模型屬性
調(diào)優(yōu)之后的模型屬性情況以及合適的參數(shù):

ROC曲線
from?sklearn.metrics?import?roc_curve,?auc
false_positive_rate,?true_positive_rate,?thresholds?=?roc_curve(y_test,?y_prob)
roc_auc?=?auc(false_positive_rate,?true_positive_rate)
roc_auc??#?1
import?matplotlib.pyplot?as?plt
plt.figure(figsize=(10,10))
plt.title('ROC')
plt.plot(false_positive_rate,true_positive_rate,?color='red',label?=?'AUC?=?%0.2f'?%?roc_auc)
plt.legend(loc?=?'lower?right')
plt.plot([0,?1],?[0,?1],linestyle='--')
plt.axis('tight')
plt.xlabel('False?Positive?Rate')
plt.ylabel('True?Positive?Rate')

混淆矩陣和ROC
這是一篇很好的文章來解釋混淆矩陣和ROC:https://www.cnblogs.com/wuliytTaotao/p/9285227.html
1、什么是混淆矩陣?

2、4大指標
TP、FP、TN、FN,第二個字母表示樣本被預測的類別,第一個字母表示樣本的預測類別與真實類別是否一致。

3、準確率

4、精準率和召回率

5、F_1和F_B


6、ROC曲線
AUC全稱為Area Under Curve,表示一條曲線下面的面積,ROC曲線的AUC值可以用來對模型進行評價。ROC曲線如圖 1 所示:

總結(jié)
看完這篇notebook源碼,你需要掌握的知識點:
機器學習建模整體思路:選擇模型、建模、網(wǎng)格搜索調(diào)參、模型評估、ROC曲線(分類) 特征工程的技術(shù):編碼轉(zhuǎn)換、數(shù)據(jù)標準化、數(shù)據(jù)集劃分 評價指標:混淆矩陣、ROC曲線作為重點,后續(xù)有文章專門講解
往期精彩回顧 本站qq群955171419,加入微信群請掃碼:
