在我们前面的数据科学系列文章中,我们通过两个案例研究(回归和分类)对数据分析和建模进行了详细探讨。在这些基础上,本系列将深入探讨机器学习中的各种技术和方法,旨在帮助读者掌握更复杂的机器学习模型及其应用。

        本系列的第一篇文章将重点介绍交叉验证,这是一种用于模型评估和优化的重要技术。通过交叉验证,我们可以更准确地评估模型的性能,并有效避免过拟合和欠拟合问题。

交叉验证概述

        交叉验证是一种将数据集分成多个子集的方法,以便对模型进行多次训练和测试,从而获得更可靠的性能评估。通过这种方法,我们可以更好地了解模型在不同数据分布下的表现,减少由于数据分割带来的偏差。

数据形状要求        

        在使用 Scikit-Learn 之前,需要了解数据形状的基本要求。大多数算法需要两个输入,即 X 和 y:

  • X:特征矩阵,形状为 [n_samples, n_features]
  • y:目标/标签向量,形状为 [n_samples,] 或 [n_samples, n_targets](取决于算法是否支持多标签)

注意

  1. 如果 X 只有一个特征,形状必须是 [n_samples, 1] 而不是 [n_samples,]。
  2. Scikit-Learn 支持 numpy 和 pandas 数据,只要形状正确。例如,如果使用 pandas,X 可以是 DataFrame,y 可以是 Series 或 DataFrame。

Scikit-Learn API 基础用法

使用 Scikit-Learn API 的常见步骤如下:

  1. 导入模型类
  2. 通过实例化该类选择模型的超参数
  3. 将数据安排成特征矩阵和目标向量
  4. 使用 fit() 方法将模型拟合到数据上
  5. 使用 predict() 方法进行推断

实践操作

        首先,我们加载一个回归数据集,并进行预处理。

import numpy as np
from sklearn.datasets import load_diabetes
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

diabetes = load_diabetes()
X = diabetes.data
y = diabetes.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

导入模型类

from sklearn.linear_model import LinearRegression

选择模型超参数

        对于线性回归示例,我们可以实例化 LinearRegression 类,并指定我们希望通过 fit_intercept 超参数来拟合截距:

model = LinearRegression(fit_intercept=True)
model

数据安排

        确保特征矩阵和目标向量的形状正确:

assert len(X_train.shape) == 2 and len(X_test.shape) == 2  # 确保特征矩阵形状正确
assert len(y_train.shape) == 1 and len(y_test.shape) == 1  # 确保目标向量形状正确

拟合模型

model.fit(X_train, y_train)  # 使用训练集拟合模型

进行预测

y_hat = model.predict(X_test)  # 使用测试集进行预测

计算均方误差

from sklearn.metrics import mean_squared_error
mean_squared_error(y_test, y_hat)

交叉验证的应用

        仅使用训练集和测试集进行模型评估并不可靠,因为这可能会导致模型对数据分割方式的偶然性过于敏感。交叉验证通过多次分割数据并重复训练和测试,提供了更可靠的模型评估方法。

K折交叉验证

        K折交叉验证是一种常见的交叉验证方法,将数据分成K个子集,每次使用其中一个子集进行测试,其余子集用于训练。

from sklearn.model_selection import cross_val_score
cross_val_score(model, X_train, y_train, cv=5)  # 5折交叉验证

ShuffleSplit

        ShuffleSplit 是 KFold 的一种变体,允许更精细地控制迭代次数和每次分割的样本比例。

from sklearn.model_selection import ShuffleSplit

shuffle_cv = ShuffleSplit(n_splits=5, test_size=0.3, random_state=0)
cross_val_score(model, X_train, y_train, cv=shuffle_cv)

分层K折交叉验证

        分层K折交叉验证确保每个子集中各类样本的比例与原始数据集中相同,适用于分类问题。

from sklearn.model_selection import StratifiedKFold

sk_cv = StratifiedKFold(n_splits=3)
cross_val_score(model, X_train, y_train, cv=sk_cv)

Group KFold

        Group KFold 确保同一组的数据不会同时出现在训练集和测试集中,适用于需要避免组数据泄露的情况。

from sklearn.model_selection import GroupKFold

gkf = GroupKFold(n_splits=5)
groups = np.random.randint(0, 5, size=y_train.shape[0])
cross_val_score(model, X_train, y_train, cv=gkf, groups=groups)

网格搜索与嵌套交叉验证

网格搜索

        网格搜索通过自动尝试多种超参数组合,找到模型的最佳配置。

from sklearn.model_selection import GridSearchCV

param_grid = {'fit_intercept': [True, False], 'positive': [True, False]}
grid = GridSearchCV(model, param_grid, cv=shuffle_cv, refit=True)
grid.fit(X_train, y_train)
grid.best_params_

嵌套交叉验证

        嵌套交叉验证通过将交叉验证嵌套在另一个交叉验证中,进一步提高模型评估的稳定性和可靠性。

from sklearn.model_selection import KFold

inner_cv = KFold(n_splits=4, shuffle=True, random_state=1)
outer_cv = KFold(n_splits=4, shuffle=True, random_state=1)

inner_model = GridSearchCV(model, param_grid=param_grid, cv=inner_cv)
nested_score = cross_val_score(inner_model, X, y, scoring='neg_mean_squared_error', cv=outer_cv)
nested_score.mean()

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

08-17 13:26