當前位置:
首頁 > 最新 > 長文詳解自然語言處理演算法xgboost和python實戰

長文詳解自然語言處理演算法xgboost和python實戰

|小修很早就想總結一下xgboost的內容,但是每次看到一大堆公式就頭大,而且網上很多資料很多都不全,下文第一部分是根據xgboost的官方中文文檔編寫的。純粹是總結學習,如有侵權還請告知。

xgboost是大規模並行boosted tree的工具,它是目前最快最好的開源boosted tree工具包,比常見的工具包快10倍以上。在數據科學方面,有大量的kaggle選手選用它進行數據挖掘比賽,它也是大家常用的一種處理自然語言的演算法,在有些情況下,xgboost甚至能夠比神經網路的結果要好(小修之前測試過各種模型對一特定文本語言分類的性能)。在工業界規模方面,xgboost的分散式版本有廣泛的可移植性,支持很多平台運行,並且保留了單機並行版本的各種優化,使得它可以很好地解決於工業界規模的問題。

1

Boosted Trees 介紹

XGBoost是「Extreme Gradient Boosting」的縮寫,這裡使用監督學習的元素以獨立和有原則的方式解釋boosted trees (增強樹)。

監督學習的要素

這裡先從XGBoost用於監督學習問題開始, 假設訓練數據xi,目標變數為yi。這裡先回顧一下監督學習的重要組成部分。

模型和參數

監督學習中的模型通常是指給定輸入xi如何去預測輸出yi的數學結構,例如一個常見的模型是線性回歸,其中的預測是由yi= sum(wjxij)的方式給出,這是加權輸入特徵的線性組合疊加的方式。其實這裡的預測y可以有不同的解釋,取決於做的任務。線性回歸中,係數w為該模型的參數,一般是需要從數據中學習的未確定的部分。

目標函數:訓練損失+正則

基於對yi的不同理解,我們可以得到不同的問題,比如回歸,分類,排序等,我們需要找到一種方法來找到訓練數據的最佳參數,為了做到這一點,需要定義個目標函數,以給定一組數據來衡量模型的性能。對於目標函數,一般包含訓練損失函數以及正則化項,。一般目標函數如下式所示:

其中L是訓練損失函數,後面一項為正則化項,目標函數和各項都是參數的函數,訓練損失衡量的是數據對訓練數據的預測性,比如常用的訓練損失函數就是預測結果和目標結果的均方誤差,另一個常用的損失函數是logistic回歸的損失函數:

正則化項是使用者通常忘記添加的部分,正則化項控制模型的複雜度,有助於避免過擬合,比如下面一圖對於在不同的損失函數和正則化項下,對數據點的擬合結果。

對於線性模型常見的正則化有L2正則和L1正則,這樣的目標函數的設計來自於統計學習中的一個重要概念,就是偏差-方差的權衡(bias-variance tradeoff),其中偏差可以理解為假設我們有無限多數據的時候,可以訓練出最好的模型所拿到的誤差,而方差是因為只有有限數據的隨機性帶來的誤差,目標中的誤差函數是為了讓模型儘可能去擬合訓練數據,這樣可以得到一個比較小偏差的模型,而正則化項則鼓勵更加簡單的模型,因為模型簡單之後,有限數據擬合出來的結果隨機性比較小,不易過擬合,使得最後模型的預測更加穩定。

Tree ensembles (樹集成)

上文介紹的都是監督學習的基本內容,下面來介紹關於xgboost的模型部分:樹集成。樹集成模型是一組classification and regression trees (CART)(分類回歸樹)。下面是一個簡單的例子,它可以分類是否有人喜歡電腦。

把一個家庭的成員分成不同的葉子,並把他們分配到相應的葉子節點上,CART與決策樹有些不同,就是葉子包含決策值,在CART中,每個葉子都有一個真實的分數,這樣就超越了簡單的分類。通常情況下,單顆樹由於過於簡單而不夠強大到可以支持在實踐中使用,實際使用的是所謂的樹集成模型,它將多棵樹的預測加到一起。

