如何解决GridSearchCV运行Scikit-Survival模型时出现FitFailedWarning报错
问题排查与解决方案
1. numpy.linalg.LinAlgError: Matrix is singular 错误修复
错误原因
- 交叉验证过程中,每折训练集经过OneHotEncoder编码后,会出现部分独热列全为0的情况:分类特征的部分取值仅存在于当前折的测试集,训练集无对应样本,编码后生成全0列。CoxPH模型对全0特征拟合时,无法计算可逆的海森矩阵,直接抛出矩阵奇异报错。
- 你之前单独在全量数据集上运行打分函数无报错,是因为全量数据覆盖了所有分类取值,无全0独热列。
修复步骤
- 调整OneHotEncoder参数,规避多重共线性与未知取值问题:
# 替换Pipeline里的OneHotEncoder初始化代码 OneHotEncoder(drop='first', handle_unknown='ignore', sparse_output=False)
- 给CoxPH模型添加L2正则,避免矩阵奇异:
# 替换两处CoxPHSurvivalAnalysis初始化代码(打分函数内、Pipeline内) CoxPHSurvivalAnalysis(alpha=0.1)
- 给打分函数添加异常捕获与常量列判断逻辑,避免单特征拟合失败终止整体流程:
import numpy as np from scipy.linalg import LinAlgError def fit_and_score_features(X, y): n_features = X.shape[1] scores = np.empty(n_features) m = CoxPHSurvivalAnalysis(alpha=0.1) for j in range(n_features): Xj = X[:, j:j+1] # 常量列直接赋值随机猜测的c-index得分,无预测能力 if np.all(Xj == Xj[0]): scores[j] = 0.5 continue try: m.fit(Xj, y) scores[j] = m.score(Xj, y) except LinAlgError: scores[j] = 0.5 return scores
2. 运行时间过长优化
当前参数网格遍历1~98所有特征数,3折交叉验证每轮都需要重新计算所有特征的单特征得分,计算量级为 98(k值) * 3(折数) * 98(单特征拟合) * 1(最终模型拟合),整体训练量极大:
- 缩小k值搜索范围,设置步长粗筛后再细调:
# 示例:每5个k值取一个样本,先定位最优区间 param_grid = {'select__k': np.arange(1, data_x_numeric.shape[1] + 1, 5)}
- 提前用全量数据计算所有特征得分,交叉验证阶段直接用固定得分选top k,无需每折重复计算,可减少90%以上计算量。
3. FutureWarning 修复
该警告为scikit-learn与pandas版本兼容性问题,OneHotEncoder处理category类型时调用了已废弃的inplace参数:
- 升级scikit-learn到1.2及以上版本可直接解决
- 无需升级的情况下可添加如下代码忽略警告,不影响运行结果:
import warnings warnings.filterwarnings("ignore", category=FutureWarning)
内容的提问来源于stack exchange,提问作者Cole
相关产品推荐
相关产品推荐

