6種監督學習方法:實現毒蘑菇分類

公衆號:尤而小屋
作者:Peter
編輯:Peter

大家好,我是Peter~

本文是kaggle案例分享的第3篇,賽題的名稱是:Mushroom Classification,Safe to eat or deadly poison?

數據來自UCI:https://archive.ics.uci.edu/ml/datasets/mushroom

kaggle源碼地址:https://www.kaggle.com/nirajvermafcb/comparing-various-ml-models-roc-curve-comparison

排名

下面是kaggle上針對本題的排名。第一名側重點是特徵選擇,沒有用到本題的數據,我個人感覺跑偏了;第二名側重點是基於貝葉斯理論的分類,能力有限,貝葉斯這塊學習好了專門再說。

所以,選擇了第三名的notebook源碼來學習。作者將6種監督學習的方法在本數據集上的建模、模型評估等過程進行了比較。

數據集

這份數據集是UCI捐獻給kaggle的。總樣本數爲8124,其中6513個樣本做訓練,1611個樣本做測試;並且,其中可食用有4208樣本,佔51.8%;有毒的樣本爲3916,佔48.2%。每個樣本描述了蘑菇的22個屬性,比如形狀、氣味等。

誤食野生蘑菇中毒事件時有發生,且蘑菇形態千差萬別,對於非專業人士,無法從外觀、形態、顏色等方面區分有毒蘑菇與可食用蘑菇,沒有一個簡單的標準能夠將有毒蘑菇和可食用蘑菇區分開來。要了解蘑菇是否可食用,必須採集具有不同特徵屬性的蘑菇是否有毒進行分析。

對蘑菇的22種特徵屬性進行分析,從而得到蘑菇可使用性模型,更好的預測出蘑菇是否可食用。

下面是UCI顯示的具體數據信息:

屬性特徵的解釋:

數據EDA

導入數據

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')

原始數據有8124條記錄,23個屬性;並且不存在缺失值

有無毒對比

統計有毒和無毒的數量對比:

可視化分析

菌蓋顏色

首先我們討論下菌蓋的顏色:每種菌蓋顏色的次數

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

# fig.update_layout(text_position="outside")
fig.show()

到底有毒的蘑菇是哪幾種顏色較多了?統計有毒和無毒下的顏色分佈:

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

fig.show()

小結:顏色n、g、e在有毒p情況是比較多的

菌的氣味

統計每種氣味的數量:

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

fig.show()

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

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

fig.show()

小結:從上面的兩張圖中,我們看出來:f這種氣味是最容易造成有毒

特徵相關性

將特徵之間的相關性係數繪製成熱力圖,查看分佈情況:

corr = data.corr()
sns.heatmap(corr)

plt.show()

特徵工程

特徵轉換

原數據中的特徵都是文本類型,我們將其轉成數值型,方便後續分析:

1、轉換前

2、實施轉換

from sklearn.preprocessing import LabelEncoder  # 類型編碼
labelencoder = LabelEncoder()

for col in data.columns:
    data[col] = labelencoder.fit_transform(data[col])

# 轉換後
data.head()

3、查看部分屬性的轉換結果

數據分佈

查看數據轉換編碼後的數據分佈情況:

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]  # 標籤

數據標準化

# 歸一化(Normalization)、標準化(Standardization)

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X = scaler.fit_transform(X)
X

主成分分析PCA

PCA過程

原始數據中22個屬性可能並不是特徵都是有效數據,或者說某些屬性本身就存在一定的關係,造成了特徵屬性的重疊。我們採用主成分分析,先找出關鍵的特徵:

# 1、實施pca
from sklearn.decomposition import PCA
pca = PCA()
pca.fit_transform(X)

# 2、得到相關係數
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),  # 主成分個數
           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()  # 自動調整子圖參數

結論:從上面的圖形中看出來最後的4個主成分方差之和很小;前面的17個佔據了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個主成分下的數據分佈

然後我們利用基於2個屬性的數據來實施K-means聚類:

1、2個主成分下的原始數據分佈

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數組形式
X_clustered = km.fit_predict(N)  # 建模結果0-1

label_color_map = {0:"g",  # 分類結果只有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個主成分的轉換

數據集的劃分:訓練集和測試集佔比爲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種監督學習方法的具體過程:

模型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)

# 結果
1.0  # 效果很好

邏輯迴歸下的混淆矩陣:

confusion_matrix = metrics.confusion_matrix(y_test, y_pred)
confusion_matrix

# 結果 
array([[815,  30],
       [ 36, 744]])

具體的auc值:

auc_roc = metrics.roc_auc_score(y_test, y_pred)  # 測試紙和預測值
auc_roc

# 結果
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

# 結果
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")  

下面是對邏輯迴歸模型進行校正。這裏的校正主要就是採取網格搜索的方法來選取最佳的參數,然後進行下一步的建模。網格搜索的過程:

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn import metrics

# 未優化的模型
LR_model= LogisticRegression()
# 待確定的參數
tuned_parameters = {"C":[0.001,0.01,0.1,1,10,100,1000],
                    "penalty":['l1','l2']  # 選擇不同的正則方式,防止過擬合
                   }
# 網格搜索模塊
from sklearn.model_selection import GridSearchCV
# 加入網格搜索功能
LR = GridSearchCV(LR_model, tuned_parameters,cv=10)
# 搜索之後再建模
LR.fit(X_train, y_train)

# 確定參數
print(LR.best_params_)

{'C': 100, 'penalty': 'l2'}

查看優化後的預測情況:

混淆矩陣和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)

# 結果
1

預測值和真實值不等的數量: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

# 結果
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

默認參數下的支持向量機過程

建模過程

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']
}

隨機網格搜索-RandomizedSearchCV

from sklearn.model_selection import RandomizedSearchCV

# 建立隨機搜索模型
model_svm = RandomizedSearchCV(
    svm_model,  # 待搜索模型
    tuned_parameters,  # 參數
    cv=10,  # 10折交叉驗證
    scoring="accuracy",  # 評分標準
    n_iter=20  # 迭代次數
    )

# 訓練模型
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

得分最佳匹配參數:

# 預測
y_pred = model_svm.predict(X_test)

# 預測值和原始標籤值計算:分類準確率
metrics.accuracy_score(y_pred, y_test)
# 結果
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]

# 預測的概率轉成0-1分類
y_pred = np.where(y_prob > 0.5, 1, 0)
model_tree.score(X_test, y_pred)
# 結果
1

混淆矩陣

各種評價指標的體現:

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:神經網絡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()

下面對神經網絡的參數進行調優:

  • hidden_layer_sizes:隱藏層個數
  • activation:激活函數
  • alpha:學習率
  • max_iter:最大迭代次數

網格搜索

from sklearn.neural_network import MLPClassifier

# 實例化
mlp_model = MLPClassifier()
# 待調節參數
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)

模型屬性

調優之後的模型屬性情況以及合適的參數:

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 所示:

總結

看完這篇notebook源碼,你需要掌握的知識點:

  • 機器學習建模整體思路:選擇模型、建模、網格搜索調參、模型評估、ROC曲線(分類)
  • 特徵工程的技術:編碼轉換、數據標準化、數據集劃分
  • 評價指標:混淆矩陣、ROC曲線作爲重點,後續有文章專門講解

預告:後面Peter自己會專門寫一篇來對這份數據進行建模分析,純原創的思路,期待下~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章