在交叉验证集上评估从训练集中获得的损失函数值

Evaluate Loss Function Value Getting From Training Set on Cross Validation Set

我正在按照 Andrew NG 的说明评估分类中的算法:

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

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

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.

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

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

基本上您的数据被拆分为 n_splits = 10,其中一些拆分缺少 class。例如,您的第 9 个拆分可​​能没有 class 数字 2.

的训练示例

因此,当您评估损失时,您的预测与测试集之间现有 class 的数量不匹配。因此,如果 y_true 中有 3 个 class 并且您的模型被训练为仅预测 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. 樱桃挑选你的分裂,以确保这不会发生。我不认为 Kfold 允许这样做,但 GridSearchCV 允许

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

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 

Al 已经在评论中提到,在这种情况下包含对数损失在 scikit-learn 中仍然存在一些未解决的问题(参见 here and here)。

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

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

K-Fold实际适用于这个目的,因为我们主要想评估某个算法产生的Thetas(即权重)与一些parameters 通过在两个成本函数 J(train)J(CV) 之间的比较中使用这些 Thetas 来确定是否该模型存在 偏差方差O.K.

然而,K-Fold主要用于测试使用模型训练产生的权重对CV进行预测训练集。