一辈双、模型解釋性的意義
機(jī)器學(xué)習(xí)業(yè)務(wù)應(yīng)用以輸出決策判斷為目標(biāo)≌撸可解釋性是指人類能夠理解決策原因的程度辐马。機(jī)器學(xué)習(xí)模型的可解釋性越高,人們就越容易理解為什么做出某些決定或預(yù)測局义。模型可解釋性指對模型內(nèi)部機(jī)制的理解以及對模型結(jié)果的理解喜爷。其重要性體現(xiàn)在:建模階段,輔助開發(fā)人員理解模型萄唇,進(jìn)行模型的對比選擇檩帐,必要時優(yōu)化調(diào)整模型;在投入運(yùn)行階段另萤,向業(yè)務(wù)方解釋模型的內(nèi)部機(jī)制湃密,對模型結(jié)果進(jìn)行解釋诅挑。比如基金推薦模型,需要解釋:為何為這個用戶推薦某支基金泛源。
在機(jī)器學(xué)習(xí)應(yīng)用中拔妥,有些領(lǐng)域(如金融風(fēng)控)的模型決策很看重業(yè)務(wù)的解釋性,通過業(yè)務(wù)先驗(yàn)的知識加以調(diào)整并監(jiān)控模型达箍、以創(chuàng)造更值得信任的没龙、安全可靠的模型。
追求業(yè)務(wù)解釋性缎玫,可以減少一些歧視硬纤、違規(guī)、不合理的特征決策赃磨,對模型帶來類似正則化效果筝家,可以減少統(tǒng)計(jì)噪音的影響(減少過擬合),有更好的泛化效果邻辉。
但是溪王,追求業(yè)務(wù)解釋性是個繁瑣的事情,首先你得有足夠的業(yè)務(wù)應(yīng)用知識的理解值骇,其次還要手動不停地調(diào)整一版又一版的模型在扰。業(yè)界上對合理的業(yè)務(wù)解釋性可以提升模型的效果這是肯定的,特別是在小數(shù)據(jù)雷客、數(shù)據(jù)不穩(wěn)定的情況,
一個金融領(lǐng)域簡單的例子桥狡,如現(xiàn)有的1000條樣本顯示搅裙,有條數(shù)據(jù)規(guī)律:申請貸款的次數(shù)低于10,用戶的貸款逾期概率就越大裹芝。但是結(jié)合業(yè)務(wù)來看部逮,一個人頻繁申請貸款,其負(fù)債嫂易、還款能力肯定是有問題的兄朋,這時僅憑這條現(xiàn)有數(shù)據(jù)規(guī)律去決策風(fēng)險(xiǎn)有點(diǎn)大,很大概率這條決策在更多樣本的情況下就是失效的怜械。
我們通過解釋性的工具剖析模型決策颅和,當(dāng)模型決策不符合合理的業(yè)務(wù)邏輯或法規(guī)什么的 ,這時缕允,就很有必要做一些特征選擇峡扩,調(diào)整模型,以符合業(yè)務(wù)解釋性:
如經(jīng)典的邏輯回歸-lr 障本,需要不斷憑借業(yè)務(wù)含義調(diào)整特征分箱決策的單調(diào)性:
一文梳理金融風(fēng)控建模全流程(Python)如樹模型教届,一個簡單的剪枝調(diào)整業(yè)務(wù)解釋性的方法响鹃。
二、引入業(yè)務(wù)先驗(yàn)約束的樹模型(GBDT)
但上面兩種方法都比較依賴于手動微調(diào)模型案训,以符合業(yè)務(wù)解釋性买置。為什么不直接在訓(xùn)練過程中,直接依據(jù)業(yè)務(wù)先驗(yàn)知識輔助模型訓(xùn)練强霎?
在此忿项,本文另提出一個思路,通過在樹模型學(xué)習(xí)訓(xùn)練過程(樹節(jié)點(diǎn)的分裂過程)脆栋,簡單引入個業(yè)務(wù)先驗(yàn)約束倦卖,以符合決策過程符合業(yè)務(wù)解釋性。
大致步驟是椿争,
在 GBDT訓(xùn)練代碼中怕膛,配置特征業(yè)務(wù)邏輯性的約束
如 當(dāng)前二分類數(shù)據(jù)集有age,weight兩個特征秦踪。假設(shè)我們從業(yè)務(wù)理解上褐捻,認(rèn)為年齡age應(yīng)該和標(biāo)簽是呈現(xiàn)負(fù)相關(guān)的,年齡數(shù)值越大椅邓,標(biāo)簽值應(yīng)該要越小柠逞。那我們就可以配置特征約束的字典feas_logit, 配置特征age業(yè)務(wù)邏輯性的約束, 新增{'age': -1}, 其中-1代表該特征與標(biāo)簽的業(yè)務(wù)規(guī)律約束為負(fù)相關(guān)景馁,+1代表正相關(guān)板壮。暫不支持非單調(diào)關(guān)系的業(yè)務(wù)約束配置。
# 配置特征業(yè)務(wù)邏輯性的約束
feas_logit = {'age': -1}
特征節(jié)點(diǎn)分裂時加入業(yè)務(wù)邏輯判斷(約束)
GBDT是cart二叉決策樹集成實(shí)現(xiàn)的合住,對于每一棵cart樹绰精,我們會遍歷所有特征,嘗試以每一特征值作為決策的分裂點(diǎn)透葛。我們可以在這里加入約束限制笨使,如年齡age特征,我們認(rèn)為它和標(biāo)簽值是負(fù)相關(guān)的僚害,那么對于每次分類age<特征閾值的左邊分支的樣本群體的標(biāo)簽均值應(yīng)該大于右邊分支的(反之亦然)硫椰。如果樹生長的特征分裂不符合業(yè)務(wù)邏輯的,則會略過萨蚕,繼續(xù)其他特征值的搜索靶草。
# 完整代碼:[aialgorithm](https://github.com/aialgorithm/Blog)
for feature in self.features:
self.logger.info(('----劃分特征:', feature))
feature_values = now_data[feature].unique()
for fea_val in feature_values:
# 嘗試劃分
left_index = list(now_data[feature] < fea_val)
right_index = list(now_data[feature] >= fea_val)
left_labelvalue = now_data[left_index][self.target_name]
right_labelvalue = now_data[right_index][self.target_name]
# 該特征劃分 加入判斷業(yè)務(wù)邏輯合理性約束##
if feature in self.feas_logit: # 如果該劃分不符合業(yè)務(wù)合理性約束則繼續(xù)搜索其他劃分
if not self.feas_logit[feature]*right_labelvalue.mean() > self.feas_logit[feature]*left_labelvalue.mean():
continue
# 計(jì)算劃分后的損失
left_se = calculate_se(left_labelvalue)
right_se = calculate_se(right_labelvalue)
sum_se = left_se + right_se
self.logger.info(('------劃分值:%.3f,左節(jié)點(diǎn)損失:%.3f,右節(jié)點(diǎn)損失:%.3f,總損失:%.3f' %
(fea_val, left_se, right_se, sum_se)))
if se is None or sum_se < se:
split_feature = feature
split_value = fea_val
se = sum_se
left_index_of_now_data = left_index
right_index_of_now_data = right_index
代碼運(yùn)行
- 依賴環(huán)境:
- 操作系統(tǒng):Windows/Linux
- 編程語言:Python3
- Python庫:pandas、PIL门岔、pydotplus爱致,
其中pydotplus庫會自動調(diào)用Graphviz,所以需要去Graphviz官網(wǎng)下載graphviz的-2.38.msi
寒随,先安裝糠悯,再將安裝目錄下的bin
添加到系統(tǒng)環(huán)境變量帮坚,此時如果再報(bào)錯可以重啟計(jì)算機(jī)。詳細(xì)過程不再描述互艾,網(wǎng)上很多解答试和。
文件結(jié)構(gòu)(修改前GBDT手寫代碼如參考文末鏈接):
- | - GBDT 主模塊文件夾
- | --- gbdt.py 梯度提升算法主框架
- | --- decision_tree.py 單顆樹生成,包括節(jié)點(diǎn)劃分和葉子結(jié)點(diǎn)生成
- | --- loss_function.py 損失函數(shù)
- | --- tree_plot.py 樹的可視化
- | - example.py 回歸/二分類/多分類測試文件
-
二分類GBDT測試纫普,運(yùn)行如下命令:
python example.py --model binary_cf
-
還未增加約束的GBDT
可見在原來的數(shù)據(jù)規(guī)律里面阅悍,age和標(biāo)簽是呈現(xiàn)正相關(guān)的,也就是age越高昨稼,標(biāo)簽越高节视。
當(dāng)我們在example.py中新增配置業(yè)務(wù)先驗(yàn)約束(令age需要和標(biāo)簽呈負(fù)相關(guān))的GBDT。此時假栓,在本實(shí)驗(yàn)數(shù)據(jù)集age特征的各分裂點(diǎn)可能都是不符合業(yè)務(wù)邏輯寻行,都沒有選用,如下運(yùn)行結(jié)果:
def run(args):
### 配置特征業(yè)務(wù)邏輯性得約束###
feas_logit = {'age': -1}
### 配置end###
個人實(shí)踐經(jīng)驗(yàn)匾荆,當(dāng)加入的業(yè)務(wù)先驗(yàn)比較合理的情況拌蜘,模型泛化(測試集)誤差可能會更低(訓(xùn)練集的誤差通常會增加),或者訓(xùn)練-測試兩者差異更小了牙丽。模型有更好的泛化能力简卧。有興趣的童鞋可以在更大數(shù)據(jù)集里面試驗(yàn)下,以便更客觀地評估下加入業(yè)務(wù)約束的模型效果差異烤芦。
參考鏈接
GBDT算法原理以及實(shí)例理解(含代碼):https://blog.csdn.net/zpalyq110/article/details/79527653