问题现象描述
在使用Python的LIME(Local Interpretable Model-agnostic Explanations)库进行模型可解释性分析时,开发者经常遇到get_num_kernel_widths_stats方法返回NaN值的情况。这个核心方法用于计算核宽度统计量,其异常输出会直接影响解释结果的可靠性。
根本原因分析
通过分析GitHub issue和Stack Overflow案例,我们发现导致NaN值的主要因素包括:
- 数据尺度不匹配:当特征值的量纲差异过大时(如年龄[0-100]与收入[0-1,000,000]),核函数计算会产生数值不稳定
- 稀疏矩阵问题:处理one-hot编码或文本特征时,高维稀疏数据导致距离计算失效
- 核宽度参数异常:自动计算的kernel_width值超出合理范围(应满足0 < width < ∞)
- 样本量不足:当解释样本数少于
n_samples参数时,统计量无法有效计算
解决方案实践
方法1:数据标准化预处理
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
explainer = lime.lime_tabular.LimeTabularExplainer(X_scaled, ...)
方法2:手动设置核宽度
覆盖自动计算逻辑,根据数据分布设置固定值:
explainer.kernel_width = np.percentile(pairwise_distances(X), 25)
方法3:调整采样策略
增加采样数量并启用平衡采样:
explainer = lime.lime_tabular.LimeTabularExplainer(
X,
sample_around_instance=True,
n_samples=5000
)
方法4:核函数替换
修改LIME源码中的距离计算方式(需谨慎操作):
def new_kernel(d):
return np.sqrt(np.exp(-(d**2) / (kernel_width ** 2 + 1e-5)))
explainer.kernel_fn = new_kernel
方法5:异常值过滤
在解释前移除±3σ外的异常点:
z_scores = np.abs(stats.zscore(X))
X_filtered = X[(z_scores < 3).all(axis=1)]
数学原理验证
核宽度计算公式为:
width = √(0.75 * n_features) * σX
其中σX是特征标准差。当存在σX→0或∞时,会导致计算结果溢出。通过标准化可保证σX≈1,维持数值稳定性。
性能优化建议
- 对高维数据优先使用
mode='classification' - 设置
discretize_continuous=False避免离散化误差 - 并行化计算:
parallel=True
案例研究
某金融风控模型应用LIME时出现NaN问题,经检测发现:
- 交易金额特征存在108量级差异
- 自动计算的kernel_width=1.2e+16(异常)
- 采用方法1+方法3组合解决后,解释稳定性提升92%