You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

序数分类器预测缺失最高类别问题求助

序数分类器预测缺失最高类别问题的解决

问题背景

我基于以下资料实现序数分类器:

  • 核心思路来源:《用任意分类器训练序数回归的简单技巧》
  • 代码参考:Stack Overflow上的序数分类器使用问答

训练数据集包含5个有用性等级类别(1-5),但使用参考代码对测试集预测时,仅能输出1-4的等级结果,训练集(n=1000)和测试集(n=15000)样本量均充足。

原始代码

from sklearn.base import clone
import numpy as np
from sklearn.neighbors import KNeighborsClassifier  # 补充缺失的导入

class OrdinalClassifier():

    def __init__(self, clf):
        self.clf = clf
        self.clfs = {}

    def fit(self, X, y):
        self.unique_class = np.sort(np.unique(y))
        if self.unique_class.shape[0] > 2:
            for i in range(self.unique_class.shape[0] - 1):
                # 为每个序数阈值拟合一个二分类器
                binary_y = (y > self.unique_class[i]).astype(np.uint8)
                clf = clone(self.clf)
                clf.fit(X, binary_y)
                self.clfs[i] = clf

    def predict_proba(self, X):
        clfs_predict = {k: v.predict_proba(X) for k, v in self.clfs.items()}
        predicted = []
        for i, y in enumerate(self.unique_class):
            if i == 0:
                # V1 = 1 - Pr(y > V1)
                predicted.append(1 - clfs_predict[i][:, 1])
            elif y in clfs_predict:
                # Vi = Pr(y > Vi-1) - Pr(y > Vi)
                predicted.append(clfs_predict[i - 1][:, 1] - clfs_predict[i][:, 1])
            else:
                # Vk = Pr(y > Vk-1)
                predicted.append(clfs_predict[i - 1][:, 1])
        return np.vstack(predicted).T

    def predict(self, X):
        return self.unique_class[np.argmax(self.predict_proba(X), axis=1)]

knn = KNeighborsClassifier()
oc = OrdinalClassifier(knn)
oc.fit(X_train, y_train)
oc.predict(X_test)

问题原因

代码中predict_proba方法的条件判断逻辑错误:

  • 当类别数为5时,self.clfs的键是0、1、2、3(对应4个二分类器)
  • 遍历self.unique_class([1,2,3,4,5])时,对于y=4(i=3),判断y in clfs_predict即检查4是否在{0,1,2,3}中,结果为False,导致该类别的概率计算错误,进而最高类别5的概率无法成为最大值,最终预测结果中不会出现5。

修正方案

将predict_proba方法中的elif y in clfs_predict改为elif i in clfs_predict,因为clfs的键是循环索引i,而非类别值y。

修正后的predict_proba方法:

def predict_proba(self, X):
    clfs_predict = {k: v.predict_proba(X) for k, v in self.clfs.items()}
    predicted = []
    for i, y in enumerate(self.unique_class):
        if i == 0:
            # V1 = 1 - Pr(y > V1)
            predicted.append(1 - clfs_predict[i][:, 1])
        elif i in clfs_predict:
            # Vi = Pr(y > Vi-1) - Pr(y > Vi)
            predicted.append(clfs_predict[i - 1][:, 1] - clfs_predict[i][:, 1])
        else:
            # Vk = Pr(y > Vk-1)
            predicted.append(clfs_predict[i - 1][:, 1])
    return np.vstack(predicted).T

额外检查项:确认训练集y_train中确实包含所有5个类别,可通过print(np.unique(y_train))验证,避免因训练集类别缺失导致的问题。

内容的提问来源于stack exchange,提问作者DoubiXu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 23:50:29