梯度提升:
from sklearn.ensemble import GradientBoostingClassifier gb=GradientBoostingClassifier(random_state=0) gb.fit(x_train,y_train) print("Accuracy on training set:{:.3f}".format(gb.score(x_train,y_train))) print("Accuracy on test set:{:.3f}".format(gb.score(x_test,y_test)))
Accuracy on training set:0.917
Accuracy on test set:0.792
我們可能是過擬合了。為了降低這種過擬合,我們可以通過限制最大深度或降低學習速率來進行更強的修剪:
gb1=GradientBoostingClassifier(random_state=0,max_depth=1) gb1.fit(x_train,y_train) print("Accuracy on training set:{:.3f}".format(gb1.score(x_train,y_train))) print("Accuracy on test set:{:.3f}".format(gb1.score(x_test,y_test)))
Accuracy on training set:0.804
Accuracy on test set:0.781
gb2=GradientBoostingClassifier(random_state=0,learning_rate=0.01) gb2.fit(x_train,y_train) print("Accuracy on training set:{:.3f}".format(gb2.score(x_train,y_train))) print("Accuracy on test set:{:.3f}".format(gb2.score(x_test,y_test)))
Accuracy on training set:0.802
Accuracy on test set:0.776
如我們所期望的,兩種降低模型復雜度的方法都降低了訓練集的准確度。可是測試集的泛化性能並沒有提高。
盡管我們對這個模型的結果不是很滿意,但我們還是希望通過特征重要度的可視化來對模型做更進一步的了解。
plot_feature_importances_diabetes(gb1)
我們可以看到,梯度提升樹的特征重要度與隨機森林的特征重要度有點類似,同時它給這個模型的所有特征賦了重要度值。
支持向量機:
from sklearn.svm import SVC svc=SVC() svc.fit(x_train,y_train) print("Accuracy on training set:{:.2f}".format(svc.score(x_train,y_train))) print("Accuracy on test set:{:.2f}".format(svc.score(x_test,y_test)))
Accuracy on training set:1.00
Accuracy on test set:0.65
這個模型過擬合比較明顯,雖然在訓練集中有一個完美的表現,但是在測試集中僅僅有65%的准確度。
SVM要求所有的特征要在相似的度量范圍內變化。我們需要重新調整各特征值尺度使其基本上在同一量表上。
from sklearn.preprocessing import MinMaxScaler scaler=MinMaxScaler() x_train_scaled=scaler.fit_transform(x_train) x_test_scaled=scaler.fit_transform(x_test) svc=SVC() svc.fit(x_train_scaled,y_train) print("Accuracy on training set:{:.2f}".format(svc.score(x_train_scaled,y_train))) print("Accuracy on test set:{:.2f}".format(svc.score(x_test_scaled,y_test)))
Accuracy on training set:0.77
Accuracy on test set:0.77
數據的度量標准化后效果大不同!現在我們的模型在訓練集和測試集的結果非常相似,這其實是有一點過低擬合的,但總體而言還是更接近100%准確度的。這樣來看,我們還可以試着提高C值或者gamma值來配適更復雜的模型。
svc=SVC(C=1000) svc.fit(x_train_scaled,y_train) print("Accuracy on training set:{:.2f}".format(svc.score(x_train_scaled,y_train))) print("Accuracy on test set:{:.2f}".format(svc.score(x_test_scaled,y_test)))
Accuracy on training set:0.79
Accuracy on test set:0.80
提高了C值后,模型效果確實有一定提升,測試集准確度提至79.7%。
深度學習:
from sklearn.neural_network import MLPClassifier mlp=MLPClassifier(random_state=42) mlp.fit(x_train,y_train) print("Accuracy on training set:{:.2f}".format(mlp.score(x_train,y_train))) print("Accuracy on test set:{:.2f}".format(mlp.score(x_test,y_test)))
Accuracy on training set:0.71
Accuracy on test set:0.67
多層神經網絡(MLP)的預測准確度並不如其他模型表現的好,這可能是數據的尺度不同造成的。深度學習算法同樣也希望所有輸入的特征在同一尺度范圍內變化。理想情況下,是均值為0,方差為1。所以,我們必須重新標准化我們的數據,以便能夠滿足這些需求。
from sklearn.preprocessing import StandardScaler scaler=StandardScaler() x_train_scaled=scaler.fit_transform(x_train) x_test_scaled=scaler.fit_transform(x_test) mlp=MLPClassifier(random_state=0) mlp.fit(x_train_scaled,y_train) print("Accuracy on training set:{:.3f}".format(mlp.score(x_train_scaled,y_train))) print("Accuracy on test set:{:.3f}".format(mlp.score(x_test_scaled,y_test)))
Accuracy on training set:0.823
Accuracy on test set:0.802
讓我們增加迭代次數:
mlp=MLPClassifier(max_iter=1000,random_state=0) mlp.fit(x_train_scaled,y_train) print("Accuracy on training set:{:.3f}".format(mlp.score(x_train_scaled,y_train))) print("Accuracy on test set:{:.3f}".format(mlp.score(x_test_scaled,y_test)))
Accuracy on training set:0.877
Accuracy on test set:0.755
增加迭代次數僅僅提升了訓練集的性能,而對測試集沒有效果。
讓我們調高alpha參數並且加強權重的正則化。
mlp=MLPClassifier(max_iter=1000,alpha=1,random_state=0) mlp.fit(x_train_scaled,y_train) print("Accuracy on training set:{:.3f}".format(mlp.score(x_train_scaled,y_train))) print("Accuracy on test set:{:.3f}".format(mlp.score(x_test_scaled,y_test)))
Accuracy on training set:0.795
Accuracy on test set:0.792
這個結果是好的,但我們無法更進一步提升測試集准確度。因此,到目前為止我們最好的模型是在數據標准化后的默認參數深度學習模型。最后,我們繪制了一個在糖尿病數據集上學習的神經網絡的第一層權重熱圖。
plt.figure(figsize=(20,5)) plt.imshow(mlp.coefs_[0],interpolation='none',cmap='viridis') plt.yticks(range(8),diabetes_features) plt.xlabel("Columns in weight matrix") plt.ylabel("Input feature") plt.colorbar()
從這個熱度圖中,快速指出哪個或哪些特征的權重較高或較低是不容易的。
設置正確的參數非常重要:
本文我們練習了很多種不同的機器學習模型來進行分類和回歸,了解了它們的優缺點是什么,以及如何控制其模型復雜度。我們同樣看到,對於許多算法來說,設置正確的參數對於性能良好是非常重要的。