如何利用gcForest爲特徵打分?

 

樓主前面有一篇博客提到了周志華老師又一力作:gcForest:探索深度神經網絡以外的方法,不瞭解的小夥伴可以翻前面的博客。

這個算法的確比傳統的集成樹算法:RandomForest,XGBoost,lightGBM都要優秀,而且引入層的概念後很好的解決了集成樹算法容易過擬合的問題。

簡單講他就是借鑑了深度學習分層訓練的思路,將機器學習中常用的RandomForest,XGBoost,LogisticRegression等算法進行集成,通過模型和樣本的多樣性讓模型更加優秀。

正是因爲它這種集成思想,反而抹殺了傳統集成樹算法的一大優勢,gcForest無法給特徵打分。原因很簡單,它每層用的基學習器像前面提到的RandomForest,XGBoost提取特徵的方式是不一樣的:

首先RandomForest作爲Bagging的代表,它是通過給指定特徵X隨機加入噪聲,通過加入噪聲前後袋外數據誤差的差值來衡量該特徵的重要程度。具體請參考:隨機森林之特徵選擇;而XGBoost作爲典型的Boosting算法提取特徵的方式和RandomForest有很大的不同,看了下他的打分函數有weight,gain,cover三種方式,其中默認的是weight,這種方式其實就是統計特徵X在每棵決策樹當中出現的次數,最後特徵X出現的次數之和就作爲特徵X的最後的得分。我們可以看出這兩種算法打分方式不同,得到的數值也不是一個量綱的。同樣LogisticRegression提取特徵的方式也和前兩者不一樣。

並且gcForst還提供了用戶自己添加基學習器的接口(添加方法請了解:gcForest官方代碼詳解),也就意味着gcForest還可以使用更多的基學習器,如果要封裝一個提取重要特徵的方法,就要考慮太多太多,每進來一個基學習器都要改變特徵打分的方法。

綜上所述,我覺得也是gcForest作者沒有封裝特徵打分方法的原因。

基於我的問題,我做了一些思考。我處理的數據用RandomForest,XGBoost都能得到不錯的結果,我們知道RandomForest可以很好的減少方差,XGBoost可以很好的減少偏差。爲了構建一個低偏差和低方差的模型,我想將這兩種算法進行集成。所以在gcForest中我只用了這兩個基學習器。

通過對RandomForest,XGBoost打分函數的學習,我和小夥伴shi.chao 對gcForest封裝了一個特徵打分方法,利用的還是源碼裏手寫數字識別的數據,每層只有RandomForest,XGBoost,爲了方便調試,就構建了兩層。

大體思想如下:

在源碼目錄:lib->gcforest->cascade->cascade_classifier.py  fit_transform()方法中進行了一些操作。這個方法就是gcForest進行模型訓練的函數。上面也提到了不同的算法特徵打分的方法是不一樣的,所以在這裏需要通過變量est_configs["type"]對基學習器類型進行判斷。如果是RandomForest,就直接調用RandomForest的打分函數,得到該基學習器返回的一個map,其中包含特徵名稱和得分,這裏用一個臨時變量保存,等到下一層獲取RandomFores打分函數得到的另一個map,然後將這個兩個map合併,相同key的將value累加,最後得到一個final_feature_rf_importance_list,是整個gcForest所有層中RandomFores得到的特徵得分。XGBoost,類似操作。具體見代碼註釋。

感興趣的小夥伴可以在這個基礎上繼續對另外的基學習器特徵打分算法進行封裝。最後gcForest的特徵得分:可以是各個基學習器特徵得分的一個融合。

比如我的模型中只用到了RandomForest和XGBoost,最後gcForest的第i個特徵的得分可以這樣表示:

Zi  = w1 * Xi/sum(X) + w2 * Yi/sum(Y)

其中Xi代表RandomForest中第i個特徵的得分,Yi代表XGBoost中第i個特徵的得分,這兩個值雖然不是一個量綱,但是通過處以它們全部特徵之和就可以得到該特徵在它的模型中的相對特徵,最後通過設置w1,w2的係數,可以調整兩種模型在gcForest中的重要程度。

代碼已經開源到github:https://github.com/phyllisyuell/gcForest-master-feature

歡迎各位交流學習,批評指正。

有問題請聯繫,一起討論:[email protected]

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章