Scikit-Learn RandomForestClassifier多标签分类OOB评分报错问题
问题原因与解决方法
为什么会报错?
当多标签的某一维度所有样本值都相同时(比如你例子里第一列全0),这个标签维度只有一个类别。Sklearn在计算OOB(袋外)评分时,内部会针对每个标签维度单独计算预测结果,但如果某个维度只有一个类别,部分决策树的OOB样本可能完全没有该类的参考样本,导致生成的预测结果形状不统一,进而触发数组广播错误。
而关闭oob_score=False时,模型跳过了OOB评分的计算流程,只执行常规的训练逻辑——常规训练对单类别标签的处理是没问题的,毕竟只是拟合一个固定输出,所以不会报错。
解决方案
方案1:过滤无区分度的标签列(推荐)
这类全相同的标签维度本身没有预测价值(模型学不到任何信息,预测结果永远固定),直接剔除即可:
import numpy as np from sklearn.ensemble import RandomForestClassifier C = np.array([[2,4,6],[4,2,1],[8,3,1]]) out = np.array([[0,1],[0,1],[0,0]]) # 筛选出有至少两种不同值的标签列 valid_cols = [col for col in range(out.shape[1]) if len(np.unique(out[:, col])) > 1] filtered_out = out[:, valid_cols] # 正常开启OOB训练 rf = RandomForestClassifier(n_estimators=100, oob_score=True) rf.fit(C, filtered_out) print("OOB Score:", rf.oob_score_)
方案2:手动实现OOB评分(适合必须保留单类别列的场景)
如果一定要保留这类无区分度的标签列,可以手动遍历每棵树计算OOB评分,遇到单类别列直接返回满分:
import numpy as np from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score C = np.array([[2,4,6],[4,2,1],[8,3,1]]) out = np.array([[0,1],[0,1],[0,0]]) rf = RandomForestClassifier(n_estimators=100, oob_score=False) rf.fit(C, out) # 手动计算OOB评分 oob_predictions = np.zeros_like(out) n_samples = C.shape[0] for tree in rf.estimators_: # 获取当前树的OOB样本索引 oob_indices = tree.oob_indices_ if len(oob_indices) == 0: continue # 预测OOB样本 pred = tree.predict(C[oob_indices]) oob_predictions[oob_indices] += pred # 取多数投票(二进制标签直接取大于0.5的结果) oob_predictions = (oob_predictions / len(rf.estimators_)) >= 0.5 # 计算每个标签维度的准确率,单类别列直接给1.0 scores = [] for col in range(out.shape[1]): if len(np.unique(out[:, col])) == 1: scores.append(1.0) else: scores.append(accuracy_score(out[:, col], oob_predictions[:, col])) # 整体OOB评分取各维度的平均 mean_oob_score = np.mean(scores) print("手动计算的OOB评分:", mean_oob_score)
内容的提问来源于stack exchange,提问作者user37292
相关产品推荐
相关产品推荐

