R 使用lightgbm Tweedie目标将形状值从原始单位转换为本机单位?

R 使用lightgbm Tweedie目标将形状值从原始单位转换为本机单位?,r,lightgbm,shap,tweedie,R,Lightgbm,Shap,Tweedie,编辑: Shapley加法解释(SHAP值)的用途是了解每个特征对模型预测的贡献。对于某些目标,例如以RMSE作为目标函数的回归,形状值采用标签值的本机单位。例如,如果估算住房成本,SHAP值可以表示为美元。正如您将在下面看到的,并非所有目标函数都是如此。特别是,Tweedie回归目标不会产生本机单位的SHAP值。这是一个需要解释的问题,因为我们想知道住房成本是如何受到+/-美元特征的影响的 考虑到这些信息,我的问题是:在用Tweedie回归目标解释模型时,如何将每个特征的形状值转换为目标标签的

编辑

Shapley加法解释(SHAP值)的用途是了解每个特征对模型预测的贡献。对于某些目标,例如以RMSE作为目标函数的回归,形状值采用标签值的本机单位。例如,如果估算住房成本,SHAP值可以表示为美元。正如您将在下面看到的,并非所有目标函数都是如此。特别是,Tweedie回归目标不会产生本机单位的SHAP值。这是一个需要解释的问题,因为我们想知道住房成本是如何受到+/-美元特征的影响的

考虑到这些信息,我的问题是:在用Tweedie回归目标解释模型时,如何将每个特征的形状值转换为目标标签的数据空间

我不知道目前有任何包实现了这样的转换

我用lightgbm的R实现说明了这个问题的更细微之处,如下所示:

library(tweedie)
library(lightgbm)

set.seed(123)

tweedie_variance_power <- 1.2

labels <- rtweedie(1000, mu = 1, phi = 1, power = tweedie_variance_power)
hist(labels)

feat1 <- labels + rnorm(1000) #good signal for label with some noise
feat2 <-rnorm(1000) #garbage feature 
feat3 <-rnorm(1000) #garbage feature 

features <- cbind(feat1, feat2, feat3)

dTrain <- lgb.Dataset(data = features,
                      label = labels)

params <- c(objective = 'tweedie',
            tweedie_variance_power = tweedie_variance_power)

mod <- lgb.train(data = dTrain,
                 params = params,
                 nrounds = 100)

#Predictions in the native units of the labels
predsNative <- predict(mod, features, rawscore = FALSE)
#Predictions in the raw format
predsRaw <- predict(mod, features, rawscore = TRUE)

#We do not expect these values to be equal
all.equal(predsTrans, predsRaw)
"Mean relative difference: 1.503072"

#We expect values to be equal if raw scores are exponentiated
all.equal(predsTrans, exp(predsRaw))
"TRUE" #... our expectations are correct

#SHAP values 
shapNative <- predict(mod, features, rawscore = FALSE, predcontrib = TRUE)
shapRaw <- predict(mod, features, rawscore = TRUE, predcontrib = TRUE )

#Are there differences between shap values when rawscore is TRUE or FALSE?
all.equal(shapNative, shapRaw)
"TRUE" #outputs are identical, that is surprising!

#So are the shap values in raw or native formats?
#To anwser this question we can sum them

#testing raw the raw case first
all.equal(rowSums(shapRaw), predsRaw)
"TRUE" 

#from this we can conclude that shap values are not in native units,
#regardless of whether rawscore is TRUE or FALSE

#Test native scores just to prove point
all.equal(rowSums(shapNative), predsNative)
"Mean relative difference: 1.636892" # reaffirms that shap values are not in native units

#However, we can perform this operation on the raw shap scores
#to get the prediction in the native value
all.equal(exp(rowSums(shapRaw)), predsNative)
'TRUE'

#reversing the operations does not yield the same result
all.equal(rowSums(exp(shapRaw)), predsNative)
"Mean relative difference: 0.7662481"

#The last line is relevant because it implies 
#The relationship between native predictions
#and exponentiated shap values is not linear

#So, given the point of SHAP is to understand how each 
#feature impacts the prediction in its native units
#the raw shap values are not as useful as they could be

#Thus, how how would we convert 
#each of these four raw shap value elements to native units,
#thus understanding their contributions to their predictions
#in currency of native units?
shapRaw[1,]
-0.15429227  0.04858757 -0.27715359 -0.48454457
库(tweedie)
图书馆(lightgbm)
种子集(123)

tweedie_variance_power我将展示如何在Python中协调shap值和模型预测,包括原始分数和原始单位。希望它能帮助你了解你在R

第1步。生成数据集

# pip install tweedie
import tweedie
y = tweedie.tweedie(1.2,1,1).rvs(size=1000)
X = np.random.randn(1000,3)
第2步。适合型号

from lightgbm.sklearn import LGBMRegressor
lgb = LGBMRegressor(objective = 'tweedie')
lgb.fit(X,y)
第3步。了解形状值是什么。

第0个数据点的形状值

shap_values = lgb.predict(X, pred_contrib=True)
shap_values[0]
array([ 0.36841812, -0.15985678,  0.28910617, -0.27317984])
前3项是模型对基线的贡献,即形状值本身:

shap_values[0,:3].sum()
0.4976675073764354
第四个是原始分数的基线:

shap_values[0,3]
-0.2731798364061747
shap_values[0,:3].sum() + shap_values[0,3]
0.22448767097026068
它们的总和在原始分数中等于模型预测:

shap_values[0,3]
-0.2731798364061747
shap_values[0,:3].sum() + shap_values[0,3]
0.22448767097026068
让我们对照原始模型预测进行检查:

preds = lgb.predict(X, raw_score=True)
preds[0]
0.2244876709702609
编辑。原始分数和原始UTIT之间的转换

要在Tweedie(以及泊松分布和伽马分布)分布的原始分数和原始单位之间进行转换,您需要了解两个事实:

  • 原件是原始的
    exp
  • exp的
    sof
    sum
    exps的
    product
  • 演示:

  • 以原始单位表示的第0次预测:
  • lgb.predict([X[0,:]))
    数组([0.39394102])
    
  • 原始分数空间中第0行的形状值:
  • shap\u values=lgb.predict(X,pred\u contrib=True,raw\u score=True)
    形状u值[0]
    阵列([-0.77194274,-0.08343294,0.22740536,-0.30358374])
    
  • 将形状值转换为原始单位(指数的乘积):
  • np.prod(np.exp(shap_值[0]))
    0.3939410249402226
    

    看起来又像我了。

    谢谢你的贡献。虽然您提供的方法描述了如何提取目标函数单位(对数似然)的形状值,但这些值不在标签的本机单位中。后来我了解到,转换回本地单位并不简单,在此进行进一步讨论:您能澄清您的问题到底是什么吗?我以为你很难将形状值与预测相协调。我向你们展示了如何在原始分数空间中做到这一点。但你不接受答案。为什么?您在将原始分数转换为原始单位时有困难吗?还要注意,这是一个回归。对数可能性是不相关的。问题是原始分数空间不是以你在回答中描述的y(我称之为原生)为单位的。我们的目标是以步骤1中描述的y为单位提取每个特征的形状值,以便它们与以y为单位的预测值相加。@kdoherty请参见EDITI向您展示的两种方法:原始分数和原始分数。小数点后15位的数字相同