roc_auc_score - y_true中只有一个类

时间:2017-07-17 08:18:51

标签: python scikit-learn auc

我在现有的数据帧上做了k-fold XV,我需要获得AUC分数。 问题是 - 有时测试数据只包含0,而不是1!

我尝试使用this示例,但使用不同的数字:

collection.stream(). … 

我得到了这个例外:

  

ValueError:y_true中只有一个类。 ROC AUC得分不是   在那种情况下定义。

是否有任何解决方法可以使其在这种情况下起作用?

6 个答案:

答案 0 :(得分:5)

您可以使用try-except来防止错误:

import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 0, 0])
y_scores = np.array([1, 0, 0, 0])
try:
    roc_auc_score(y_true, y_scores)
except ValueError:
    pass

现在,如果只有一个班级,您也可以将roc_auc_score设置为零。但是,我不会这样做。我猜您的测试数据非常不平衡。我建议使用分层K折叠,这样你至少可以同时使用两个类。

答案 1 :(得分:1)

是的,这显然是一个错误!您的代码完全正确:

import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 0, 0])
y_scores = np.array([1, 0, 0, 0])
roc_auc_score(y_true, y_scores)

这是我的“解决方案”

from sklearn.metrics import roc_auc_score, accuracy_score
def roc_auc_score_FIXED(y_true, y_pred):
    if len(np.unique(y_true)) == 1: # bug in roc_auc_score
        return accuracy_score(y_true, np.rint(y_pred))
    return roc_auc_score(y_true, y_pred)

答案 2 :(得分:0)

我现在正面临着同样的问题,使用try-catch无法解决我的问题。为了解决这个问题,我开发了以下代码。

import pandas as pd
import numpy as np

class KFold(object):

    def __init__(self, folds, random_state=None):

        self.folds = folds

        self.random_state = random_state

    def split(self, x, y):

        assert len(x) == len(y), 'x and y should have the same length'

        x_, y_ = pd.DataFrame(x), pd.DataFrame(y)

        y_ = y_.sample(frac=1, random_state=self.random_state)

        x_ = x_.loc[y_.index]

        event_index, non_event_index = list(y_[y == 1].index), list(y_[y == 0].index)

        assert len(event_index) >= self.folds, 'number of folds should be less than the number of rows in x'

        assert len(non_event_index) >= self.folds, 'number of folds should be less than number of rows in y'

        indexes = []

        #
        #
        #
        step = int(np.ceil(len(non_event_index) / self.folds))

        start, end = 0, step

        while start < len(non_event_index):

            train_fold = set(non_event_index[start:end])

            valid_fold = set([k for k in non_event_index if k not in train_fold])

            indexes.append([train_fold, valid_fold])

            start, end = end, min(step + end, len(non_event_index))


        #
        #
        #
        step = int(np.ceil(len(event_index) / self.folds))

        start, end, i = 0, step, 0

        while start < len(event_index):

            train_fold = set(event_index[start:end])

            valid_fold = set([k for k in event_index if k not in train_fold])

            indexes[i][0] = list(indexes[i][0].union(train_fold))

            indexes[i][1] = list(indexes[i][1].union(valid_fold))

            indexes[i] = tuple(indexes[i])

            start, end, i = end, min(step + end, len(event_index)), i + 1

        return indexes 

我只是编写了该代码,但并未对其进行详尽的测试。仅针对二进制类别进行了测试。希望它有用。

答案 3 :(得分:0)

只需将代码修改为0到1,即可正常工作

import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 1, 0, 0])
y_scores = np.array([1, 0, 0, 0])
roc_auc_score(y_true, y_scores)

我相信错误消息建议y_true中只有一个类(全部为零),您需要在y_true中提供2个类。

答案 4 :(得分:0)

如错误所示,如果批次的基本事实中不存在类,则

在这种情况下,未定义ROC AUC分数。

我反对抛出异常(关于什么?这是预期的行为)或返回另一个指标(例如准确性)。指标本身并没有破坏。

我不想用度量“ fix”来解决数据不平衡“问题”。如果可能的话,最好使用其他采样,或者只加入满足班级人口需求的多个批次。

答案 5 :(得分:0)

您可以从(例如)增加批次大小从32到64,您可以使用StratifiedKFold或StratifiedShuffleSplit。如果错误仍然出现,请尝试整理您的数据,例如在您的DataLoader中。