寫在前面
前面博客寫過 bagging 算法的實現方式,並且提到集成算法的其他三類模型組合方式,此文主要簡述Boosting 中Adaboost / GBDT 的實現方式.
算法主要特點
Boosting:
- 順序集合:嘗試添加在之前模型缺失的地方做得很好的新模型
- 旨在減少偏差,而不是方差
- 適合低方差高偏差模型
- 基於樹的方法的示例是梯度提升
圖例描述
接下來進入主題
1. Adaboost 算法:
WIKI百科:
AdaBoost,即Adaptive Boosting,譯爲自適應增強,其1995年由Freund和Schapire提出的。AdaBoost算法是提升方法(Boosting)的一種,那什麼是提升方法呢?提升方法是一種將弱學習算法提升爲強學習算法的一種統計學習方法,在分類問題中,它通過反覆修改訓練樣本的權值分佈,構建一系列基本分類器(弱分類器),並將這些基本分類器線性組合起來,構建一個強分類器,以提高分類性能。而AdaBoost算法便是提升方法中的代表性算法,另外一個是提升樹方法(Boosting Tree)。
通俗理解:
即Adaptive boosting,是一種迭代算法。每輪迭代中會在訓練集上產生一個新的分類器,然後使用該分類器對所有樣本進行分類,以評估每個樣本的重要性(informative)。 具體來說,算法會爲每個訓練樣本賦予一個權值。每次用訓練完的新分類器標註各個樣本,若某個樣本點已被分類正確,則將其權值降低;若樣本點未被正確分類,則提高其權值。權值越高的樣本在下一次訓練中所佔的比重越大,也就是說越難區分的樣本在訓練過程中會變得越來越重要。 整個迭代過程直到錯誤率足夠小或達到一定次數爲止。
1.1 實現原理:
數學基礎
圖例描述
實現描述
- 初始化樣本的權值爲1/n。
- 基於樣本與權值訓練弱分類器;
- 根據分類器對樣本進行判別,如果判別正確,此樣本的權值降低,判別錯誤,降低樣本的權值,同時 根據識別率計算出此分類器的權值;
- 利用改變權值的樣本訓練下一個分類器;
- 循環得到N個分類器與其對應的權值;
- 基於加權的分類器組合成爲最終的模型
adaboost算法模型簡單,不容易過擬合,無需調參,優點挺多。但是其實也是需要根據樣本類型來使用。
1.2 實例分析:
實例環境
sklearn + anconda + jupyter
實例步驟
- 數據:可以採用 datasets 的數據,在此作者使用的是自己整理的股票行情
- 訓練、測試數據歸一化
- 參數尋優可以使用GridSearch,在此不作贅述
參數列表:
- 代碼實現
#coding:utf-8
import time
import sklearn
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
from sklearn.externals import joblib
from sklearn import preprocessing # 數據預處理工具
from sklearn.ensemble import AdaBoostClassifier # adaboost算法
from sklearn.grid_search import GridSearchCV # 用於參數尋優
import matplotlib.pyplot as plt
from matplotlib import *
%matplotlib inline
start = time.clock()
min_max_scaler = preprocessing.MinMaxScaler()
# 讀取訓練數據 並數據規整化
raw_data = pd.read_csv('train_data.csv')
raw_datax = raw_data
X1_scaled = min_max_scaler.fit_transform(raw_datax.ix[:,3:7])
y1 = raw_datax['Y1']
y1 = list(y1)
# 讀取測試數據 並數據規整化
raw_datat = pd.read_csv('test_data.csv')
raw_datatx = raw_datat
X1t_scaled = min_max_scaler.fit_transform(raw_datatx.ix[:,3:7])
y1t = raw_datatx['Y1']
y1t = list(y1t)
print len(X1_scaled)
print len(X1t_scaled)
# print X1_scaled
# print X1t_scaled
end = time.clock()
print '運行時間:',end - start
# Fit model
start = time.clock()
regr_1 = DecisionTreeClassifier()
regr_2 = AdaBoostClassifier(base_estimator=DecisionTreeClassifier())
clf = regr_1.fit(X1_scaled, y1)
clf1 = regr_2.fit(X1_scaled, y1)
#save model
joblib.dump(clf1,'Adaboost_M0.pkl',compress=3)
clf1 = joblib.load('Adaboost_M0.pkl')
# Predict
y_1 = clf.predict(X1t_scaled)
y_2 = clf1.predict(X1t_scaled)
print '單純決策樹: ',clf.score(X1t_scaled,y1t)
print 'Adaboost_M0: ',clf1.score(X1t_scaled,y1t)
end = time.clock()
print end - start
1.3 方法總結
- adaboost 算法原理即迭代訓練過程中每次都會根據上一次訓練的分類結果重新分配訓練樣本的權重,以達到每次迭代訓練都作重訓練分類錯誤樣本的目的,最終模型分類較爲準確
1.運用注意點
2.優化方向點
2.GBDT算法
WIKI百科:
全稱(Gradient Boosting Decision Tree),梯度增強是用於迴歸和分類問題的機器學習技術,其以弱預測模型(通常是決策樹)的集合的形式產生預測模型。它與其他增強方法一樣以階段式方式構建模型,並且通過允許任意可微分損失函數的優化來概括它們。
梯度增強的想法起源於Leo Breiman 的觀察,增強可以被解釋爲對適當的成本函數的優化算法。隨後由Jerome H. Friedman 和Llew Mason,Jonathan Baxter,Peter Bartlett和Marcus Frean的更通用的功能梯度提升視角同時開發了顯式迴歸梯度提升算法。
通俗理解:
其實Boosting更像是一種思想,Gradient Boosting是一種Boosting的方法,它主要的思想是,每一次建立模型是在之前建立模型損失函數的梯度下降方向。損失函數(loss function)描述的是模型的好壞程度,損失函數越大,則說明模型越容易出錯(其實這裏有一個方差、偏差均衡的問題,但是這裏就假設損失函數越大,模型越容易出錯)。如果我們的模型能夠讓損失函數持續的下降,則說明我們的模型在不停的改進,而最好的方式就是讓損失函數在其梯度(Gradient)的方向上下降。
每次模型在梯度方向上的減少的部分,可以認爲是一個“小”的或者“弱”的模型,最終我們會通過加權(也就是每次在梯度方向上下降的距離)的方式將這些“弱”的模型合併起來,形成一個更好的模型。
2.1 實現原理
數學基礎:
圖例描述:
實現描述:
- 給定一個初始值
- 表示建立M棵決策樹(迭代M次)
- 表示對函數估計值F(x)進行Logistic變換
- 表示對於K個分類進行下面的操作(其實這個for循環也可以理解爲向量的操作,每一個樣本點xi都對 應 了K種可能的分類yi,所以yi, F(xi), p(xi)都是一個K維的向量,這樣或許容易理解一點)
- 表示求得殘差減少的梯度方向
- 表示根據每一個樣本點x,與其殘差減少的梯度方向,得到一棵由J個葉子節點組成的決策樹
- 爲當決策樹建立完成後,通過這個公式,可以得到每一個葉子節點的增益(這個增益在預測的時候用的)每個增益的組成其實也是一個K維的向量,表示如果在決策樹預測的過程中,如果某一個樣本點掉入了這個葉子節點,則其對應的K個分類的值是多少。比如說,GBDT得到了三棵決策樹,一個樣本點在預測的時候,也會掉入3個葉子節點上,其增益分別爲(假設爲3分類的問題):
(0.5, 0.8, 0.1), (0.2, 0.6, 0.3), (0.4, 0.3, 0.3),那麼這樣最終得到的分類爲第二個,因爲選擇分類2的決策樹是最多的。 - 將當前得到的決策樹與之前的那些決策樹合併起來,作爲新的一個模型
2.2 實例分析
實例環境
sklearn + anconda + jupyter
實例步驟
- 數據:可以採用 datasets 的數據,在此作者使用的是自己整理的股票行情
- 訓練、測試數據歸一化
- 參數尋優可以使用GridSearch,在此不作贅述
參數列表:
參數意義:
- 代碼實現:
#coding:utf-8
import time
import sklearn
import numpy as np
import pandas as pd
from numpy import *
from pandas import Series,DataFrame
from sklearn.externals import joblib
from sklearn import preprocessing # 數據預處理工具
from sklearn.ensemble import GradientBoostingClassifier # 梯度樹分類
from sklearn.tree import DecisionTreeClassifier # 決策數分類
from sklearn.grid_search import GridSearchCV # 用於參數尋優
import matplotlib.pyplot as plt
from matplotlib import *
%matplotlib inline
start = time.clock() # 計時
min_max_scaler = preprocessing.MinMaxScaler()
# 讀取訓練數據 並數據規整化
raw_data = pd.read_csv('train_data.csv')
raw_datax = raw_data
X1_scaled = min_max_scaler.fit_transform(raw_datax.ix[:,3:7])
y1 = raw_datax['Y1']
y1 = list(y1)
# 讀取測試數據 並數據規整化
raw_datat = pd.read_csv('test_data.csv')
raw_datatx = raw_datat
X1t_scaled = min_max_scaler.fit_transform(raw_datatx.ix[:,3:7])
y1t = raw_datatx['Y1']
y1t = list(y1t)
print len(X1_scaled)
print len(X1t_scaled)
# print X1_scaled
# print X1t_scaled
end = time.clock()
print '運行時間:',end - start
# Fit model
start = time.clock()
regr_1 = DecisionTreeClassifier()
regr_2 = GradientBoostingClassifier()
clf = regr_1.fit(X1_scaled, y1)
clf1 = regr_2.fit(X1_scaled, y1)
#save model
joblib.dump(clf1,'GBDT.pkl',compress=3)
clf1 = joblib.load('GBDT.pkl')
# Predict
y_1 = clf.predict(X1t_scaled)
y_2 = clf1.predict(X1t_scaled)
print '單純決策樹: ',clf.score(X1t_scaled,y1t)
print 'GBDT: ',clf1.score(X1t_scaled,y1t)
end = time.clock()
print end - start
2.3 方法總結
資料參考:http://blog.csdn.net/qq_30189255/article/details/51532442