ValueError: This solver needs samples of at least 2 classes in the data, but the data contains only one class: 0.0
ValueError: This solver needs samples of at least 2 classes in the data, but the data contains only one class: 0.0
我在将数据集拆分为测试集和训练集后对训练集应用了逻辑回归,但出现了上述错误。我试图解决这个问题,当我尝试在控制台中打印我的响应向量 y_train 时,它会打印整数值,例如 0 或 1。但是当我将其写入文件时,我发现这些值是浮点数,例如 0.0和 1.0。如果那是问题,我怎样才能克服它。
lenreg = LogisticRegression()
print y_train[0:10]
y_train.to_csv(path='ytard.csv')
lenreg.fit(X_train, y_train)
y_pred = lenreg.predict(X_test)
print metics.accuracy_score(y_test, y_pred)
StrackTrace如下,
Traceback (most recent call last):
File "/home/amey/prog/pd.py", line 82, in <module>
lenreg.fit(X_train, y_train)
File "/usr/lib/python2.7/dist-packages/sklearn/linear_model/logistic.py", line 1154, in fit
self.max_iter, self.tol, self.random_state)
File "/usr/lib/python2.7/dist-packages/sklearn/svm/base.py", line 885, in _fit_liblinear
" class: %r" % classes_[0])
ValueError: This solver needs samples of at least 2 classes in the data, but the data contains only one class: 0.0
与此同时,我浏览了 link 没有得到答复。有解决办法吗
这里的问题是您的 y_train
向量,无论出于何种原因,只有零。这实际上不是你的错,而是一种错误(我认为)。 classifier 需要 2 个 classes 否则它会抛出这个错误。
有道理。如果您的 y_train
向量只有零(即只有 1 class ),那么 classifier 实际上不需要做任何工作,因为所有预测都应该只是一个 class.
在我看来,classifier 仍应完成并仅预测一个 class(在本例中为全零),然后发出警告,但事实并非如此。它会抛出错误。
检查这种情况的方法如下:
lenreg = LogisticRegression()
print y_train[0:10]
y_train.to_csv(path='ytard.csv')
if len(np.sum(y_train)) in [len(y_train),0]:
print "all one class"
#do something else
else:
#OK to proceed
lenreg.fit(X_train, y_train)
y_pred = lenreg.predict(X_test)
print metics.accuracy_score(y_test, y_pred)
为了更轻松地解决问题,我建议您在测试集中包含更多样本,例如 100 或 1000 而不是 10。
我发现这是因为我的 y_test 中只有 1 或 0,因为我的样本量非常小。尝试更改您的 test_size 值。
我在使用 learning_curve
时遇到了同样的问题:
train_sizes, train_scores, test_scores = learning_curve(estimator,
X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes,
scoring="f1", random_state=RANDOM_SEED, shuffle=True)
添加 suffle
参数,使集合随机化。
这并不能防止错误的发生,但它是一种增加在函数使用的子集中同时具有 类 的机会的方法。
# python3
import numpy as np
from sklearn.svm import LinearSVC
def upgrade_to_work_with_single_class(SklearnPredictor):
class UpgradedPredictor(SklearnPredictor):
def __init__(self, *args, **kwargs):
self._single_class_label = None
super().__init__(*args, **kwargs)
@staticmethod
def _has_only_one_class(y):
return len(np.unique(y)) == 1
def _fitted_on_single_class(self):
return self._single_class_label is not None
def fit(self, X, y=None):
if self._has_only_one_class(y):
self._single_class_label = y[0]
else:
super().fit(X, y)
return self
def predict(self, X):
if self._fitted_on_single_class():
return np.full(X.shape[0], self._single_class_label)
else:
return super().predict(X)
return UpgradedPredictor
LinearSVC = upgrade_to_work_with_single_class(LinearSVC)
或困难的方式(更正确):
import numpy as np
from sklearn.svm import LinearSVC
from copy import deepcopy, copy
from functools import wraps
def copy_class(cls):
copy_cls = type(f'{cls.__name__}', cls.__bases__, dict(cls.__dict__))
for name, attr in cls.__dict__.items():
try:
hash(attr)
except TypeError:
# Assume lack of __hash__ implies mutability. This is NOT
# a bullet proof assumption but good in many cases.
setattr(copy_cls, name, deepcopy(attr))
return copy_cls
def upgrade_to_work_with_single_class(SklearnPredictor):
SklearnPredictor = copy_class(SklearnPredictor)
original_init = deepcopy(SklearnPredictor.__init__)
original_fit = deepcopy(SklearnPredictor.fit)
original_predict = deepcopy(SklearnPredictor.predict)
@staticmethod
def _has_only_one_class(y):
return len(np.unique(y)) == 1
def _fitted_on_single_class(self):
return self._single_class_label is not None
@wraps(SklearnPredictor.__init__)
def new_init(self, *args, **kwargs):
self._single_class_label = None
original_init(self, *args, **kwargs)
@wraps(SklearnPredictor.fit)
def new_fit(self, X, y=None):
if self._has_only_one_class(y):
self._single_class_label = y[0]
else:
original_fit(self, X, y)
return self
@wraps(SklearnPredictor.predict)
def new_predict(self, X):
if self._fitted_on_single_class():
return np.full(X.shape[0], self._single_class_label)
else:
return original_predict(self, X)
setattr(SklearnPredictor, '_has_only_one_class', _has_only_one_class)
setattr(SklearnPredictor, '_fitted_on_single_class', _fitted_on_single_class)
SklearnPredictor.__init__ = new_init
SklearnPredictor.fit = new_fit
SklearnPredictor.predict = new_predict
return SklearnPredictor
LinearSVC = upgrade_to_work_with_single_class(LinearSVC)
您可以找到每个 classes 的第一次(或任何一次)出现的索引,并将它们连接到数组顶部并从它们的原始位置删除它们,这样就会有训练集中每个 class 的至少一个实例。
此错误与您使用的数据集有关,该数据集包含一个 class,例如 1/benign,而它必须包含两个 classes 1 和 0 或 Benign 和 Attack。
我在将数据集拆分为测试集和训练集后对训练集应用了逻辑回归,但出现了上述错误。我试图解决这个问题,当我尝试在控制台中打印我的响应向量 y_train 时,它会打印整数值,例如 0 或 1。但是当我将其写入文件时,我发现这些值是浮点数,例如 0.0和 1.0。如果那是问题,我怎样才能克服它。
lenreg = LogisticRegression()
print y_train[0:10]
y_train.to_csv(path='ytard.csv')
lenreg.fit(X_train, y_train)
y_pred = lenreg.predict(X_test)
print metics.accuracy_score(y_test, y_pred)
StrackTrace如下,
Traceback (most recent call last):
File "/home/amey/prog/pd.py", line 82, in <module>
lenreg.fit(X_train, y_train)
File "/usr/lib/python2.7/dist-packages/sklearn/linear_model/logistic.py", line 1154, in fit
self.max_iter, self.tol, self.random_state)
File "/usr/lib/python2.7/dist-packages/sklearn/svm/base.py", line 885, in _fit_liblinear
" class: %r" % classes_[0])
ValueError: This solver needs samples of at least 2 classes in the data, but the data contains only one class: 0.0
与此同时,我浏览了 link 没有得到答复。有解决办法吗
这里的问题是您的 y_train
向量,无论出于何种原因,只有零。这实际上不是你的错,而是一种错误(我认为)。 classifier 需要 2 个 classes 否则它会抛出这个错误。
有道理。如果您的 y_train
向量只有零(即只有 1 class ),那么 classifier 实际上不需要做任何工作,因为所有预测都应该只是一个 class.
在我看来,classifier 仍应完成并仅预测一个 class(在本例中为全零),然后发出警告,但事实并非如此。它会抛出错误。
检查这种情况的方法如下:
lenreg = LogisticRegression()
print y_train[0:10]
y_train.to_csv(path='ytard.csv')
if len(np.sum(y_train)) in [len(y_train),0]:
print "all one class"
#do something else
else:
#OK to proceed
lenreg.fit(X_train, y_train)
y_pred = lenreg.predict(X_test)
print metics.accuracy_score(y_test, y_pred)
为了更轻松地解决问题,我建议您在测试集中包含更多样本,例如 100 或 1000 而不是 10。
我发现这是因为我的 y_test 中只有 1 或 0,因为我的样本量非常小。尝试更改您的 test_size 值。
我在使用 learning_curve
时遇到了同样的问题:
train_sizes, train_scores, test_scores = learning_curve(estimator,
X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes,
scoring="f1", random_state=RANDOM_SEED, shuffle=True)
添加 suffle
参数,使集合随机化。
这并不能防止错误的发生,但它是一种增加在函数使用的子集中同时具有 类 的机会的方法。
# python3
import numpy as np
from sklearn.svm import LinearSVC
def upgrade_to_work_with_single_class(SklearnPredictor):
class UpgradedPredictor(SklearnPredictor):
def __init__(self, *args, **kwargs):
self._single_class_label = None
super().__init__(*args, **kwargs)
@staticmethod
def _has_only_one_class(y):
return len(np.unique(y)) == 1
def _fitted_on_single_class(self):
return self._single_class_label is not None
def fit(self, X, y=None):
if self._has_only_one_class(y):
self._single_class_label = y[0]
else:
super().fit(X, y)
return self
def predict(self, X):
if self._fitted_on_single_class():
return np.full(X.shape[0], self._single_class_label)
else:
return super().predict(X)
return UpgradedPredictor
LinearSVC = upgrade_to_work_with_single_class(LinearSVC)
或困难的方式(更正确):
import numpy as np
from sklearn.svm import LinearSVC
from copy import deepcopy, copy
from functools import wraps
def copy_class(cls):
copy_cls = type(f'{cls.__name__}', cls.__bases__, dict(cls.__dict__))
for name, attr in cls.__dict__.items():
try:
hash(attr)
except TypeError:
# Assume lack of __hash__ implies mutability. This is NOT
# a bullet proof assumption but good in many cases.
setattr(copy_cls, name, deepcopy(attr))
return copy_cls
def upgrade_to_work_with_single_class(SklearnPredictor):
SklearnPredictor = copy_class(SklearnPredictor)
original_init = deepcopy(SklearnPredictor.__init__)
original_fit = deepcopy(SklearnPredictor.fit)
original_predict = deepcopy(SklearnPredictor.predict)
@staticmethod
def _has_only_one_class(y):
return len(np.unique(y)) == 1
def _fitted_on_single_class(self):
return self._single_class_label is not None
@wraps(SklearnPredictor.__init__)
def new_init(self, *args, **kwargs):
self._single_class_label = None
original_init(self, *args, **kwargs)
@wraps(SklearnPredictor.fit)
def new_fit(self, X, y=None):
if self._has_only_one_class(y):
self._single_class_label = y[0]
else:
original_fit(self, X, y)
return self
@wraps(SklearnPredictor.predict)
def new_predict(self, X):
if self._fitted_on_single_class():
return np.full(X.shape[0], self._single_class_label)
else:
return original_predict(self, X)
setattr(SklearnPredictor, '_has_only_one_class', _has_only_one_class)
setattr(SklearnPredictor, '_fitted_on_single_class', _fitted_on_single_class)
SklearnPredictor.__init__ = new_init
SklearnPredictor.fit = new_fit
SklearnPredictor.predict = new_predict
return SklearnPredictor
LinearSVC = upgrade_to_work_with_single_class(LinearSVC)
您可以找到每个 classes 的第一次(或任何一次)出现的索引,并将它们连接到数组顶部并从它们的原始位置删除它们,这样就会有训练集中每个 class 的至少一个实例。
此错误与您使用的数据集有关,该数据集包含一个 class,例如 1/benign,而它必须包含两个 classes 1 和 0 或 Benign 和 Attack。