【问题标题】:Evaluate Loss Function Value Getting From Training Set on Cross Validation Set评估从交叉验证集上的训练集获得的损失函数值
【发布时间】:2019-01-14 12:02:04
【问题描述】:

我正在按照 Andrew NG 的指令来评估分类中的算法:

  1. 求训练集的损失函数。
  2. 将其与交叉验证的损失函数进行比较。
  3. 如果两者足够接近且足够小,请转到下一步(否则,存在偏差或方差..等)。
  4. 使用上一步生成的 Thetas(即权重)对测试集进行预测作为最终确认。

我正在尝试使用 Scikit-Learn Library 来应用它,但是,我真的迷路了,并且确定我完全错了(我没有在网上找到类似的东西):

from sklearn import model_selection, svm
from sklearn.metrics import make_scorer, log_loss
from sklearn import datasets

def main():

    iris = datasets.load_iris()
    kfold = model_selection.KFold(n_splits=10, random_state=42)
    model= svm.SVC(kernel='linear', C=1)
    results = model_selection.cross_val_score(estimator=model,
                                              X=iris.data,
                                              y=iris.target,
                                              cv=kfold,
                                              scoring=make_scorer(log_loss, greater_is_better=False))

    print(results)

错误

ValueError: y_true contains only one label (0). Please provide the true labels explicitly through the labels argument.

我不确定它是否是正确的开始方式。非常感谢任何帮助。

【问题讨论】:

  • 问题似乎是这里的评分(损失函数)。这似乎是sklearn 中的一个错误,您可以see here

标签: python machine-learning scikit-learn loss-function


【解决方案1】:

鉴于您在 cmets 中提供的说明以及您对 log loss 本身并不特别感兴趣,我认为最直接的方法是放弃 log loss 并转而追求准确性:

from sklearn import model_selection, svm
from sklearn import datasets

iris = datasets.load_iris()
kfold = model_selection.KFold(n_splits=10, random_state=42)
model= svm.SVC(kernel='linear', C=1)
results = model_selection.cross_val_score(estimator=model,
                                              X=iris.data,
                                              y=iris.target,
                                              cv=kfold,
                                              scoring="accuracy")  # change 

在 cmets 中已经提到,在这种情况下包含日志丢失仍然会受到 scikit-learn 中一些未解决的问题的影响(请参阅 herehere)。

为了估计模型的泛化能力,您可以使用准确度指标。

【讨论】:

  • 谢谢,加一...我刚刚对 Andrew 的教程感到困惑,该教程介绍了如何通过比较 CV 和 Training J-Cost Function 来选择最佳模型并选择最小的接近模型。
【解决方案2】:

这种错误在你做交叉验证时经常出现。

基本上,您的数据被拆分为n_splits = 10,其中一些拆分中缺少一些类。例如,您的第 9 次分组可能没有第 2 类的训练示例。

因此,当您评估损失时,您的预测和测试集之间的现有类数不匹配。因此,如果您在 y_true 中有 3 个类并且您的模型被训练为仅预测 2 个类,则您无法计算损失。

在这种情况下你会怎么做?

你有三种可能:

  1. 洗牌你的数据KFold(n_splits=10, random_state=42, shuffle = True)
  2. 让 n_splits 更大
  3. 向损失函数明确提供标签列表,如下所示

args_loss = { "labels": [0,1,2] } make_scorer(log_loss, greater_is_better=False,**args_loss)

  1. Cherry 选择你的分裂,以确保不会发生这种情况。我不认为 Kfold 允许这样做,但 GridSearchCV 允许

【讨论】:

  • 我喜欢你对问题的解释,但事情正在过去 "labels": [0,1,2] throws ValueError: The number of classes in labels is different from that in y_pred. Classes found in labels: [0 1 2] .. 我相信你的意思是 make n_splits smaller 不是更大
  • 这首先是我的想法,但事实证明并非如此:替换为scoring="accuracy" 同时保持n_splits=10 可以正常工作;此外,减少nsplits 和/或改组数据并不能解决问题。原因是损失函数本身,正如@ncfirth 已经在 OP 中评论的那样
  • @desertnaut 我真的需要听从 Andrew 的指示,还是仅仅获得准确度或 F1-Score 等?
  • 取决于您要达到的目标!如果你对准确性没问题,那就去吧……
  • @desertnaut 我想要实现的是估计算法对看不见的数据的泛化能力,以避免过拟合和欠拟合,即(模型选择
【解决方案3】:

仅供关注 Andrew 课程的未来读者使用:

K-Fold实际上适用于这个目的,因为我们主要想用一些参数评估某个算法产生的Thetas(即权重) > 在交叉验证集上使用这些 Thetas 比较成本函数 J(train)J(CV) 以确定模型是否存在偏差方差 或者它是好的

不过,K-Fold 主要用于测试使用在训练集上训练模型产生的权重对 CV 的预测。

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 2018-05-03
    • 2022-11-08
    • 2020-07-07
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    相关资源
    最近更新 更多