机器学习模型通常需要大量数据,但它们如何在实时中处理新数据至关重要。交叉验证是一种通过将数据分成多个部分,使用部分数据训练模型,剩余部分测试模型来测试模型效果的方法。这有助于发现过拟合和欠拟合,提供模型在实际情况中表现的一个概念。
本指南将带您了解交叉验证的基础知识、类型以及最佳使用方法,以提高您的机器学习效果。
在开始实际的交叉验证之前,请确保您对以下内容有良好的理解:
要跟随我们的示例,请确保您的计算机上安装了Python和以下库:
pip install numpy pandas scikit-learn matplotlib
让我们从头开始:交叉验证是最广泛使用的数据重采样方法之一,用于评估预测模型的泛化能力并防止过拟合。与简单的训练-测试分割不同,它通过轮换训练和测试集提供更全面的理解。这有助于确保每个数据点都有机会被测试,并有助于获得可靠的性能指标。
交叉验证有多种类型,每种类型适用于不同的数据结构和技术。让我们来看看最常用的技术。
过程:
优点:
注意事项:
代码示例:
from sklearn.model_selection import KFoldfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_scoreimport numpy as np# 示例数据X = np.random.rand(100, 5) # 100个样本,5个特征y = np.random.randint(0, 2, 100) # 二元目标变量kf = KFold(n_splits=5)model = LogisticRegression()accuracies = []for train_index, test_index in kf.split(X): X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] model.fit(X_train, y_train) predictions = model.predict(X_test) accuracies.append(accuracy_score(y_test, predictions))print("平均准确率:", np.mean(accuracies))
分层k折交叉验证类似于普通的k折,但它确保每个折叠具有与整个数据集相同的类别分布。这使得它特别适合于不平衡的数据集。
代码示例:
from sklearn.model_selection import StratifiedKFoldskf = StratifiedKFold(n_splits=5)accuracies = []for train_index, test_index in skf.split(X, y): X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] model.fit(X_train, y_train) predictions = model.predict(X_test) accuracies.append(accuracy_score(y_test, predictions))print("分层平均准确率:", np.mean(accuracies))
在每次运行中,留一法交叉验证(LOOC)使用一个数据点进行测试,其余数据用于训练。这个过程非常彻底,但对于大型数据集来说计算量很大。
代码示例:
from sklearn.model_selection import StratifiedKFoldskf = StratifiedKFold(n_splits=5)accuracies = []for train_index, test_index in skf.split(X, y): X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] model.fit(X_train, y_train) predictions = model.predict(X_test) accuracies.append(accuracy_score(y_test, predictions))print("分层平均准确率:", np.mean(accuracies))
时间序列交叉验证具有以下特点:
代码示例:
from sklearn.model_selection import TimeSeriesSplittscv = TimeSeriesSplit(n_splits=3)accuracies = []for train_index, test_index in tscv.split(X): X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] model.fit(X_train, y_train) predictions = model.predict(X_test) accuracies.append(accuracy_score(y_test, predictions))print("时间序列交叉验证准确率:", np.mean(accuracies))
以下是组k折交叉验证与其他交叉验证方法的不同之处:
代码示例:
from sklearn.model_selection import GroupKFold# 模拟分组数据groups = np.random.randint(0, 5, len(X)) # 5个独特的组gkf = GroupKFold(n_splits=5)accuracies = []for train_index, test_index in gkf.split(X, y, groups): X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] model.fit(X_train, y_train) predictions = model.predict(X_test) accuracies.append(accuracy_score(y_test, predictions))print("组K折交叉验证准确率:", np.mean(accuracies))
为什么我们要进行这种重采样过程来构建模型?以下是一些重要原因:
以下是使用交叉验证的一些重要最佳实践:
可视化示例:
import matplotlib.pyplot as pltfrom sklearn.datasets import make_classificationfrom sklearn.model_selection import KFoldX, y = make_classification(n_samples=100, n_features=2, n_classes=2, random_state=42, n_informative=2, n_redundant=0)kf = KFold(n_splits=5)plt.figure(figsize=(10, 6))for i, (train_index, test_index) in enumerate(kf.split(X)): plt.scatter(X[test_index, 0], X[test_index, 1], label=f'折叠 {i + 1}')plt.title('K折交叉验证分割')plt.xlabel('特征 1')plt.ylabel('特征 2')plt.legend()plt.show()
上面的可视化展示了数据集如何被分成5个不同的折叠用于交叉验证。每种颜色代表在每个折叠中分配给测试集的数据点。
交叉验证是机器学习中的一个重要工具,确保模型能够很好地泛化,并提供对模型性能的洞察。通过正确的交叉验证技术和最佳实践,你可以在构建用于实际应用的稳健、可靠模型时多一个工具。