手把手丨咱們在UCL找到了一個糖尿病數據集,用機器學習預測糖尿病(二)

邏輯迴歸:

邏輯迴歸是最經常使用的分類算法之一。python

from sklearn.linear_model import LogisticRegression
logreg=LogisticRegression().fit(x_train,y_train)
print("Training set score:{:.3f}".format(logreg.score(x_train,y_train)))
print("Test set score:{:.3f}".format(logreg.score(x_test,y_test)))

 Training set score:0.781算法

 Test set score:0.771dom

正則化參數C=1(默認值)的模型在訓練集上準確度爲78%,在測試集上準確度爲77%。函數

logreg100=LogisticRegression(C=100).fit(x_train,y_train)
print("Training set score:{:.3f}".format(logreg100.score(x_train,y_train)))
print("Test set score:{:.3f}".format(logreg100.score(x_test,y_test)))

 Training set score:0.785測試

 Test set score:0.766spa

而將正則化參數C設置爲100時,模型在訓練集上準確度稍有提升但測試集上準確度略降,說明較少正則化和更復雜的模型並不必定會比默認參數模型的預測效果更好。rest

所以,咱們選擇默認值C=1。code

讓咱們用可視化的方式來看一下用三種不一樣正則化參數C所得模型的係數。orm

更強的正則化(C = 0.001)會使係數愈來愈接近於零。仔細地看圖,咱們還能發現特徵「DiabetesPedigreeFunction」(糖尿病遺傳函數)在 C=100, C=1 和C=0.001的狀況下, 係數都爲正。這代表不管是哪一個模型,DiabetesPedigreeFunction(糖尿病遺傳函數)這個特徵值都與樣本爲糖尿病是正相關的。blog

diabetes_features=[x for i,x in enumerate(diabetes.columns) if i!=8]
plt.figure(figsize=(8,6))
plt.plot(logreg.coef_.T,'o',label="C=1")
plt.plot(logreg100.coef_.T,'^',label="C=100")
plt.plot(logreg001.coef_.T,'v',label="C=0.001")
plt.xticks(range(diabetes.shape[1]),diabetes_features,rotation=90)
plt.hlines(0,0,diabetes.shape[1])
plt.ylim(-5,5)
plt.xlabel("Feature")
plt.ylabel("Coefficient magnitude")
plt.legend()

 

 決策樹:

from sklearn.tree import DecisionTreeClassifier
tree=DecisionTreeClassifier(random_state=0)
tree.fit(x_train,y_train)
print("Accuracy on training set:{:.3f}".format(tree.score(x_train,y_train)))
print("Accuracy on test set:{:.3f}".format(tree.score(x_test,y_test)))

 Accuracy on training set:1.000

 Accuracy on test set:0.714

訓練集的準確度能夠高達100%,而測試集的準確度相對就差了不少。這代表決策樹是過分擬合的,不能對新數據產生好的效果。所以,咱們須要對樹進行預剪枝。

咱們設置max_depth=3,限制樹的深度以減小過擬合。這會使訓練集的準確度下降,但測試集準確度提升。

tree=DecisionTreeClassifier(max_depth=3,random_state=0)
tree.fit(x_train,y_train)
print("Accuracy on training set:{:.3f}".format(tree.score(x_train,y_train)))
print("Accuracy on test set:{:.3f}".format(tree.score(x_test,y_test)))

 Accuracy on training set:0.773

 Accuracy on test set:0.740

 

決策樹中的特徵重要度:

決策樹中的特徵重要度是用來衡量每一個特徵對於預測結果的重要性的。對每一個特徵有一個從0到1的打分,0表示「一點也沒用」,1表示「完美預測」。各特徵的重要度加和必定是爲1的。

print("Feature importances:\n{}".format(tree.feature_importances_))

 Feature importances: [ 0.04554275 0.6830362 0. 0. 0. 0.27142106 0. 0. ]

而後咱們能可視化特徵重要度:

def plot_feature_importances_diabetes(model):
    plt.figure(figsize=(8,6))
    n_features=8
    plt.barh(range(n_features),model.feature_importances_,align='center')
    plt.yticks(np.arange(n_features),diabetes_features)
    plt.xlabel("Feature importance")
    plt.ylabel("Feature")
    plt.ylim(-1,n_features)
plot_feature_importances_diabetes(tree)

 

特徵「血糖」是目前最重要的特徵。

 隨機森林:

讓咱們在糖尿病數據集中應用一個由100棵樹組成的隨機森林:

from sklearn.ensemble import RandomForestClassifier
rf=RandomForestClassifier(n_estimators=100,random_state=0)
rf.fit(x_train,y_train)
print("Accuracy on training set:{:.3f}".format(rf.score(x_train,y_train)))
print("Accuracy on test set:{:.3f}".format(rf.score(x_test,y_test)))

 Accuracy on training set:1.000

 Accuracy on test set:0.786

沒有更改任何參數的隨機森林有78.6%的準確度,比邏輯迴歸和單一決策樹的預測效果更好。然而,咱們仍是能夠調整max_features設置,看看效果是否可以提升。

rf1=RandomForestClassifier(max_depth=3,n_estimators=100,random_state=0)
rf1.fit(x_train,y_train)
print("Accuracy on training set:{:.3f}".format(rf1.score(x_train,y_train)))
print("Accuracy on test set:{:.3f}".format(rf1.score(x_test,y_test)))

 Accuracy on training set:0.800

 Accuracy on test set:0.755

結果並無提升,這代表默認參數的隨機森林在這裏效果很好。

隨機森林的特徵重要度:

plot_feature_importances_diabetes(rf1)

 

與單一決策樹類似,隨機森林的結果仍然顯示特徵「血糖」的重要度最高,可是它也一樣顯示「BMI(身體質量指數)」在總體中是第二重要的信息特徵。隨機森林的隨機性促使算法考慮了更多可能的解釋,這就致使隨機森林捕獲的數據比單一樹要大得多。

相關文章
相關標籤/搜索