2021SC@SDUSC
代码地址:similarity/f1_score.py at master · tensorflow/similarity · GitHub
import tensorflow as tf
from tensorflow_similarity.types import FloatTensor
from .classification_metric import ClassificationMetric
class F1Score(ClassificationMetric):
"""Calculates the harmonic mean of precision and recall.
Computes the F-1 Score given the query classification counts. The metric is
computed as follows:
$$
F_1 = 2 \cdot \frac{\textrm{precision} \cdot \textrm{recall}}{\textrm{precision} + \textrm{recall}}
$$
args:
name: Name associated with a specific metric object, e.g.,
f1@0.1
Usage with `tf.similarity.models.SimilarityModel()`:
```python
model.calibrate(x=query_examples,
y=query_labels,
calibration_metric='f1')
```
"""
def __init__(self, name: str = 'f1') -> None:
super().__init__(
name=name,
canonical_name='f1_score')
def compute(self,
tp: FloatTensor,
fp: FloatTensor,
tn: FloatTensor,
fn: FloatTensor,
count: int) -> FloatTensor:
"""Compute the classification metric.
The `compute()` method supports computing the metric for a set of
values, where each value represents the counts at a specific distance
threshold.
Args:
tp: A 1D FloatTensor containing the count of True Positives at each
distance threshold.
fp: A 1D FloatTensor containing the count of False Positives at
each distance threshold.
tn: A 1D FloatTensor containing the count of True Negatives at each
distance threshold.
fn: A 1D FloatTensor containing the count of False Negatives at
each distance threshold.
count: The total number of queries
Returns:
A 1D FloatTensor containing the metric at each distance threshold.
"""
recall = tf.math.divide_no_nan(tp, tp + fn)
precision = tf.math.divide_no_nan(tp, tp + fp)
numer = 2 * recall * precision
denom = recall + precision
result: FloatTensor = tf.math.divide_no_nan(numer, denom)
return result
一般来说,我们更喜欢具有更高精度和召回分数的分类器。然而,精度和召回率之间存在权衡:在调整分类器时,提高精度分数通常会降低召回分数,反之亦然——天下没有免费的午餐。
现在假设你有两个分类器——分类器 A 和分类器 B——每个都有自己的精度和召回率。一个有更好的召回分数,另一个有更好的精度。我们想谈谈他们的相对表现。换句话说,我们想将模型的性能总结为一个指标。这就是使用 F1 分数的地方。这是一种将精度和召回率组合成一个数字的方法。 F1 分数是使用平均值(“平均值”)计算的,而不是通常的算术平均值。它使用调和平均值,由这个简单的公式给出:
F1-score = 2 ×(精度 × 召回率)/(精度 + 召回率)
在上面的例子中,我们的二元分类器的 F1 分数是:
F1-score = 2 × (83.3% × 71.4%) / (83.3% + 71.4%) = 76.9%
与算术平均值类似,F1 分数将始终介于准确率和召回率之间。但它的行为有所不同:F1 分数赋予较低数字更大的权重。例如,当 Precision 为 100% 且 Recall 为 0% 时,F1-score 将为 0%,而不是 50%。或者例如,假设分类器 A 的精度=召回率=80%,分类器 B 的精度=60%,召回率=100%。从算术上讲,两种模型的准确率和召回率的平均值是相同的。但是当我们使用 F1 的调和平均公式时,分类器 A 的得分将是 80%,而分类器 B 的得分仅为 75%。 Model B 的低精度分数拉低了其 F1 分数。