sklearn log_loss报Unknown label type错误的解决方法咨询
解决sklearn log_loss的ValueError问题
问题场景
执行sklearn的log损失计算时触发ValueError,代码逻辑为:用LabelEncoder拟合浮点型类别数组,再调用log_loss函数传入真实标签、类别概率及labels参数。
复现代码
from sklearn import preprocessing le = preprocessing.LabelEncoder() le.fit([2.5, 3.0, 3.5, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0]) from sklearn.metrics import log_loss le.classes_ log_loss([6.0], [[0., 0., 0., 0., 0.28571429, 0.14285714, 0., 0.57142857, 0. ]], labels=list(le.classes_))
报错信息
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) C:\Users\PRANAV~1\AppData\Local\Temp/ipykernel_25368/2311544075.py in <module> ----> 1 log_loss([6.0], [[0., 0., 0., 0., 0.28571429, 0.14285714, 2 0., 0.57142857, 0. ]], labels=list(le.classes_)) ~\AppData\Roaming\Python\Python39\site-packages\sklearn\utils\validation.py in inner_f(*args, **kwargs) 61 extra_args = len(args) - len(all_args) 62 if extra_args <= 0: ---> 63 return f(*args, **kwargs) 64 65 # extra_args > 0 ~\AppData\Roaming\Python\Python39\site-packages\sklearn\metrics\_classification.py in log_loss(y_true, y_pred, eps, normalize, sample_weight, labels) 2233 2234 if labels is not None: -> 2235 lb.fit(labels) 2236 else: 2237 lb.fit(y_true) ~\AppData\Roaming\Python\Python39\site-packages\sklearn\preprocessing\_label.py in fit(self, y) 295 296 self.sparse_input_ = sp.issparse(y) --> 297 self.classes_ = unique_labels(y) 298 return self 299 ~\AppData\Roaming\Python\Python39\site-packages\sklearn\utils\multiclass.py in unique_labels(*ys) 96 _unique_labels = _FN_UNIQUE_LABELS.get(label_type, None) 97 if not _unique_labels: ---> 98 raise ValueError("Unknown label type: %s" % repr(ys)) 99 100 ys_labels = set(chain.from_iterable(_unique_labels(y) for y in ys)) ValueError: Unknown label type: ([2.5, 3.0, 3.5, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0],)
原因分析
log_loss用于分类任务,要求标签为离散类型。但传入的labels是浮点型列表,sklearn将其误判为连续型标签,导致unique_labels函数无法识别标签类型。
解决方法
方法一:将真实标签转为LabelEncoder编码后的整数
利用LabelEncoder把原始浮点标签转为整数编码,此时无需指定labels参数,log_loss可直接匹配概率数组:
from sklearn import preprocessing from sklearn.metrics import log_loss le = preprocessing.LabelEncoder() le.fit([2.5, 3.0, 3.5, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0]) # 转换真实标签为整数编码 y_true_encoded = le.transform([6.0]) # 计算log损失 loss = log_loss(y_true_encoded, [[0., 0., 0., 0., 0.28571429, 0.14285714, 0., 0.57142857, 0.]]) print(loss)
方法二:将labels参数转为numpy数组
将labels从列表转为numpy数组,明确告知sklearn这是离散分类标签:
import numpy as np from sklearn import preprocessing from sklearn.metrics import log_loss le = preprocessing.LabelEncoder() le.fit([2.5, 3.0, 3.5, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0]) # 用numpy数组传入labels参数 loss = log_loss([6.0], [[0., 0., 0., 0., 0.28571429, 0.14285714, 0., 0.57142857, 0.]], labels=np.array(le.classes_)) print(loss)
内容的提问来源于stack exchange,提问作者pranav nerurkar
相关产品推荐
相关产品推荐

