假设我正在尝试预测一套公寓的价格。因此,我有大量标记的数据,每套公寓都有可能影响价格的特征,如:
- 城市
- 街道
- 楼层
- 建造年份
- 社会经济状况
- 平方英尺
- 等等
我训练了一个模型,比如XGBOOST。现在,我想预测一套新公寓的价格。有什么好的方法可以展示这套公寓的“好”在哪里,“不好”在哪里,以及影响程度(按0-1比例)吗?
例如:楼层是一个“强”特征(即,在这个区域这个楼层是受欢迎的,因此对公寓价格有积极影响),但社会经济状况是一个弱特征(即,社会经济状况较低,因此对公寓价格有负面影响)。
我希望能够大致说明我的模型为何决定这个价格,并且我想让用户通过这些指标感受到公寓的价值。
我考虑过对每个特征进行详尽搜索——但我担心这会花费太多时间。
有没有更聪明的方法来做到这一点?
任何帮助都将不胜感激…
回答:
有好消息要告诉你,确实有方法可以做到。
最近发布了一个名为“SHAP”(SHapley Additive exPlanation)的包,专门用于此目的。这是GitHub的链接。
它支持复杂模型的可视化(这些模型难以直观解释),如提升树(特别是XGBOOST!)
它可以展示“真实”的特征重要性,这比xgboost提供的"gain"
、"weight"
和"cover"
更好,因为这些指标不一致。
你可以在这里阅读关于为什么SHAP在特征评估方面更好的所有信息这里。
给你一个能用的代码会很困难,但有很好的文档,你应该编写一个适合你的代码。
这是构建你的第一个图表的指导方针:
import shapimport xgboost as xgb# 假设X_train和y_train分别是数据样本的特征和标签dtrain = xgb.DMatrix(X_train, label=y_train, feature_names=feature_names, weight=weights_trn)# 训练你的xgboost模型bst = xgb.train(params0, dtrain, num_boost_round=2500, evals=watchlist, early_stopping_rounds=200)# "explainer"对象的形状explainer = shap.TreeExplainer(bst)# "你要解释的值,我从我的训练集中取的,但你可以在这里解释任何你想要的东西"shap_values = explainer.shap_values(X_test)shap.summary_plot(shap_values, X_test)shap.summary_plot(shap_values, X_test, plot_type="bar")
要绘制“为何某个样本得到其得分”,你可以使用SHAP内置的函数(仅在Jupyter Notebook中有效)。这里有一个完美的例子
我个人编写了一个使用matplotlib
绘制它的函数,这需要一些努力。
这是我使用shap值制作的一个图表的例子(特征是保密的,所以都已擦除)
你可以看到97%的预测为label=1
,以及每个特征对该特定样本的log-loss增加或减少了多少。