我自己也面临过这个任务,我还没有找到比sklearn.metrics.get_scorer 函数更好的按名称访问指标的方法,但它的缺点是你必须在那里传递一个估计器,而不是预测。我尝试使用@collinb9 建议,但你看,你必须在那里访问一个受保护的方法,在我的例子中,它导致了令人不快的后果,即错误计算的指标。
这是一个显示此问题的简短示例。
from sklearn import datasets, model_selection, linear_model, metrics
features, labels = datasets.make_regression(1000, random_state=123)
train_features, test_features, train_labels, test_labels = model_selection.train_test_split(features, labels, test_size=0.1, random_state=567)
model = linear_model.LinearRegression()
model.fit(train_features, train_labels)
print(f'variant 1 neg_mse = {metrics.get_scorer("neg_mean_squared_error")(model, test_features, test_labels)}')
print(f'variant 1 neg_rmse = {metrics.get_scorer("neg_root_mean_squared_error")(model, test_features, test_labels)}\n')
preds = model.predict(test_features)
print(f'variant 2 mse = {metrics.mean_squared_error(test_labels, preds)}')
print(f'variant 2 rmse = {metrics.mean_squared_error(test_labels, preds, squared=False)}\n')
print(f'protected neg_mse = {metrics.get_scorer("neg_mean_squared_error")._score_func(test_labels, preds)}')
print(f'protected neg_rmse = {metrics.get_scorer("neg_root_mean_squared_error")._score_func(test_labels, preds)}')
这个程序的输出将是:
variant 1 neg_mse = -2.142587870436064e-25
variant 1 neg_rmse = -4.628809642268803e-13
variant 2 mse = 2.142587870436064e-25
variant 2 rmse = 4.628809642268803e-13
protected neg_mse = 2.142587870436064e-25
protected neg_rmse = 2.142587870436064e-25
您会看到,使用受保护方法计算的指标不同。首先,我们下令得到负值,但得到了正值(应该提到,对于variant 2 指标,我们并不暗示负值)。其次,neg_mse 和neg_rmse 的值相等但应该不同。
如果我们去sklearn metrics的源代码,我们会看到:
-
This is how
_score_func is called:乘以符号,这就是我们失去负值的地方。
-
This is how scorers are made:你看,
neg_root_mean_squared_error_scorer 有额外的参数squared=False。此参数在metrics.mean_squared_error 中明确说明为可选参数,因此您不会出错。我们可以将此参数作为关键字参数传递给_score_fun,至少我们会得到一个正确的绝对值:
print(f'protected neg_rmse = {metrics.get_scorer("neg_root_mean_squared_error")._score_func(test_labels, preds, squared=False)}')
protected neg_rmse = 4.628809642268803e-13
为了简单起见,据我所知,我已经展示了按名称获取 sklearn 指标的唯一方法(顺便说一句,您可以找到完整的名称列表 here),并且使用 protected 是不安全的你不应该使用的方法。顺便说一句,我使用的是 sklearn version=0.24.2。