log_loss 在 sklearn 中:标签二值化不支持多输出目标数据
log_loss in sklearn: Multioutput target data is not supported with label binarization
代码如下
from sklearn import metrics
import numpy as np
y_true = np.array([[0.2,0.8,0],[0.9,0.05,0.05]])
y_predict = np.array([[0.5,0.5,0.0],[0.5,0.4,0.1]])
metrics.log_loss(y_true, y_predict)
产生以下错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-32-24beeb19448b> in <module>()
----> 1 metrics.log_loss(y_true, y_predict)
~\AppData\Local\conda\conda\envs\tensorflow\lib\site-packages\sklearn\metrics\classification.py in log_loss(y_true, y_pred, eps, normalize, sample_weight, labels)
1646 lb.fit(labels)
1647 else:
-> 1648 lb.fit(y_true)
1649
1650 if len(lb.classes_) == 1:
~\AppData\Local\conda\conda\envs\tensorflow\lib\site-packages\sklearn\preprocessing\label.py in fit(self, y)
276 self.y_type_ = type_of_target(y)
277 if 'multioutput' in self.y_type_:
--> 278 raise ValueError("Multioutput target data is not supported with "
279 "label binarization")
280 if _num_samples(y) == 0:
ValueError: Multioutput target data is not supported with label binarization
我很好奇为什么。我正在尝试重新阅读对数丢失的定义,但找不到任何会使计算不正确的内容。
源代码表明 metrics.log_loss 不支持 y_true
中的概率。它仅支持形状为 (n_samples, n_classes)
的二进制指标,例如 [[0,0,1],[1,0,0]]
或 class 形状为 (n_samples,)
的标签,例如 [2, 0]
。在后一种情况下,class 标签将被单热编码为在计算对数损失之前看起来像指标矩阵。
在此区块中:
lb = LabelBinarizer()
if labels is not None:
lb.fit(labels)
else:
lb.fit(y_true)
您正在到达 lb.fit(y_true)
,如果 y_true
不全是 1
and/or 0
,它将失败。例如:
>>> import numpy as np
>>> from sklearn import preprocessing
>>> lb = preprocessing.LabelBinarizer()
>>> lb.fit(np.array([[0,1,0],[1,0,0]]))
LabelBinarizer(neg_label=0, pos_label=1, sparse_output=False)
>>> lb.fit(np.array([[0.2,0.8,0],[0.9,0.05,0.05]]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/imran/.pyenv/versions/anaconda3-4.4.0/lib/python3.6/site-packages/sklearn/preprocessing/label.py", line 278, in fit
raise ValueError("Multioutput target data is not supported with "
ValueError: Multioutput target data is not supported with label binarization
我会定义你自己的自定义对数损失函数:
def logloss(y_true, y_pred, eps=1e-15):
y_pred = np.clip(y_pred, eps, 1 - eps)
return -(y_true * np.log(y_pred)).sum(axis=1).mean()
这是您的数据输出:
>>> logloss(y_true, y_predict)
0.738961717153653
不,我不是在谈论二进制class化。
您上面显示的 y_true
和 y_predict
不会被视为 class 化目标,除非另有说明。
首先,因为它们是概率,所以它可以取任何连续值,因此它在 scikit 中被检测为回归。
其次,y_pred或y_true中的每个元素都是一个概率列表。这被检测为多输出。因此 "Multioutput targets".
的错误
您需要提供 log_loss
的实际标签,而不是 y_true 的概率(基本事实)。顺便说一句,为什么你有这样的可能性?概率可以用于预测数据,但为什么用于实际数据?
为此,您需要先将 y_true
的概率转换为标签,将最高概率视为获胜者 class。
这可以通过 numpy.argmax 使用以下代码完成:
import numpy as np
y_true = np.argmax(y_true, axis=1)
print(y_true)
Output:- [0, 1]
# We will not do this the above for y_predict, because probabilities are allowed in it.
# We will use labels param to declare that we have actually 3 classes,
# as evident from your probabilities.
metrics.log_loss(y_true, y_predict, labels=[0,1,2])
Output:- 0.6931471805599458
正如与@Imran 讨论的那样,这里有一个 y_true
的示例,其值不是 0 或 1。
- 此处的示例使用 log_loss 进行 3-class class化,其中 y 的值为 0、1 和 2 :- http://scikit-learn.org/stable/auto_examples/calibration/plot_calibration_multiclass.html#sphx-glr-auto-examples-calibration-plot-calibration-multiclass-py
下面的示例简单地检查是否允许其他值:
y_true = np.array([0, 1, 2])
y_pred = np.array([[0.5,0.5,0.0],[0.5,0.4,0.1], [0.4,0.1,0.5]])
metrics.log_loss(y_true, y_pred)
Output:- 1.3040076684760489 (No error)
代码如下
from sklearn import metrics
import numpy as np
y_true = np.array([[0.2,0.8,0],[0.9,0.05,0.05]])
y_predict = np.array([[0.5,0.5,0.0],[0.5,0.4,0.1]])
metrics.log_loss(y_true, y_predict)
产生以下错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-32-24beeb19448b> in <module>()
----> 1 metrics.log_loss(y_true, y_predict)
~\AppData\Local\conda\conda\envs\tensorflow\lib\site-packages\sklearn\metrics\classification.py in log_loss(y_true, y_pred, eps, normalize, sample_weight, labels)
1646 lb.fit(labels)
1647 else:
-> 1648 lb.fit(y_true)
1649
1650 if len(lb.classes_) == 1:
~\AppData\Local\conda\conda\envs\tensorflow\lib\site-packages\sklearn\preprocessing\label.py in fit(self, y)
276 self.y_type_ = type_of_target(y)
277 if 'multioutput' in self.y_type_:
--> 278 raise ValueError("Multioutput target data is not supported with "
279 "label binarization")
280 if _num_samples(y) == 0:
ValueError: Multioutput target data is not supported with label binarization
我很好奇为什么。我正在尝试重新阅读对数丢失的定义,但找不到任何会使计算不正确的内容。
源代码表明 metrics.log_loss 不支持 y_true
中的概率。它仅支持形状为 (n_samples, n_classes)
的二进制指标,例如 [[0,0,1],[1,0,0]]
或 class 形状为 (n_samples,)
的标签,例如 [2, 0]
。在后一种情况下,class 标签将被单热编码为在计算对数损失之前看起来像指标矩阵。
在此区块中:
lb = LabelBinarizer()
if labels is not None:
lb.fit(labels)
else:
lb.fit(y_true)
您正在到达 lb.fit(y_true)
,如果 y_true
不全是 1
and/or 0
,它将失败。例如:
>>> import numpy as np
>>> from sklearn import preprocessing
>>> lb = preprocessing.LabelBinarizer()
>>> lb.fit(np.array([[0,1,0],[1,0,0]]))
LabelBinarizer(neg_label=0, pos_label=1, sparse_output=False)
>>> lb.fit(np.array([[0.2,0.8,0],[0.9,0.05,0.05]]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/imran/.pyenv/versions/anaconda3-4.4.0/lib/python3.6/site-packages/sklearn/preprocessing/label.py", line 278, in fit
raise ValueError("Multioutput target data is not supported with "
ValueError: Multioutput target data is not supported with label binarization
我会定义你自己的自定义对数损失函数:
def logloss(y_true, y_pred, eps=1e-15):
y_pred = np.clip(y_pred, eps, 1 - eps)
return -(y_true * np.log(y_pred)).sum(axis=1).mean()
这是您的数据输出:
>>> logloss(y_true, y_predict)
0.738961717153653
不,我不是在谈论二进制class化。
您上面显示的 y_true
和 y_predict
不会被视为 class 化目标,除非另有说明。
首先,因为它们是概率,所以它可以取任何连续值,因此它在 scikit 中被检测为回归。
其次,y_pred或y_true中的每个元素都是一个概率列表。这被检测为多输出。因此 "Multioutput targets".
的错误您需要提供 log_loss
的实际标签,而不是 y_true 的概率(基本事实)。顺便说一句,为什么你有这样的可能性?概率可以用于预测数据,但为什么用于实际数据?
为此,您需要先将 y_true
的概率转换为标签,将最高概率视为获胜者 class。
这可以通过 numpy.argmax 使用以下代码完成:
import numpy as np
y_true = np.argmax(y_true, axis=1)
print(y_true)
Output:- [0, 1]
# We will not do this the above for y_predict, because probabilities are allowed in it.
# We will use labels param to declare that we have actually 3 classes,
# as evident from your probabilities.
metrics.log_loss(y_true, y_predict, labels=[0,1,2])
Output:- 0.6931471805599458
正如与@Imran 讨论的那样,这里有一个 y_true
的示例,其值不是 0 或 1。
- 此处的示例使用 log_loss 进行 3-class class化,其中 y 的值为 0、1 和 2 :- http://scikit-learn.org/stable/auto_examples/calibration/plot_calibration_multiclass.html#sphx-glr-auto-examples-calibration-plot-calibration-multiclass-py
下面的示例简单地检查是否允许其他值:
y_true = np.array([0, 1, 2])
y_pred = np.array([[0.5,0.5,0.0],[0.5,0.4,0.1], [0.4,0.1,0.5]])
metrics.log_loss(y_true, y_pred)
Output:- 1.3040076684760489 (No error)