2401_83383683 2024-11-09 14:19 采纳率: 0%
浏览 4
已结题

python随机森林对两个excel表格读取,shap报错

我有一个python随机森林代码,读取excel文件进行随机森林以及算100次决定系数的平均数R2,最后用shap来解释模型。但是我遇到了一个问题

img

img


在运行上面的数据时,可以运行。
但是同一段代码,在运行下面的数据时,会报错,这是为什么?明明数据都差不多。

img

img


以下是我的python代码:

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score
import pandas as pd
import numpy as np
import shap
import matplotlib.pyplot as plt

from tqdm import tqdm

# 假设您已经加载了数据
file_path = r"C:\Users\lenovo\Desktop\U2_R11.xlsx" # 替换为Excel文件路径
data = pd.read_excel(file_path)

# 准备特征和目标变量
X = data.iloc[:, :-1]  # 提取所有特征,假设最后一列是目标变量
y = data.iloc[:, -1]   # 提取目标变量

# 测试次数
num_iterations = 100
r2_scores = []
shap_values_list=[]
pbar = tqdm(total=num_iterations)
for i in range(num_iterations):
    # 拆分数据集为训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=i)

    # 训练模型
    model = RandomForestRegressor(n_estimators=100, random_state=i)
    model.fit(X_train, y_train)

    # 在测试集上进行预测
    y_pred = model.predict(X_test)

    # 计算 R² 值
    r2 = r2_score(y_test, y_pred)
    r2_scores.append(r2)  # 将 R² 值添加到列表中

    # 使用 SHAP 计算 SHAP 值
    explainer = shap.Explainer(model, X_train)
    shap_values = explainer(X)
    shap_values_list.append(shap_values.values)
    pbar.update(1)
pbar.close()

# 计算平均 R² 值和标准差
mean_r2 = np.mean(r2_scores)
std_r2 = np.std(r2_scores)

print("平均决定系数R² 经过 {} 次迭代值: {:.4f}".format(num_iterations, mean_r2))
print("R² 方差得分: {:.4f}".format(std_r2))

# 计算所有 SHAP 值的平均值
mean_shap_values = np.mean(shap_values_list, axis=0)

# 使用 SHAP 汇总可视化柱状图
plt.figure(figsize=(10, 8))
plt.title("SHAP Values Summary")
shap.summary_plot(mean_shap_values, X, plot_type="bar")
plt.show()

以下是报错内容:
4%|▍ | 4/100 [00:00<00:05, 18.92it/s]Traceback (most recent call last):
File "C:\Users\lenovo\Desktop\因果代码\因果模型\刑事侦察题目\RF.py", line 41, in
shap_values = explainer(X)
File "C:\Users\lenovo\AppData\Local\Programs\Python\Python39\lib\site-packages\shap\explainers_tree.py", line 233, in call
v = self.shap_values(X, y=y, from_call=True, check_additivity=check_additivity, approximate=self.approximate)
File "C:\Users\lenovo\AppData\Local\Programs\Python\Python39\lib\site-packages\shap\explainers_tree.py", line 446, in shap_values
self.assert_additivity(out, self.model.predict(X))
File "C:\Users\lenovo\AppData\Local\Programs\Python\Python39\lib\site-packages\shap\explainers_tree.py", line 579, in assert_additivity
check_sum(self.expected_value + phi.sum(-1), model_output)
File "C:\Users\lenovo\AppData\Local\Programs\Python\Python39\lib\site-packages\shap\explainers_tree.py", line 573, in check_sum
raise ExplainerError(err_msg)
shap.utils._exceptions.ExplainerError: Additivity check failed in TreeExplainer! Please ensure the data matrix you passed to the explainer is the same shape that the model was trained on. If your data shape is correct then please report this on GitHub. This check failed because for one of the samples the sum of the SHAP values was 7.147069, while the model output was 7.223052. If this difference is acceptable you can set check_additivity=False to disable this check.
5%|▌ | 5/100 [00:00<00:07, 12.35it/s]

  • 写回答

