You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Sklearn的10折CV中手动固定20%验证集大小且不打乱数据

问题解答

当然可以用Sklearn实现你需要的这种自定义交叉验证策略。核心思路是自定义验证集的拆分规则,因为Sklearn允许传入自定义的交叉验证生成器来替代默认的KFold等方法。

具体实现步骤

你的需求是:10次迭代、每次验证集固定20%(1165个样本)、数据不打乱、验证集按顺序滑动覆盖整个数据集。可以通过两种方式实现:

方式1:直接生成拆分索引

先计算验证集大小,然后手动生成10组训练/验证索引对,传给cross_val_score的cv参数:

import numpy as np
from sklearn.model_selection import cross_val_score

# 计算验证集大小
val_size = int(0.2 * 5829)  # 1165
n_splits = 10
n_samples = 5829

# 生成自定义拆分
def custom_split():
    # 计算步长,确保10次迭代能覆盖整个数据集
    step = (n_samples - val_size) // (n_splits - 1)
    for i in range(n_splits):
        val_start = i * step
        val_end = val_start + val_size
        # 处理最后一次可能超出数据集长度的情况
        if val_end > n_samples:
            val_end = n_samples
            val_start = n_samples - val_size
        # 生成训练集和验证集索引
        train_idx = np.concatenate([np.arange(val_start), np.arange(val_end, n_samples)])
        val_idx = np.arange(val_start, val_end)
        yield train_idx, val_idx

# 使用自定义拆分进行交叉验证
scores = cross_val_score(your_model, X, y, cv=custom_split())

方式2:自定义交叉验证类(更规范)

继承Sklearn的BaseCrossValidator类,封装拆分逻辑,适合复用:

import numpy as np
from sklearn.model_selection import BaseCrossValidator, cross_val_score

class SlidingWindowCV(BaseCrossValidator):
    def __init__(self, n_splits, val_size):
        self.n_splits = n_splits
        self.val_size = val_size
    
    def get_n_splits(self, X=None, y=None, groups=None):
        return self.n_splits
    
    def split(self, X, y=None, groups=None):
        n_samples = len(X)
        step = (n_samples - self.val_size) // (self.n_splits - 1) if self.n_splits > 1 else 0
        for i in range(self.n_splits):
            val_start = i * step
            val_end = val_start + self.val_size
            if val_end > n_samples:
                val_end = n_samples
                val_start = n_samples - self.val_size
            train_idx = np.concatenate([np.arange(val_start), np.arange(val_end, n_samples)])
            val_idx = np.arange(val_start, val_end)
            yield train_idx, val_idx

# 实例化自定义交叉验证器
cv = SlidingWindowCV(n_splits=10, val_size=1165)
# 执行交叉验证
scores = cross_val_score(your_model, X, y, cv=cv)

关键说明

  • 两种方式都完全符合你的要求:数据不打乱、验证集固定20%大小、10次迭代、验证集按顺序滑动。
  • 代码中加入了对最后一次迭代的边界处理,确保验证集不会超出数据集范围,始终保持1165个样本。

内容的提问来源于stack exchange,提问作者Murilo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 11:42:25