目录

机器学习 - 交叉验证


在此页面上,W3schools.com 与纽约数据科学院,为我们的学生提供数字培训内容。


交叉验证

在调整模型时,我们的目标是提高未见数据的整体模型性能。超参数调整可以在测试集上带来更好的性能。然而,优化测试集的参数可能会导致信息泄漏,导致模型在未见过的数据上表现更差。为了纠正这个问题,我们可以执行交叉验证。

为了更好地理解 CV,我们将对 iris 数据集执行不同的方法。让我们首先加载并分离数据。

from sklearn import datasets

X, y = datasets.load_iris(return_X_y=True)

交叉验证的方法有很多,我们将从 k 折交叉验证开始。


K-折叠

模型中使用的训练数据被分成 k 个较小的集合,用于验证模型。然后在 k-1 倍训练集上训练模型。然后将剩余的折叠用作验证集来评估模型。

由于我们将尝试对不同种类的鸢尾花进行分类,因此我们需要导入一个分类器模型,在本练习中,我们将使用DecisionTreeClassifier。我们还需要从以下位置导入 CV 模块sklearn

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import KFold, cross_val_score

加载数据后,我们现在可以创建并拟合模型以进行评估。

clf = DecisionTreeClassifier(random_state=42)

现在让我们评估我们的模型,看看它在每个模型上的表现如何k-折叠。

k_folds = KFold(n_splits = 5)

scores = cross_val_score(clf, X, y, cv = k_folds)

通过平均所有折叠的分数来了解 CV 的整体表现也是一个很好的做法。

示例

运行 k 折 CV:

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import KFold, cross_val_score

X, y = datasets.load_iris(return_X_y=True)

clf = DecisionTreeClassifier(random_state=42)

k_folds = KFold(n_splits = 5)

scores = cross_val_score(clf, X, y, cv = k_folds)

print("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
运行示例 »

广告


分层K折

在类别不平衡的情况下,我们需要一种方法来解释训练集和验证集的不平衡。为此,我们可以对目标类别进行分层,这意味着两组的所有类别的比例相同。

示例

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import StratifiedKFold, cross_val_score

X, y = datasets.load_iris(return_X_y=True)

clf = DecisionTreeClassifier(random_state=42)

sk_folds = StratifiedKFold(n_splits = 5)

scores = cross_val_score(clf, X, y, cv = sk_folds)

print("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
运行示例 »

虽然折叠数量相同,但在确保存在分层类别时,平均 CV 会从基本 k 折叠增加。


留一法 (LOO)

不像 k-fold LeaveOneOut 那样选择训练数据集中的分割数量,而是利用 1 个观察值进行验证,并使用 n-1 个观察值进行训练。这种方法是一种穷举技术。

示例

运行 LOO 简历:

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import LeaveOneOut, cross_val_score

X, y = datasets.load_iris(return_X_y=True)

clf = DecisionTreeClassifier(random_state=42)

loo = LeaveOneOut()

scores = cross_val_score(clf, X, y, cv = loo)

print("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
运行示例 »

我们可以观察到执行的交叉验证分数的数量等于数据集中的观察数量。在本例中,iris 数据集中有 150 个观测值。

平均简历分数为 94%。


保留 P-Out (LPO)

Leave-P-Out 只是与 Leave-One-Out 思想的细微差别,因为我们可以选择在验证集中使用的 p 数量。

示例

运行 LPO CV:

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import LeavePOut, cross_val_score

X, y = datasets.load_iris(return_X_y=True)

clf = DecisionTreeClassifier(random_state=42)

lpo = LeavePOut(p=2)

scores = cross_val_score(clf, X, y, cv = lpo)

print("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
运行示例 »

正如我们所看到的,这是一种详尽的方法,即使 ap = 2,我们计算的分数也比留一法多得多,但它获得了大致相同的平均 CV 分数。


随机分割

不像KFold,ShuffleSplit遗漏了一定比例的数据,不用于训练或验证集。为此,我们必须决定训练和测试的规模以及分割的数量。

示例

运行随机播放拆分 CV:

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import ShuffleSplit, cross_val_score

X, y = datasets.load_iris(return_X_y=True)

clf = DecisionTreeClassifier(random_state=42)

ss = ShuffleSplit(train_size=0.6, test_size=0.3, n_splits = 5)

scores = cross_val_score(clf, X, y, cv = ss)

print("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
运行示例 »

结束语

这些只是可应用于模型的一些 CV 方法。还有更多的交叉验证类,大多数模型都有自己的类。查看 sklearns 交叉验证以获取更多 CV 选项。