上圖示兩個樹集成的例子,將每棵樹的預測分數加起來得到最終的分數,如果你看一下這個例子,一個重要的事實就是兩棵樹互相補充,在數學上表示,可以表示為下式所描述的模型:

其中K是樹的數量,f是函數空間F的函數,F是所有可能的CARTs的集合,所以我們的優化目標可以寫成下式所示:

這裡需要點出的是隨機森林(random forests)的模型就是樹集成,所以隨機森林和增強樹(boosted trees)在模型沒有什麼不同。不同之處只是在於我們如何訓練它們,這意味著如果寫一個樹集成的預測服務,你只需要編寫它們中的一個,它們應該直接為隨機森林和增強樹工作,這也是監督學習基石元素的一個例子。

Tree Boosting

在介紹完模型之後,這裡介紹如何去訓練學習樹,按照一般監督學習模型的處理思路,需要定義一個合理的目標函數,然後嘗試去優化這一目標函數。

這裡假設有如下所示的目標函數,當然它是需要飽含訓練損失和正則化的:

另外還有一個問題,為了每一步選擇一個好的樹,就需要添加一個優化目標的方法:

如果使用均方誤差作為損失函數,它將是下面的形式:

均方誤差的形式比較友好,具有一階項(通常稱為殘差)和二次項,對於其他形式的損失,獲得這麼好的形式並不是那麼容易,所以在一般情況下,我們把損失函數的泰勒展開到二階

其中gi和hi的定義為:

我們刪除了所有的常量之後,t步驟中的具體目標就變成了:

這成為了新樹的優化目標,這個定義的一個重要優點是它只依賴於gi和hi,這就是xgboost如何支持自定義損失函數,我們可以使用完全相同的i和hi作為輸入的求解器來對每個損失函數進行優化,包括邏輯回歸(logistic regression),權重邏輯回歸(weight logistic regression)。

模型複雜度

我們已經介紹了訓練步驟,但是我們還需要定義樹的複雜度,這裡首先改進一棵樹的定義f(x) 如下:

這裡w是樹葉上的分數向量,q是將每個數據點分配給葉子的函數,T是樹葉的數量,在XGBoost中,我們將複雜度定義為:

當然有不止一種方法來定義複雜度,但是這個具體的方法在實踐中運行良好,正則化是大多樹的包容易忽略的一部分,這是因為傳統的樹學習演算法的只強調提高不純性(impurity),而複雜度控制則是啟發式的。

The structure score (結構分數)

這是derivation的神奇部分,在對樹模型進行重新格式化之後,我們可以用第t棵樹來編寫目標值:

其中Ii= 是分配給第j個葉子的數據點的索引集合,需要注意的是,在第二行中,我們改變了總和的索引,因為同一葉子上的所有數據點都得到了相同的分數,我們可以通過定義Gj和Hj來近一步壓縮表達式:

在這個等式中wj是相互獨立的,形式Gjwj+1/2(Hj + lamda)wj*wj是二次的,對於給定的結構q(x)的最好的wj,我們可以得到最好的客觀規約:

最後一個方程度量一個結構q(x)到底有多好

這一切看起來有些複雜,可以看一下上面的圖片,看看分數是如何計算的,基本上,對於一個給定的樹結構,我們把統計gi和hi推到它們所屬的葉子上,統計數據加和到一起,然後使用公式計算樹是多好,除了考慮到模型的複雜度,這個分數就像決策樹中的雜質測量一樣(例如:熵和Gini係數)。

學習樹結構

既然有來一個方法來衡量一棵樹有多好,理想情況下我們會列舉所有可能的樹並挑選出最好的樹,在實踐中,這種方法是比較棘手的,所以我們會盡量一次優化樹的一個層次,具體來說,我們試圖將一片葉子分成兩片,並得到分數(這裡使用Gini係數):

這個公式可以分解為1)新左葉上的得分,2)新右葉上得分,3)原始葉子上的得分,4)附加葉子上的正則化,我們可以在這裡看到一個重要的事實:如果增益小於gamma,我們最好不要添加那個分支,這正是基於樹模型的剪枝技術。對於真實有價值的數據,通常需要尋找一個最佳的分割,為了有效地做到這一點,我們把所有的實例按照排序順序排列,如下圖所示:

