如何使用烤宽面条计算 F1-micro 分数
How to calculate F1-micro score using lasagne
import theano.tensor as T
import numpy as np
from nolearn.lasagne import NeuralNet
def multilabel_objective(predictions, targets):
epsilon = np.float32(1.0e-6)
one = np.float32(1.0)
pred = T.clip(predictions, epsilon, one - epsilon)
return -T.sum(targets * T.log(pred) + (one - targets) * T.log(one - pred), axis=1)
net = NeuralNet(
# your other parameters here (layers, update, max_epochs...)
# here are the one you're interested in:
objective_loss_function=multilabel_objective,
custom_score=("validation score", lambda x, y: np.mean(np.abs(x - y)))
)
我在网上找到这段代码,想测试一下。它确实有效,结果包括训练损失、测试损失、验证分数和时间等。
但是如何获得F1-micro分数呢?另外,如果我在添加以下代码后尝试导入 scikit-learn 来计算 F1:
data = data.astype(np.float32)
classes = classes.astype(np.float32)
net.fit(data, classes)
score = cross_validation.cross_val_score(net, data, classes, scoring='f1', cv=10)
print score
我收到这个错误:
ValueError: Can't handle mix of multilabel-indicator and
continuous-multioutput
如何根据以上代码实现F1微计算?
假设您在测试集上的真实标签是 y_true
(形状:(n_samples, n_classes)
,仅由 0 和 1 组成),并且您的测试观察值是 X_test
(形状:(n_samples, n_features)
).
然后你在 y_test = net.predict(X_test)
的测试集上得到你的净预测值。
如果你正在做多class class化:
由于在您的网络中您已将 regression
设置为 False
,因此这也应该仅由 0 和 1 组成。
您可以计算微平均 f1 分数:
from sklearn.metrics import f1_score
f1_score(y_true, y_pred, average='micro')
用于说明这一点的小代码示例(使用虚拟数据,使用您的实际 y_test
和 y_true
):
from sklearn.metrics import f1_score
import numpy as np
y_true = np.array([[0, 0, 1], [0, 1, 0], [0, 0, 1], [0, 0, 1], [0, 1, 0]])
y_pred = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 1], [0, 0, 1]])
t = f1_score(y_true, y_pred, average='micro')
如果你在做多标签class化:
您输出的不是 0 和 1 的矩阵,而是概率矩阵。 y_pred[i, j] 是观察 i 属于 class j 的概率。
您需要定义一个阈值,高于该阈值您将说观察属于给定 class。然后,您可以相应地为标签添加属性,并按照与前一种情况相同的方式进行操作。
thresh = 0.8 # choose your own value
y_test_binary = np.where(y_test > thresh, 1, 0)
# creates an array with 1 where y_test>thresh, 0 elsewhere
f1_score(y_true, y_pred_binary, average='micro')
import theano.tensor as T
import numpy as np
from nolearn.lasagne import NeuralNet
def multilabel_objective(predictions, targets):
epsilon = np.float32(1.0e-6)
one = np.float32(1.0)
pred = T.clip(predictions, epsilon, one - epsilon)
return -T.sum(targets * T.log(pred) + (one - targets) * T.log(one - pred), axis=1)
net = NeuralNet(
# your other parameters here (layers, update, max_epochs...)
# here are the one you're interested in:
objective_loss_function=multilabel_objective,
custom_score=("validation score", lambda x, y: np.mean(np.abs(x - y)))
)
我在网上找到这段代码,想测试一下。它确实有效,结果包括训练损失、测试损失、验证分数和时间等。
但是如何获得F1-micro分数呢?另外,如果我在添加以下代码后尝试导入 scikit-learn 来计算 F1:
data = data.astype(np.float32)
classes = classes.astype(np.float32)
net.fit(data, classes)
score = cross_validation.cross_val_score(net, data, classes, scoring='f1', cv=10)
print score
我收到这个错误:
ValueError: Can't handle mix of multilabel-indicator and continuous-multioutput
如何根据以上代码实现F1微计算?
假设您在测试集上的真实标签是 y_true
(形状:(n_samples, n_classes)
,仅由 0 和 1 组成),并且您的测试观察值是 X_test
(形状:(n_samples, n_features)
).
然后你在 y_test = net.predict(X_test)
的测试集上得到你的净预测值。
如果你正在做多class class化:
由于在您的网络中您已将 regression
设置为 False
,因此这也应该仅由 0 和 1 组成。
您可以计算微平均 f1 分数:
from sklearn.metrics import f1_score
f1_score(y_true, y_pred, average='micro')
用于说明这一点的小代码示例(使用虚拟数据,使用您的实际 y_test
和 y_true
):
from sklearn.metrics import f1_score
import numpy as np
y_true = np.array([[0, 0, 1], [0, 1, 0], [0, 0, 1], [0, 0, 1], [0, 1, 0]])
y_pred = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 1], [0, 0, 1]])
t = f1_score(y_true, y_pred, average='micro')
如果你在做多标签class化:
您输出的不是 0 和 1 的矩阵,而是概率矩阵。 y_pred[i, j] 是观察 i 属于 class j 的概率。
您需要定义一个阈值,高于该阈值您将说观察属于给定 class。然后,您可以相应地为标签添加属性,并按照与前一种情况相同的方式进行操作。
thresh = 0.8 # choose your own value
y_test_binary = np.where(y_test > thresh, 1, 0)
# creates an array with 1 where y_test>thresh, 0 elsewhere
f1_score(y_true, y_pred_binary, average='micro')