【问题标题】:How to get both predicted value and error metric in sklearn如何在sklearn中同时获得预测值和误差度量
【发布时间】:2019-01-19 19:07:51
【问题描述】:

我有两个单独的 python 函数,其中一个使用 cross_val_predict 返回数据集的预测值,另一个使用 cross_validate 返回多个错误度量值。下面显示的是用于获取指标值的方法(我已经实现了类似的方法来获取预测值)。

def metric_val(folds):
.
.
.
scoring = {'r_score': 'r2',
           'abs_error': 'neg_mean_absolute_error',
           'squared_error': 'neg_mean_squared_error'}

scores = cross_validate(best_svr, X, y, scoring=scoring, cv=folds, return_train_score=True)

print("****\nR2 :", "", scores['test_r_score'].mean(),
      "| MAE :", scores['test_abs_error'].mean(),
      )
return prediction

我不想同时使用这两个函数,因为它的计算成本很高。是否有单一方法或替代方法可以同时获得预测和指标?

【问题讨论】:

  • 展示你是如何定义foldsscoring的,我们可以创建一个简单的函数来做到这一点。
  • 我已编辑以包含更多详细信息。谢谢
  • 什么是folds
  • folds指的是k-fold cross validation所需的折叠次数。例如,对于10-fold cross validation,它可以是10

标签: python machine-learning scikit-learn regression


【解决方案1】:

可以操纵计分器以使其返回预测,尽管这有点小技巧。操作方法如下:

cross_validate() 函数可以采用自定义评分函数。评分函数必须返回一个数字,但您可以在函数内做任何您想做的事情。由于您拥有clf 和所有测试数据,只需保存clf.predict() 的输出,然后返回一个虚拟值以让得分手满意。有关更多信息,请参阅Implementing your own scoring object 上的 sklearn 文档。

像这样:

from sklearn import svm, datasets
from sklearn.model_selection import train_test_split, cross_validate, cross_val_predict

# example data
iris = datasets.load_iris()
X, y = iris.data, iris.target 
clf = svm.SVC(probability=True, random_state=0)

定义自定义get_preds() 函数,将其作为scorer 潜入:

def get_preds(clf, X, y): # y is required for a scorer but we won't use it
    with open("pred.csv", "ab+") as f: # append each fold to file
        np.savetxt(f, clf.predict(X))
    return 0

scoring = {'preds': get_preds,
           'accuracy': 'accuracy',
           'recall': 'recall_macro'} # add desired scorers here

k = 5
cross_validate(clf, X, y, 
               scoring=scoring, 
               return_train_score=True,
               cv = k)

重新加载get_preds(),重新调整形状以匹配折叠集,然后平均折叠:

preds = np.loadtxt("pred.csv").reshape(k, len(X))
my_preds = np.mean(my_preds, axis=0).round()

cross_val_predict() 预测进行比较:

cv_preds = cross_val_predict(clf, X, y, cv=k)

np.equal(my_preds, cv_preds).sum() # 487 out of 500

我们在这里看到临时的get_preds() 方法和cross_val_predict() 之间几乎完全一致。小的差异可能是由于我的平均方法与cross_val_predict 的不同(我只是四舍五入到最接近的整数类,不是很复杂),或者它可能与sklearn cross-validation docs 中这个略显神秘的注释有关:

请注意,此计算的结果可能与使用 cross_val_score 获得的结果略有不同,因为元素以不同的方式分组。

【讨论】:

  • 你能详细说明一下吗? cross_validate() k-fold 验证,它只有一个默认值cv=3(其中cvk 的kwarg)。但是你可以为cv 参数传入任何值k,它工作得很好。 (我刚刚在cv=5 上查看了这个示例数据。)
  • 我得到了那个部分。那么clf.predict(X) 是否提供与cross_val_predict 相同的结果?我也想得到预测值,但是当我应用 10 倍交叉验证并尝试打印出这些值时,它会给出大量的值,这与 cross_val_predict 不同。
  • 查看更新 - 我有一两个错误,但我的解决方案现在看起来基本与 cross_val_predict 一致。这对你也有用吗?
  • 它返回比数据集本身更多的值,给出此错误ValueError: cannot reshape array of size 3510 into shape (10,117)
  • 您能否确认我的解决方案适用于我提供的示例数据?如果您无法提供minimal reproducible example,则很难知道您的数据发生了什么。首先确认您的问题在此解决方案的一般情况下得到了回答,然后让我们看看我们是否可以找出您的数据和/或代码在哪里存在某种使事情变得混乱的边缘情况。
【解决方案2】:

在 sklearn 中没有预定义的函数可以计算预测和性能指标。 但是您可以使用sklearn.metrics 检索所有性能指标。

【讨论】:

    猜你喜欢
    • 2020-06-01
    • 1970-01-01
    • 2021-05-01
    • 2020-05-18
    • 1970-01-01
    • 2015-09-16
    • 2015-01-27
    • 2016-04-01
    • 1970-01-01
    相关资源
    最近更新 更多