使用keras库可以获得以下精度:
model.compile(optimizer='sgd',
loss='mse',
metrics=[tf.keras.metrics.Precision()])
sklearn计算的精度与keras计算的精度是什么类型的?
precision_score(y_true, y_pred, average=???)
- 宏
- micro
- 加权的
- 无
如下图所示,将zero_division设置为1时会发生什么?:
precision_score(y_true, y_pred, average=None, zero_division=1)
TLDR对于二进制分类,默认为binary
,对于多类分类,默认是micro
。其他平均类型如None
和macro
也可以通过如下所述的小修改来实现。
这应该会让您对tf.keras.Precision()
和sklearn.metrics.precision_score()
之间的差异有所了解。让我们比较一下不同的场景。
场景1:二进制分类
对于二进制分类,您的y_true和y_pred分别为0,1和0-1。两者的实现都非常直接。
Sklearn文档:仅报告pos_label指定的类的结果。这仅适用于目标(y_{true,pred}(为二进制的情况。
#Binary classification
from sklearn.metrics import precision_score
import tensorflow as tf
y_true = [0,1,1,1]
y_pred = [1,0,1,1]
print('sklearn precision: ',precision_score(y_true, y_pred, average='binary'))
#Only report results for the class specified by pos_label.
#This is applicable only if targets (y_{true,pred}) are binary.
m = tf.keras.metrics.Precision()
m.update_state(y_true, y_pred)
print('tf.keras precision:',m.result().numpy())
sklearn precision: 0.6666666666666666
tf.keras precision: 0.6666667
场景2:多类别分类(全局精度(
在这里,您使用的是多类标签,但您不必担心每个类的精度如何。您只需要一个TP和FP的全局集合来计算总精度分数。在sklearn
中,这由参数micro
设置,而在tf.keras
中,这是Precision()
的默认设置
Sklearn文档:通过计算真阳性、假阴性和假阳性的总数来全局计算度量。
#Multi-class classification (global precision)
#3 classes, 6 samples
y_true = [[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0],[0,0,1]]
y_pred = [[1,0,0],[0,0,1],[0,1,0],[1,0,0],[1,0,0],[0,1,0]]
print('sklearn precision: ',precision_score(y_true, y_pred, average='micro'))
#Calculate metrics globally by counting the total true positives, false negatives and false positives.
m.reset_states()
m = tf.keras.metrics.Precision()
m.update_state(y_true, y_pred)
print('tf.keras precision:',m.result().numpy())
sklearn precision: 0.3333333333333333
tf.keras precision: 0.33333334
场景3:多类别分类(每个标签的二进制精度(
如果您想知道每个类的精度,那么您对这个场景很感兴趣。在sklearn
中,这是通过将average
参数设置为None
来完成的,而在tf.keras
中,您必须使用class_id
分别为每个单独的类实例化对象。
Sklearn文档:如果无,则返回每个类的分数。
#Multi-class classification (binary precision for each label)
#3 classes, 6 samples
y_true = [[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0],[0,0,1]]
y_pred = [[1,0,0],[0,0,1],[0,1,0],[1,0,0],[1,0,0],[0,1,0]]
print('sklearn precision: ',precision_score(y_true, y_pred, average=None))
#If None, the scores for each class are returned.
#For class 0
m0 = tf.keras.metrics.Precision(class_id=0)
m0.update_state(y_true, y_pred)
#For class 1
m1 = tf.keras.metrics.Precision(class_id=1)
m1.update_state(y_true, y_pred)
#For class 2
m2 = tf.keras.metrics.Precision(class_id=2)
m2.update_state(y_true, y_pred)
mm = [m0.result().numpy(), m1.result().numpy(), m2.result().numpy()]
print('tf.keras precision:',mm)
sklearn precision: [0.66666667 0. 0. ]
tf.keras precision: [0.6666667, 0.0, 0.0]
场景4:多类分类(单个二进制分数的平均值(
一旦你计算了每个类别的个人精度,你可能需要取平均分数(或加权平均值(。在sklearn
中,通过将参数average
设置为macro
来获得个人得分的简单平均值。在tf.keras
中,您可以通过取上述场景中计算的单个精度的平均值来获得相同的结果。
Sklearn文档:计算每个标签的指标,并找到它们的未加权平均值。
#Multi-class classification (Average of individual binary scores)
#3 classes, 6 samples
y_true = [[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0],[0,0,1]]
y_pred = [[1,0,0],[0,0,1],[0,1,0],[1,0,0],[1,0,0],[0,1,0]]
print('sklearn precision (Macro): ',precision_score(y_true, y_pred, average='macro'))
print('sklearn precision (Avg of None):' ,np.average(precision_score(y_true, y_pred, average=None)))
print(' ')
print('tf.keras precision:',np.average(mm)) #mm is list of individual precision scores
sklearn precision (Macro): 0.2222222222222222
sklearn precision (Avg of None): 0.2222222222222222
tf.keras precision: 0.22222222
注意:请记住,使用sklearn
,您有直接预测标签的模型,而precision_score
是一个独立的方法。因此,它可以直接对预测值和实际值的标签列表进行操作。然而,tf.keras.Precision()
是一个必须应用于二进制或多类密集输出的度量。它将无法直接使用标签。您必须为每个样本提供一个n长度的数组,其中n是类/输出密集节点的数量。
希望这能澄清两种情况在不同情况下的不同。请在sklearn文档和tf.keras文档中找到更多详细信息。
您的第二个问题-
根据sklearn文档,
zero_division - “warn”, 0 or 1, default=”warn”
#Sets the value to return when there is a zero division. If set to “warn”, #this acts as 0, but warnings are also raised.
这是一个异常处理标志。在计算分数的过程中,如果遇到divide by zero
,它会认为它等于零并发出警告。否则,如果显式设置为1,请将其设置为1。