從左到右的掃描就足以計算所有可能的拆分解決方案的結構得分,我們可以有效找到最佳的拆分。

2

xgboost的安裝

1.xgboost的安裝有一些依賴包,所以在安裝xgboost之前需要安裝這些依賴包,為了方便安裝,這裡推薦直接安裝anaconda,這裡面集成了絕大多數的第三方庫.

2.xgboost可以在官網上下載,下載下來

3: 這裡以liunix系統安裝過程為例子介紹安裝過程:

首先需要檢查linux系統是不是安裝了gcc-c++,檢查命令為:

rpm -qa grep gcc

如果發現沒有安裝可以使用如下命令安裝:

yum install gcc-c++

確認gcc-c++已經安裝之後,可以開始編譯和安裝工作了,然後進入到下載的xgboost的文件夾中使用下面的命令進行:

make

cd python-package

python setup.py install --user

最後驗證,在終端中輸入python,進入python編譯器,輸入import xgboost,如果沒有報錯,則按裝成功。

3

python實踐xgboost:對文本進行分類

這裡我只給出xgboost_model的核心代碼,如下所示,至於xgboost_model的參數可以根據之前小修介紹的jieba分詞和Tfidf獲取每條文本去獲取訓練文本和測試文本的weight:

在頭文件中需要包含: import xgboost as xgb.

這裡介紹xgboost中的一些參數,當然一些參數可以對照第一部分的內容進行理解:

xgboost所有的參數可以分為三類: 1. 通用參數:宏觀函數控制,2. Booster參數: 控制每一步的booster, 3. 學習目標參數:控制訓練目的的表現。

1: 通用參數:

booster [默認是gbtree]:gbtree基於樹的模型,gbliner為基於線性模型

silent[默認為0]:值為1時,靜默模式開啟,不會輸出任何信息

nthread[默認值為最大可能的線程數]:這個參數用來進行多線程式控制制,應當輸入系統的核數,

2: booster參數

這裡只介紹tree booster的,因為它的表現遠勝於linear booster,所以linear booster一般很少用

eta[默認0.3]:類似於learning rate參數,通過減少每一步的權重,可以提高模型的魯棒性,常用的值為0.2,0.3

max_depth[默認6]:這個值為樹的最大深度,max_depth越大,模型會學到更具體更局部的樣本,常用的為6.

gamma[默認為0]: gamma為指定了節點分裂所需要的最小損失函數下降值,這個參數的值越大,演算法越保守,這個參數的值和損失函數息息相關。

subsample[默認為1]:這個參數控制對於每棵樹,隨機採樣的比例,減少這個參數的值,演算法會更加保守,避免過擬合,但是如果這個值設置的過小,它可能會導致前擬合,常用的值為0.7-1

colsample_bytree[默認1]:用來控制每棵樹隨機採用列數的佔比,常用是0.7-1。

3: 學習目標參數

objective[默認reg:linear]:這個參數定義需要被最小化的損失函數,binary:logistic 而分類的邏輯回歸,返回預測的概率,multi:softmax使用softmax的多分類器,返回預測的類別,這種情況下,還需要多設一個參數: num_class(類別數目)。multi: softprob 和multi: softmax參數一樣,但是返回的是每個數據屬於各個類別的概率。

eval_metric[默認取決於objective參數的取值]:對於有效數據的度量方法,對於回歸問題,默認是rmse,對於分類問題,默認值是error,其他的值:rmse均方根誤差,mae平均絕對誤差,logloss負對數似然函數值,error二分類錯誤率,merror為多分類錯誤率,auc為曲線下面積。

seed[默認0]:隨機樹的種子,設置可以復現隨機數據的結果。

參考內容:

[1] http://xgboost.apachecn.org/cn/latest/model.html

自然語言處理技術

關注微信號每天收聽我們的消息

自然語言處理技術為您推送精品閱讀

每天一個知識點,健康生活每一天

歡迎關注公眾號學習交流


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 自然語言處理技術 的精彩文章:

自然語言處理之中文分詞器-jieba分詞器詳解及python實戰

TAG:自然語言處理技術 |