27条回答 默认 最新

  • 杨同学* 2024-11-09 20:08
    关注
    获得0.30元问题酬金

    该回答引用ChatGPT4o, 并由本人整理回复, 如有帮助,还请采纳。
    你的代码在使用 SHAP 计算 SHAP 值时出现了 ExplainerError: Additivity check failed in TreeExplainer! 错误。这个问题通常与 SHAP 值的可加性检查失败有关,也可能是因为 SHAP 使用的输入数据格式与模型训练的输入数据格式不完全一致。以下是一些可能的解决方法:

    解决方法

    1. 关闭 SHAP 的 Additivity Check
      SHAP 的 TreeExplainer 有一个 additivity 检查机制,它会验证 SHAP 值的总和是否等于模型的输出。在某些情况下,比如在使用 RandomForestRegressor 时,这个检查可能会失败。可以通过设置 check_additivity=False 来关闭这个检查。

      修改如下代码:

      explainer = shap.Explainer(model, X_train)
      shap_values = explainer(X, check_additivity=False)
      
    2. 确保输入数据格式一致
      确保传递给 explainer 的数据和模型训练的数据在格式上完全一致。你可以通过以下方式检查:

      • 检查数据类型:确保 X_trainX 的数据类型相同,比如都为 pandas.DataFrame
      • 检查列顺序:确保 X_trainX 的列顺序一致。
      • 检查缺失值:确保 XX_train 没有缺失值(NaN)。缺失值可能会导致 SHAP 的解释器失败。
    3. 检查 SHAP 的版本兼容性
      某些版本的 SHAP 可能会与 sklearn 中的 RandomForestRegressor 产生兼容性问题。建议确保你使用的是最新版本的 SHAP 和 scikit-learn。可以通过以下命令升级:

      pip install -U shap scikit-learn
      
    4. 简化测试数据的规模
      在一些情况下,使用整个 X 数据集可能会导致计算不稳定。可以尝试使用较小的测试集来测试 SHAP 值的计算,如 X_test,而不是 X

      修改如下代码:

      shap_values = explainer(X_test, check_additivity=False)
      
    5. 调试输出
      如果问题依旧存在,可以在代码中添加调试信息来检查 XX_train 的形状、数据类型等是否一致。

    代码示例

    结合以上建议,修改后的代码示例如下:

    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.metrics import r2_score
    import pandas as pd
    import numpy as np
    import shap
    import matplotlib.pyplot as plt
    from tqdm import tqdm
    
    # 假设您已经加载了数据
    file_path = r"C:\Users\lenovo\Desktop\U2_R11.xlsx" # 替换为Excel文件路径
    data = pd.read_excel(file_path)
    
    # 准备特征和目标变量
    X = data.iloc[:, :-1]  # 提取所有特征,假设最后一列是目标变量
    y = data.iloc[:, -1]   # 提取目标变量
    
    # 测试次数
    num_iterations = 100
    r2_scores = []
    shap_values_list = []
    pbar = tqdm(total=num_iterations)
    for i in range(num_iterations):
        # 拆分数据集为训练集和测试集
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=i)
    
        # 训练模型
        model = RandomForestRegressor(n_estimators=100, random_state=i)
        model.fit(X_train, y_train)
    
        # 在测试集上进行预测
        y_pred = model.predict(X_test)
    
        # 计算 R² 值
        r2 = r2_score(y_test, y_pred)
        r2_scores.append(r2)  # 将 R² 值添加到列表中
    
        # 使用 SHAP 计算 SHAP 值
        explainer = shap.Explainer(model, X_train)
        shap_values = explainer(X_test, check_additivity=False)  # 使用测试集且关闭 additivity 检查
        shap_values_list.append(shap_values.values)
        pbar.update(1)
    pbar.close()
    
    # 计算平均 R² 值和标准差
    mean_r2 = np.mean(r2_scores)
    std_r2 = np.std(r2_scores)
    
    print("平均决定系数R² 经过 {} 次迭代值: {:.4f}".format(num_iterations, mean_r2))
    print("R² 方差得分: {:.4f}".format(std_r2))
    
    # 计算所有 SHAP 值的平均值
    mean_shap_values = np.mean(shap_values_list, axis=0)
    
    # 使用 SHAP 汇总可视化柱状图
    plt.figure(figsize=(10, 8))
    plt.title("SHAP Values Summary")
    shap.summary_plot(mean_shap_values, X, plot_type="bar")
    plt.show()
    

    总结

    通过设置 check_additivity=False,并确保 X_trainX 的格式、列顺序一致,应该可以避免这个报错。如果问题依然存在,请尝试用更小的数据集来测试 SHAP 的计算,或者使用较新的 SHAP 版本和 scikit-learn 版本来解决可能的兼容性问题

    评论

报告相同问题?

问题事件

  • 系统已结题 11月17日
  • 创建了问题 11月9日

悬赏问题

  • ¥15 多尺度特征图提取和融合
  • ¥15 微信小程序:渲染收货地址时页面不显示
  • ¥20 win7 64位DirectShow提示初始化失败如何解决?
  • ¥20 小规模孤立词识别系统设计
  • ¥15 关于Java对接海康威视车牌识别一体机SDK是否需要固定外网的IP?
  • ¥15 Linux扩容时,格式化卡住了:vgdispaly查看卷组信息,没有输出
  • ¥18 关于#ubuntu#的问题:使用背景-工作职责内有七八台ubuntu系统的电脑,平时需要互相调取资料,想实现把这几台电脑用交换机组成一个局域网,来实现指定文件夹的互相调取和写入
  • ¥20 求一个简易射频信号综测仪
  • ¥15 esp8266 tally灯 接收端改为发射端
  • ¥30 Labview代码调用access 数据库,相同代码其中一个调用不出来是为什么