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


邏輯回歸:

邏輯回歸是最常用的分類算法之一。

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.771

正則化參數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.766

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

因此,我們選擇默認值C=1。

讓我們用可視化的方式來看一下用三種不同正則化參數C所得模型的系數。

更強的正則化(C = 0.001)會使系數越來越接近於零。仔細地看圖,我們還能發現特征“DiabetesPedigreeFunction”(糖尿病遺傳函數)在 C=100, C=1 和C=0.001的情況下, 系數都為正。這表明無論是哪個模型,DiabetesPedigreeFunction(糖尿病遺傳函數)這個特征值都與樣本為糖尿病是正相關的。

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(身體質量指數)”在整體中是第二重要的信息特征。隨機森林的隨機性促使算法考慮了更多可能的解釋,這就導致隨機森林捕獲的數據比單一樹要大得多。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM