使用LIME探索模型
編者按:模型的解釋性對於模型的應用和可信,有著重要意義。同時,也可以讓模型更透明,更公平,也更好地服務大眾,以降低模型多帶來的風險。如何對黑盒模型的解釋性做探索和研究,本文的LIME方法在一定程度上可以發揮作用和達成目的。
最近在工作中,我被要求幫助一些臨床醫生理解為什麼我的風險模型將特定的病人分類為高風險。就在這項工作之前,我在華盛頓大學偶然發現了一些資料科學家的工作,他們叫lime。LIME代表模型無關的區域性性可解釋演算法。我的想法是,通過在資料點附近的引數空間區域性擬合一個線性(又名“可解釋”)模型,我可以回答臨床醫生對特定患者提出的那些問題。我決定將lime作為一種解決方案,過去幾個月我一直專注於為我的風險模型實現這個直譯器。幸運的是,我還發現了一個R包,它實現了這個源自python的解決方案。
樣本資料
因此本文的第一步是找到一些公共資料來說明。我記得 ofollow,noindex" target="_blank"> James, Witten, Hastie和Tibshirani在《統計學學習導論》 中舉過一個例子。
我要用Heart.csv資料,可以通過以下連結下載:
library(readr) library(ranger) library(tidyverse) library(lime) dat <- read_csv("http://www-bcf.usc.edu/~gareth/ISL/Heart.csv") dat$X1 <- NULL
現在讓我們快速看一下資料:
Hmisc::describe(dat)
這個資料中的目標變數是AHD。這個標誌標識病人是否患有冠狀動脈疾病。如果我們能準確預測,臨床醫生可能會更好地治療這些病人,並希望幫助他們避免類似胸痛或更嚴重的心臟病發作等AHD症狀。
資料處理
對於預測模型,我選擇使用ranger執行的隨機森林模型,它並行化r中的隨機森林演算法。但是首先,一些資料清理是必要的。在替換缺失的值之後,我將把資料拆分為測試和訓練資料框。
# Replace missing values dat$Ca[is.na(dat$Ca)] <- -1 dat$Thal[is.na(dat$Thal)] <- "missing" ## 75% of the sample size smp_size <- floor(0.75 * nrow(dat)) ## set the seed to make your partition reproducible set.seed(123) train_ind <- sample(seq_len(nrow(dat)), size = smp_size) train <- dat[train_ind, ] test <- dat[-train_ind, ] mod <- ranger(AHD~., data=train, probability = TRUE, importance = "permutation") mod$prediction.error ## [1] 0.1326235
我們對OOB預測錯誤的快速粗略檢查告訴我們,我們的模型在預測AHR方面表現良好。現在的問題是向我們的醫生和護士描述為什麼我們相信某人是AHR的高危人群。在學習lime之前,我可能會做一些類似於下面程式碼的事情,首先檢視樹中哪些變數最重要。
plot_importance <- function(mod){ tmp <- mod$variable.importance dat <- data.frame(variable=names(tmp),importance=tmp) ggplot(dat, aes(x=reorder(variable,importance), y=importance))+ geom_bar(stat="identity", position="dodge")+ coord_flip()+ ylab("Variable Importance")+ xlab("") } # Plot the variable importance plot_importance(mod)
之後,我可能會看一些部分依賴圖來了解這些重要的變數在這個變數範圍內是如何變化的。然而,這種方法的缺點通常是我需要保持所有其他變數不變。如果我真的相信我的變數之間存在相互作用,那麼當其他變數發生變化時,部分依賴圖就會發生巨大的變化。
使用LIME解釋模型
進入LIME。如上所述,LIME的整個目的是提供一個本地可解釋的模型,以幫助我們理解,如果我們在許多排列中稍微調整其他變數,我們的預測將如何變化。在這種特殊情況下使用lime的第一步是新增一些函式,以便lime包知道如何處理ranger包的輸出。一旦我有了這些,我就可以使用lime()和explain()函式的組合來得到我需要的東西。在所有多元線性模型中,我們仍然有一個問題…相關的解釋變數。根據原始模型中變數的數量,我們可能需要將模型進行配對,只檢視最“有影響力”或“重要”的變數。在使用嶺迴歸或L2懲罰校正多共線性後,lime預設使用正向選擇或選擇係數較大的變數。如下所示,您還可以使用Lasso(即L1懲罰)選擇解釋的變數,或者使用“樹”方法使用xgboost最重要的變數。
# Train LIME Explainer expln <- lime(train, model = mod) preds <- predict(mod,train,type = "response") # Add ranger to LIME predict_model.ranger <- function(x, newdata, type, ...) { res <- predict(x, data = newdata, ...) switch( type, raw = data.frame(Response = ifelse(res$predictions[,"Yes"] >= 0.5,"Yes","No"), stringsAsFactors = FALSE), prob = as.data.frame(res$predictions[,"Yes"], check.names = FALSE) ) } model_type.ranger <- function(x, ...) 'classification' reasons.forward <- explain(x=test[,names(test)!="AHD"], explainer=expln, n_labels = 1, n_features = 4) reasons.ridge <- explain(x=test[,names(test)!="AHD"], explainer=expln, n_labels = 1, n_features = 4, feature_select = "highest_weights") reasons.lasso <- explain(x=test[,names(test)!="AHD"], explainer=expln, n_labels = 1, n_features = 4, feature_select = "lasso_path") reasons.tree <- explain(x=test[,names(test)!="AHD"], explainer=expln, n_labels = 1, n_features = 4, feature_select = "tree")
注意:使用當前版本的lime時,您可能會遇到feature_select = "lasso_path"選項的問題。要讓上面的程式碼執行在上面,您可以在這裡安裝我的改進版lime。
繪製解釋圖
現在我們已經有了所有的解釋,我最喜歡的lime包功能之一是plot_explain()函式。你可以很容易地為我們上面的每個選擇方法顯示最重要的變數,我們可以看到,在預測AHD的最具影響力的4個變數的選擇中,它們都是非常一致的。
plot_explanations(reasons.forward)
plot_explanations(reasons.ridge)
plot_explanations(reasons.lasso)
plot_explanations(reasons.tree)
感謝您閱讀關於lime的快速教程。我還想探討這個包的更多內容。特別是它在影象和文字分類中的應用。
作者:Mark Nielsen 原文連結: https://www.nielsenmark.us/2018/11/09/exploring-models-with-lime/
版權宣告: 作者保留權利。文章為作者獨立觀點,不代表資料人網立場。嚴禁修改,轉載請註明原文連結:http://shujuren.org/article/783.html
資料人網: 資料人學習,交流和分享的平臺,誠邀您創造和分享資料知識,共建和共享資料智庫。