引入業(yè)務(wù)先驗(yàn)約束的樹模型(Python)

一、模型解釋性的意義

機(jī)器學(xué)習(xí)業(yè)務(wù)應(yīng)用以輸出決策判斷為目標(biāo)??山忉屝允侵溉祟惸軌蚶斫鉀Q策原因的程度。機(jī)器學(xué)習(xí)模型的可解釋性越高,人們就越容易理解為什么做出某些決定或預(yù)測(cè)。模型可解釋性指對(duì)模型內(nèi)部機(jī)制的理解以及對(duì)模型結(jié)果的理解。其重要性體現(xiàn)在:建模階段,輔助開發(fā)人員理解模型,進(jìn)行模型的對(duì)比選擇,必要時(shí)優(yōu)化調(diào)整模型;在投入運(yùn)行階段,向業(yè)務(wù)方解釋模型的內(nèi)部機(jī)制,對(duì)模型結(jié)果進(jìn)行解釋。比如基金推薦模型,需要解釋:為何為這個(gè)用戶推薦某支基金。

在機(jī)器學(xué)習(xí)應(yīng)用中,有些領(lǐng)域(如金融風(fēng)控)的模型決策很看重業(yè)務(wù)的解釋性,通過(guò)業(yè)務(wù)先驗(yàn)的知識(shí)加以調(diào)整并監(jiān)控模型、以創(chuàng)造更值得信任的、安全可靠的模型。



追求業(yè)務(wù)解釋性,可以減少一些歧視、違規(guī)、不合理的特征決策,對(duì)模型帶來(lái)類似正則化效果,可以減少統(tǒng)計(jì)噪音的影響(減少過(guò)擬合),有更好的泛化效果。

但是,追求業(yè)務(wù)解釋性是個(gè)繁瑣的事情,首先你得有足夠的業(yè)務(wù)應(yīng)用知識(shí)的理解,其次還要手動(dòng)不停地調(diào)整一版又一版的模型。業(yè)界上對(duì)合理的業(yè)務(wù)解釋性可以提升模型的效果這是肯定的,特別是在小數(shù)據(jù)、數(shù)據(jù)不穩(wěn)定的情況,

一個(gè)金融領(lǐng)域簡(jiǎn)單的例子,如現(xiàn)有的1000條樣本顯示,有條數(shù)據(jù)規(guī)律:申請(qǐng)貸款的次數(shù)低于10,用戶的貸款逾期概率就越大。但是結(jié)合業(yè)務(wù)來(lái)看,一個(gè)人頻繁申請(qǐng)貸款,其負(fù)債、還款能力肯定是有問(wèn)題的,這時(shí)僅憑這條現(xiàn)有數(shù)據(jù)規(guī)律去決策風(fēng)險(xiǎn)有點(diǎn)大,很大概率這條決策在更多樣本的情況下就是失效的。

我們通過(guò)解釋性的工具剖析模型決策,當(dāng)模型決策不符合合理的業(yè)務(wù)邏輯或法規(guī)什么的 ,這時(shí),就很有必要做一些特征選擇,調(diào)整模型,以符合業(yè)務(wù)解釋性:

二、引入業(yè)務(wù)先驗(yàn)約束的樹模型(GBDT)

但上面兩種方法都比較依賴于手動(dòng)微調(diào)模型,以符合業(yè)務(wù)解釋性。為什么不直接在訓(xùn)練過(guò)程中,直接依據(jù)業(yè)務(wù)先驗(yàn)知識(shí)輔助模型訓(xùn)練?

在此,本文另提出一個(gè)思路,通過(guò)在樹模型學(xué)習(xí)訓(xùn)練過(guò)程(樹節(jié)點(diǎn)的分裂過(guò)程),簡(jiǎn)單引入個(gè)業(yè)務(wù)先驗(yàn)約束,以符合決策過(guò)程符合業(yè)務(wù)解釋性。


大致步驟是,

在 GBDT訓(xùn)練代碼中,配置特征業(yè)務(wù)邏輯性的約束

如 當(dāng)前二分類數(shù)據(jù)集有age,weight兩個(gè)特征。假設(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)分裂時(shí)加入業(yè)務(wù)邏輯判斷(約束)

