GBDT 適用范圍
GBDT 可以適用於回歸問題(線性和非線性)其實多用於回歸;
GBDT 也可用於二分類問題(設定閾值,大於為正,否則為負)和多分類問題
RF與GBDT之間的區別與聯系
1)相同點:
- 都是由多棵樹組成
- 最終的結果都由多棵樹共同決定。
2)不同點:
- 組成隨機森林的樹可以分類樹也可以是回歸樹,而GBDT只由回歸樹組成
- 組成隨機森林的樹可以並行生成(Bagging);GBDT 只能串行生成(Boosting);這兩種模型都用到了Bootstrap的思想。
- 隨機森林的結果是多數表決表決的,而GBDT則是多棵樹加權累加之和
- 隨機森林對異常值不敏感,而GBDT對異常值比較敏感
- 隨機森林是減少模型的方差,而GBDT是減少模型的偏差
- 隨機森林不需要進行特征歸一化。而GBDT則需要進行特征歸一化
- 隨機森林對訓練集一視同仁權值一樣,GBDT是基於權值的弱分類器的集成
gbdt參數詳解
class sklearn.ensemble.GradientBoostingClassifier(*, loss='deviance', learning_rate=0.1, n_estimators=100, subsample=1.0,
criterion='friedman_mse', min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3,
min_impurity_decrease=0.0, min_impurity_split=None, init=None, random_state=None, max_features=None,
verbose=0, max_leaf_nodes=None, warm_start=False, presort='deprecated', validation_fraction=0.1,
n_iter_no_change=None, tol=0.0001, ccp_alpha=0.0)
參數:
(1)n_estimators: 也就是弱學習器的最大迭代次數,或者說最大的弱學習器的個數。一般來說n_estimators太小,容易欠擬合,n_estimators太大,又容易過擬合,一般選擇一個適中的數值。默認是100。在實際調參的過程中,我們常常將n_estimators和下面介紹的參數learning_rate一起考慮
(2)learning_rate, float,默認= 0.1,學習率縮小了每棵樹的貢獻learning_rate。在learning_rate和n_estimators之間需要權衡
(3)subsample: 即我們在原理篇的正則化章節講到的子采樣,取值為(0,1]。注意這里的子采樣和隨機森林不一樣,隨機森林使用的是放回抽樣,而這里是不放回抽樣。如果取值為1,則全部樣本都使用,等於沒有使用子采樣。如果取值小於1,則只有一部分樣本會去做GBDT的決策樹擬合。選擇小於1的比例可以減少方差,即防止過擬合,但是會增加樣本擬合的偏差,因此取值不能太低。推薦在[0.5, 0.8]之間,默認是1.0,即不使用子采樣
(4)loss: 即我們GBDT算法中的損失函數。分類模型和回歸模型的損失函數是不一樣的。
對於分類模型,有對數似然損失函數"deviance"和指數損失函數"exponential"兩者輸入選擇。默認是對數似然損失函數"deviance"。在原理篇中對這些分類損失函數有詳細的介紹。一般來說,推薦使用默認的"deviance"。它對二元分離和多元分類各自都有比較好的優化。而指數損失函數等於把我們帶到了Adaboost算法。
對於回歸模型,有均方差"ls", 絕對損失"lad", Huber損失"huber"和分位數損失“quantile”。默認是均方差"ls"。一般來說,如果數據的噪音點不多,用默認的均方差"ls"比較好。如果是噪音點較多,則推薦用抗噪音的損失函數"huber"。而如果我們需要對訓練集進行分段預測的時候,則采用“quantile”
(5)alpha:這個參數只有GradientBoostingRegressor有,當我們使用Huber損失"huber"和分位數損失“quantile”時,需要指定分位數的值。默認是0.9,如果噪音點較多,可以適當降低這個分位數的值
(6)min_samples_split, int或float,默認為2,拆分內部節點所需的最少樣本數:如果為int,則認為min_samples_split是最小值。如果為float,min_samples_split則為分數, 是每個拆分的最小樣本數。ceil(min_samples_split * n_samples)
(7)min_samples_leaf, int或float,默認值= 1,在葉節點處所需的最小樣本數。僅在任何深度的分裂點在min_samples_leaf左分支和右分支中的每個分支上至少留下訓練樣本時,才考慮。這可能具有平滑模型的效果,尤其是在回歸中。如果為int,則認為min_samples_leaf是最小值。如果為float,min_samples_leaf則為分數, 是每個節點的最小樣本數。ceil(min_samples_leaf * n_samples)
(8)min_weight_fraction_leaf, float,默認值= 0.0,在所有葉節點處(所有輸入樣本)的權重總和中的最小加權分數。如果未提供sample_weight,則樣本的權重相等。
(9)max_depth, int,默認= 3,各個回歸估計量的最大深度。最大深度限制了樹中節點的數量。調整此參數以獲得最佳性能;最佳值取決於輸入變量的相互作用。也就是那個樹有多少層(一般越多越容易過擬合)
(10)min_impurity_decrease, 浮動,默認值= 0.0,如果節點分裂會導致雜質的減少大於或等於該值,則該節點將被分裂
(11)min_impurity_split ,float,默認=無提前停止樹木生長的閾值。如果節點的雜質高於閾值,則該節點將分裂,否則為葉
(12)init:計量或“零”,默認=無,一個估計器對象,用於計算初始預測。 init必須提供fit和predict_proba。如果為“零”,則初始原始預測設置為零。默認情況下,使用 DummyEstimator預測類優先級
(13)max_features:節點分裂時參與判斷的最大特征數
- int:個數
- float:占所有特征的百分比
- auto:所有特征數的開方
- sqrt:所有特征數的開方
- log2:所有特征數的log2值
- None:等於所有特征數
其他沒啥好說的,有興趣可以自己查看官網https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingClassifier.html
屬性:
n_estimators_
feature_importances_
oob_improvement_
train_score_
loss_
init_
estimators_
classes_
n_features_
n_classes_
max_features_
# -*- coding: utf-8 -*- """ Created on Tue Aug 11 10:12:48 2020 """ from sklearn.ensemble import AdaBoostClassifier ,AdaBoostRegressor from sklearn.datasets import load_iris x_data=load_iris().data y_data=load_iris().target from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test = train_test_split(x_data,y_data,test_size=0.3,random_state=1,stratify=y_data) #單個決策樹模型 from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score tree = DecisionTreeClassifier(criterion='gini',max_depth=4,random_state=1) tree.fit(X_train,y_train) y_train_pred = tree.predict(X_train) y_test_pred = tree.predict(X_test) tree_train = accuracy_score(y_train,y_train_pred) tree_test = accuracy_score(y_test,y_test_pred) print('Decision tree train/test accuracies %.3f/%.3f' % (tree_train,tree_test)) #Decision tree train/test accuracies 0.971/0.978 #gbdt實現 import matplotlib.pyplot as plt from sklearn.ensemble import GradientBoostingClassifier depth_ = [1, 2, 3, 4, 5, 6, 7, 8] scores1 = [] scores2 = [] for depth in depth_: gbdt = GradientBoostingClassifier(n_estimators=100, max_depth=depth, random_state=1) gbdt.fit(X_train,y_train) a1=accuracy_score(y_train,gbdt.predict(X_train)) a2=accuracy_score(y_test,gbdt.predict(X_test)) scores1.append(a1) scores2.append(a2) plt.plot(depth_,scores1) plt.plot(depth_,scores2)
梯度提升以進行回歸
class sklearn.ensemble.GradientBoostingRegressor(loss='ls', learning_rate=0.1, n_estimators=100, subsample=1.0,
min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, init=None, random_state=None,
max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False)
參數
loss:{'ls','lad','huber','quantile'},可選(默認='ls')
損失函數有待優化。“ ls”是指最小二乘回歸。“ lad”(最小絕對偏差)是僅基於輸入變量的順序信息的高度魯棒的損失函數。“ huber”是兩者的結合。“分位數”允許分位數回歸(使用α來指定分位數)。
learning_rate:float,可選(默認= 0.1)
學習率通過learning_rate縮小每棵樹的貢獻。在learning_rate和n_estimators之間需要權衡。
n_estimators:int(默認= 100)
要執行的提升階段數。梯度提升對於過度擬合具有相當強的魯棒性,因此大量提升通常會帶來更好的性能。
max_depth:整數,可選(默認= 3)
各個回歸估計量的最大深度。最大深度限制了樹中節點的數量。調整此參數以獲得最佳性能;最佳值取決於輸入變量的相互作用。如果max_leaf_nodes不為None則忽略。
min_samples_split:整數,可選(默認= 2)
拆分內部節點所需的最小樣本數。
min_samples_leaf:整數,可選(默認= 1)
在葉節點處所需的最小樣本數。
min_weight_fraction_leaf:浮點型,可選(默認= 0.)
輸入樣本的最小加權分數必須位於葉節點。
subsample:浮點型,可選(默認= 1.0)
用於擬合各個基礎學習者的樣本比例。如果小於1.0,則將導致隨機梯度增強。subsample與參數n_estimators交互。選擇小於1.0的子樣本會導致方差減少和偏差增加。
max_features:int,float,string或None,可選(默認=無)
- 尋找最佳分割時要考慮的功能數量:
- 如果為int,則在每個拆分中考慮max_features功能。
- 如果為float,則max_features是一個百分比,並 在每次拆分時考慮int(max_features * n_features)個特征。
- 如果為“ auto”,則max_features = n_features。。
- 如果為“ sqrt”,則max_features = sqrt(n_features)。
- 如果為“ log2”,則max_features = log2(n_features)。
- 如果為None,則max_features = n_features。
選擇max_features <n_features會導致方差減少和偏差增加。
注意:直到找到至少一個有效的節點樣本分區,分割的搜索才會停止,即使它需要有效檢查多個max_features功能也是如此。
max_leaf_nodes:int或None,可選(默認=無)
以最佳優先方式種植具有max_leaf_nodes的樹。最佳節點定義為雜質的相對減少。如果為None,則葉節點數不受限制。
alpha:浮點(默認= 0.9)
Huber損失函數和分位數損失函數的alpha分位數。僅當loss ='huber'或loss ='quantile'時。
init:BaseEstimator,無,可選(默認=無)
一個估計器對象,用於計算初始預測。初始化必須提供適應和預測。如果為None,則使用loss.init_estimator。
verbose:int,默認:0
啟用詳細輸出。如果為1,則偶爾打印一次進度和性能(樹越多,頻率越低)。如果大於1,則為每棵樹打印進度和性能。
warm_start:布爾值,默認值:False
設置為True時,請重用上一個調用的解決方案以適合並在集合中添加更多的估計量,否則,只需擦除以前的解決方案即可。
屬性:
feature_importances_:數組,形狀= [n_features]
功能的重要性(越高,功能越重要)。特征重要性
oob_improvement_:數組,形狀= [n_estimators]
相對於先前的迭代,袋裝樣本的損失(=偏差)的改善。 oob_improvement_ [0]是初始估算器在第一階段損失方面的改進。
train_score_:數組,形狀= [n_estimators]
第i個得分train_score_ [i]是袋內樣本在第i次迭代時模型的偏差(=損失)。如果子樣本 == 1,則這是訓練數據的偏差。
loss_:LossFunction
具體的LossFunction對象。
`init`:BaseEstimator
提供初始預測的估算器。通過init參數或loss.init_estimator進行設置。
estimators_:DecisionTreeRegressor的ndarray,形狀= [n_estimators,1]
擬合子估計量的集合。
方法:
Decision_function(X) | 計算X的決策函數。 |
fit(X, y[, sample_weight, monitor]) | 擬合梯度提升模型。 |
fit_transform(X [,y]) | 適合數據,然后對其進行轉換。 |
get_params([deep]) | 獲取此估計量的參數。 |
predict(X) | 預測X的回歸目標。 |
score(X, y[, sample_weight]) | 返回預測的確定系數R ^ 2。 |
set_params(**params) | 設置此估算器的參數。 |
staged_decision_function(X) | 為每次迭代計算X的決策函數。 |
staged_predict(X) | 預測X的每個階段的回歸目標。 |
transform(X[, threshold]) | 將X還原為其最重要的功能。 |
具體操作可以參考官網https://scikit-learn.org/0.16/modules/generated/sklearn.ensemble.GradientBoostingRegressor.html
使用波斯頓房價的數據
# 從 sklearn.datasets 導入波士頓房價數據讀取器。 from sklearn.datasets import load_boston # 從讀取房價數據存儲在變量 boston 中。 boston = load_boston() # 從sklearn.cross_validation 導入數據分割器。 from sklearn.model_selection import train_test_split X = boston.data y = boston.target # 隨機采樣 25% 的數據構建測試樣本,其余作為訓練樣本。 X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=33, test_size=0.25) # 從 sklearn.preprocessing 導入數據標准化模塊。 from sklearn.preprocessing import StandardScaler # 分別初始化對特征和目標值的標准化器。 ss_X = StandardScaler() ss_y = StandardScaler() # 分別對訓練和測試數據的特征以及目標值進行標准化處理。 X_train = ss_X.fit_transform(X_train) X_test = ss_X.transform(X_test) y_train = ss_y.fit_transform(y_train.reshape(-1,1)) y_test = ss_y.transform(y_test.reshape(-1,1)) from sklearn.ensemble import GradientBoostingRegressor max_depth=list(range(2,7)) l=[] for i in max_depth: clf= GradientBoostingRegressor(learning_rate=0.1, n_estimators=100,max_depth=i,random_state=0) clf=clf.fit(X_train,y_train) score=clf.score(X_test, y_test) l.append(score) import matplotlib.pyplot as plt plt.plot(max_depth,l) #可以看出max_depth=3是最好的, clf= GradientBoostingRegressor(learning_rate=0.1, n_estimators=100,max_depth=3,random_state=0) clf=clf.fit(X_train,y_train) #查看屬性 clf.feature_importances_ plt.plot(clf.feature_importances_) clf.estimators_ clf.score(X_test, y_test)