超参数和验证集

大多数机器学习算法都有超参数,超参数的值不是通过学习算法本身学习出来的。超参数之所以成为超参数,是因为它们大多数都不适合在训练集上学习,尤其是控制模型容量的超参数,因为它们总是会趋向于最大可能的模型容量,导致过拟合。

为解决这个问题,引入了验证集样本。将训练数据分成两个不相交的子集,其中一个用于学习参数,一个作为验证集,用于估计训练中或训练后的泛化误差,更新超参数。

交叉验证

当数据集太小时,将数据集分为训练集和测试集可能是有问题的。一个小规模的测试集意味着平均测试误差估计的统计不确定性。替代方法之一便是交叉验证,代价是增加了计算量。

最常见的是k-折交叉验证过程,将数据集分成 k 个不重合的子集。测试误差可以估计为 k 次计算后的平均测试误差。在第 i 次测试时,数据的第 i 个子集用于测试集,其他的数据用于训练集。

from sklearn import svm
from sklearn import datasets

digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
svc = svm.SVC(C=1, kernel='linear')
svc.fit(X_digits[:-100], y_digits[:-100]).score(X_digits[-100:], y_digits[-100:])

# using 3-fold cross-validation
X_folds = np.array_split(X_digits, 3)
y_folds = np.array_split(y_digits, 3)
scores = list()
for k in range(3):
    X_train = list(X_folds)
    X_test = X_train.pop(k)
    X_train = np.concatenate(X_train)
    y_train = list(y_folds)
    y_test = y_train.pop(k)
    y_train = np.concatenate(y_train)
    scores.append(svc.fit(X_train, y_train).score(X_test, y_test))

print(score)

在 sklearn中,我们可以直接调用函数:

from sklearn.model_selection import KFold, cross_val_score

X = ['a', 'a', 'b', 'c', 'c', 'c']
k_fold = KFold(n_splits=3)
for train_indices, test_indices in k_fold.split(X):
    print('Train: %s | Test: %s' % (train_indices, test_indices))

"""
Train: [2 3 4 5] | Test: [0 1]
Train: [0 1 4 5] | Test: [2 3]
Train: [0 1 2 3] | Test: [4 5]
"""

[svc.fit(X_digits[train], y_digits[train]).score(X_digits[test], y_digits[test])
for train, test in k_fold.split(X_digits)]
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