GBDT是cart二叉決策樹集成實(shí)現(xiàn)的,對(duì)于每一棵cart樹,我們會(huì)遍歷所有特征,嘗試以每一特征值作為決策的分裂點(diǎn)。我們可以在這里加入約束限制,如年齡age特征,我們認(rèn)為它和標(biāo)簽值是負(fù)相關(guān)的,那么對(duì)于每次分類age<特征閾值的左邊分支的樣本群體的標(biāo)簽均值應(yīng)該大于右邊分支的(反之亦然)。如果樹生長(zhǎng)的特征分裂不符合業(yè)務(wù)邏輯的,則會(huì)略過(guò),繼續(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
  • 編程語(yǔ)言:Python3
  • Python庫(kù):pandas、PIL、pydotplus,
    其中pydotplus庫(kù)會(huì)自動(dòng)調(diào)用Graphviz,所以需要去Graphviz官網(wǎng)下載graphviz的-2.38.msi
    ,先安裝,再將安裝目錄下的bin添加到系統(tǒng)環(huán)境變量,此時(shí)如果再報(bào)錯(cuò)可以重啟計(jì)算機(jī)。詳細(xì)過(guò)程不再描述,網(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 回歸/二分類/多分類測(cè)試文件
  • 二分類GBDT測(cè)試,運(yùn)行如下命令:

    python example.py --model binary_cf

  • 還未增加約束的GBDT



    可見在原來(lái)的數(shù)據(jù)規(guī)律里面,age和標(biāo)簽是呈現(xiàn)正相關(guān)的,也就是age越高,標(biāo)簽越高。

  • 當(dāng)我們?cè)趀xample.py中新增配置業(yè)務(wù)先驗(yàn)約束(令age需要和標(biāo)簽呈負(fù)相關(guān))的GBDT。此時(shí),在本實(shí)驗(yàn)數(shù)據(jù)集age特征的各分裂點(diǎn)可能都是不符合業(yè)務(wù)邏輯,都沒有選用,如下運(yùn)行結(jié)果:

def run(args):
    ### 配置特征業(yè)務(wù)邏輯性得約束###
    feas_logit = {'age': -1}
    ### 配置end###

個(gè)人實(shí)踐經(jīng)驗(yàn),當(dāng)加入的業(yè)務(wù)先驗(yàn)比較合理的情況,模型泛化(測(cè)試集)誤差可能會(huì)更低(訓(xùn)練集的誤差通常會(huì)增加),或者訓(xùn)練-測(cè)試兩者差異更小了。模型有更好的泛化能力。有興趣的童鞋可以在更大數(shù)據(jù)集里面試驗(yàn)下,以便更客觀地評(píng)估下加入業(yè)務(wù)約束的模型效果差異。

參考鏈接
GBDT算法原理以及實(shí)例理解(含代碼):https://blog.csdn.net/zpalyq110/article/details/79527653

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 邏輯回歸由于其簡(jiǎn)單高效、易于解釋,是工業(yè)應(yīng)用最為廣泛的模型之一,比如用于金融風(fēng)控領(lǐng)域的評(píng)分卡、互聯(lián)網(wǎng)的推薦系統(tǒng)。上...
    算法進(jìn)階閱讀 2,696評(píng)論 0 1
  • 本文將會(huì)講述計(jì)算廣告(主要是DSP)中的主要模塊、用到的策略及其場(chǎng)景。筆者希望大家能和ta一樣,在了解廣告業(yè)務(wù)的同...
    allin8116閱讀 1,785評(píng)論 0 1
  • 在信貸的風(fēng)控模型中最常用、最經(jīng)典的可能要屬評(píng)分卡了,所謂評(píng)分卡就是給信貸客戶進(jìn)行打分,按照不同業(yè)務(wù)場(chǎng)景可為貸前、貸...
    程序員的隱秘角落閱讀 3,691評(píng)論 0 3
  • 本文示例沿用之前文章的數(shù)據(jù):一文梳理金融風(fēng)控建模全流程(Python)[https://mp.weixin.qq....
    算法進(jìn)階閱讀 965評(píng)論 0 2
  • 如果說(shuō)存在這樣一個(gè)應(yīng)用,在構(gòu)建這個(gè)應(yīng)用的時(shí)候需要應(yīng)用到大規(guī)模數(shù)據(jù)處理、數(shù)據(jù)挖掘、信息檢索、預(yù)測(cè)理論、人工智能、認(rèn)知...
    stayrascal閱讀 848評(píng)論 0 2

友情鏈接更多精彩內(nèi)容