我编写了一个简单的函数,其中使用 scikit-learn
中的
average_ precision_score来计算平均精度。
我的代码:
def compute_average_precision(predictions, gold):
gold_predictions = np.zeros(predictions.size, dtype=np.int)
for idx in range(gold):
gold_predictions[idx] = 1
return average_precision_score(predictions, gold_predictions)
当函数执行时,会产生以下错误。
Traceback (most recent call last):
File "test.py", line 91, in <module>
total_avg_precision += compute_average_precision(np.asarray(probs), len(gold_candidates))
File "test.py", line 29, in compute_average_precision
return average_precision_score(predictions, gold_predictions)
File "/if5/wua4nw/anaconda3/lib/python3.5/site-packages/sklearn/metrics/ranking.py", line 184, in average_precision_score
average, sample_weight=sample_weight)
File "/if5/wua4nw/anaconda3/lib/python3.5/site-packages/sklearn/metrics/base.py", line 81, in _average_binary_score
raise ValueError("{0} format is not supported".format(y_type))
ValueError: continuous format is not supported
如果我打印两个 numpy 数组
predictions
和 gold_predictions
,举个例子,它看起来不错。 [下面提供一个示例。]
[ 0.40865014 0.26047812 0.07588802 0.26604077 0.10586583 0.17118802
0.26797949 0.34618672 0.33659923 0.22075308 0.42288553 0.24908153
0.26506338 0.28224747 0.32942101 0.19986877 0.39831917 0.23635269
0.34715138 0.39831917 0.23635269 0.35822859 0.12110706]
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
我在这里做错了什么?错误是什么意思?
scikit-learn 中的许多指标仅适用于特定类型的目标数据。 Scikit-learn 使用实用函数
sklearn.utils.multiclass.type_of_target
来检查目标数据的类型。以下是可能的类型:
np.random.rand(100)
np.random.rand(100,2)
np.random.choice([0, 1], size=100)
np.random.choice([0, 1, 2], size=100)
np.random.choice([0, 1, 2], size=(100,2))
np.random.choice([0, 1], size=(100,2))
np.random.rand(100).astype(object)
传递给任何度量函数的第一个参数确定目标数据的类型。所以在OP的例子中,内部类型检查是在
predictions
变量上完成的,如下所示。
from sklearn.utils.multiclass import type_of_target
type_of_target(predictions) # 'continuous'
发生此错误的最常见方式是,当使用评估给定分数的分类任务性能的指标时,传递了不受支持的目标类型(可能像OP中那样错误地排序了参数)。下表总结了此类指标的所有支持类型。
连续 | 连续- 多输出 |
二进制 | 多类别 | 多类- 多输出 |
多标签- 指示器 |
未知 | |
---|---|---|---|---|---|---|---|
平均精度 分数 |
✔ | ✔ | |||||
覆盖范围 错误 |
✔ | ||||||
dcg 分数 | ✔ | ✔ | ✔ | ||||
检测曲线 | ✔ | ||||||
标签排名 平均精度 分数 |
✔ | ||||||
标签排名 损失 |
✔ | ||||||
ndcg 分数 | ✔ | ✔ | ✔ | ||||
查全率 曲线 |
✔ | ||||||
roc auc 分数 | ✔ | ✔ 必须通过 |
✔ | ||||
roc 曲线 | ✔ | ||||||
top-k 准确率分数 |
✔ | ✔ |
还有一些指标可以评估给定“类别预测”的分类任务的性能。它们通常适用于二元、多类或多标签指标目标类型。如果向其提供“错误”的目标类型,则会引发相关的 ValueError: Unknown label type
或
ValueError: y should be a 1d array
错误。下面总结了哪些指标允许哪些目标类型。
accuracy_score
、
classification_report
、
f1_score
、
fbeta_score
、
hamming_loss
、
jaccard_score
、
log_loss
、
multilabel_confusion_matrix
,
precision_recall_fscore_support
、
precision_score
、
recall_score
、
zero_one_loss
适用于二元、多类或多标签指标目标类型
balanced_accuracy_score
、
cohen_kappa_score
、
confusion_matrix
、
hinge_loss
、
matthews_corrcoef
》仅适用于二进制或多类
brier_score_loss
仅适用于二进制
ValueError: Classification metrics can't handle a mix of target types
。当预测类型与真实值类型不匹配时,就会发生这种情况,即,当
type_of_target(y_true) != type_of_target(y_pred)
时,就会发生这种情况。确保它们是相同的。
发生此错误的另一种方式是,如果您使用 sklearn.metrics.make_scorer
和
needs_threshold=True
创建自定义记分器。在这种情况下,仅接受二元或多标签指标目标类型,即使传递给评分器的基础指标适用于其他目标类型。例如,sklearn.metrics.top_k_accuracy_score
适用于多类目标类型,但如果通过需要阈值的metrics.make_scorer
将其制作为记分器,则它将不再起作用。import numpy as np
from sklearn import linear_model, metrics, datasets
X, y = datasets.make_classification(n_informative=3, n_classes=3) # multiclass
lr = linear_model.LogisticRegression()
lr.fit(X, y)
metrics.top_k_accuracy_score(y, lr.decision_function(X)) # <--- OK
scorer = metrics.make_scorer(metrics.top_k_accuracy_score, needs_threshold=True)
scorer(lr, X, y) # <--- ValueError: multiclass format is not supported