roc_auc_score - y_true 中只有一个 class
roc_auc_score - Only one class present in y_true
我正在现有数据框上做 k-fold XV,我需要获得 AUC 分数。
问题是 - 有时测试数据只包含 0,而不包含 1!
我尝试使用 this 示例,但数字不同:
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)
我得到这个例外:
ValueError: Only one class present in y_true. ROC AUC score is not
defined in that case.
是否有任何解决方法可以使其在这种情况下起作用?
您可以使用 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
现在,如果只有一个 class,您还可以将 roc_auc_score
设置为零。但是,我不会这样做。我猜你的测试数据是高度不平衡的。我建议改用分层 K 折,这样您至少可以同时拥有两个 classes。
我现在面临同样的问题,使用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
我只是写了那个代码,并没有对它进行详尽的测试。它仅针对二进制类别进行了测试。希望还是有用的。
简单修改代码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 中只有一个 class(全为零),您需要在 y_true 中提供 2 个 class。
如错误所述,如果批次的基本事实中不存在 class,
ROC AUC score is not defined in that case.
我反对抛出异常(关于什么?这是预期的行为)或返回另一个指标(例如准确性)。该指标本身并没有被破坏。
我不想用指标 "fix" 解决数据不平衡 "issue"。如果可能的话,使用另一个样本可能会更好,或者只是加入满足 class 人口要求的多个批次。
您可以增加批量大小,例如从 32 到 64,你可以使用 StratifiedKFold 或 StratifiedShuffleSplit。如果错误仍然存在,请尝试洗牌您的数据,例如在您的 DataLoader 中。
我正在现有数据框上做 k-fold XV,我需要获得 AUC 分数。 问题是 - 有时测试数据只包含 0,而不包含 1!
我尝试使用 this 示例,但数字不同:
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)
我得到这个例外:
ValueError: Only one class present in y_true. ROC AUC score is not defined in that case.
是否有任何解决方法可以使其在这种情况下起作用?
您可以使用 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
现在,如果只有一个 class,您还可以将 roc_auc_score
设置为零。但是,我不会这样做。我猜你的测试数据是高度不平衡的。我建议改用分层 K 折,这样您至少可以同时拥有两个 classes。
我现在面临同样的问题,使用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
我只是写了那个代码,并没有对它进行详尽的测试。它仅针对二进制类别进行了测试。希望还是有用的。
简单修改代码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 中只有一个 class(全为零),您需要在 y_true 中提供 2 个 class。
如错误所述,如果批次的基本事实中不存在 class,
ROC AUC score is not defined in that case.
我反对抛出异常(关于什么?这是预期的行为)或返回另一个指标(例如准确性)。该指标本身并没有被破坏。
我不想用指标 "fix" 解决数据不平衡 "issue"。如果可能的话,使用另一个样本可能会更好,或者只是加入满足 class 人口要求的多个批次。
您可以增加批量大小,例如从 32 到 64,你可以使用 StratifiedKFold 或 StratifiedShuffleSplit。如果错误仍然存在,请尝试洗牌您的数据,例如在您的 DataLoader 中。