公衆號:尤而小屋
作者: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自己會專門寫一篇來對這份數據進行建模分析,純原創的思路,期待下~