交叉验证代码_交叉验证数据集的分割

7792e9abfb00eac8f172d9d19206a268.png

我们知道,交叉验证需要对数据集进行分割。而如何对数据进行分割呢?本文主要的内容就是提供一个分割的思路。所使用的程序语言基于python!

第一步,我们需要提供数据。数据其实无需多么实际,一个好的方法能够是能够尽可能适用于各类数据的。为了便于演示,我们使用自制的整数来进行交叉验证。如下所示。

f8f0c3f0422695244d312ac66d8a5c15.png

可以看出,这批数据共有95个样本。现在假设我们要把他分割成10份,训练集和验证集的比例为(9:1)。如果我们拿出了验证集,剩下的就是训练集了。因此首要目标应该是确定验证集,这样一来,剩下的就是训练集了。而要确定验证集,需要先确定分割后每份数据的大小。这一步可以通过公式:

,

其中,

这样一来,就得到了每一份的应有长度(由于

,因此存在某些份额的长度较小的问题)。之后,我们需要将数据安装这个比例进行分割,得到的分割数据应该长这个样:

2a36410621704c21d79963b5d2a0ec97.png

可以看出,我们成功的把数据分成了10份。现在,只需要一次选择第i个数组为验证集,而后剩下的就可以作为训练集了。这里的两行关键操作如下:

valid = [[divide[j] for j in i] for i in reindex]
train = [[divide[j] for j in range(sum(radio)) if j not in i] for i in reindex]

其中reindex是验证集的所有可能位置,在此处应该是[[0],[1],[2],...,[9]],而divide就是我们上图中的被分割过的数据了。通过这两部的嵌套列表操作,我们就能够得到训练集和验证集了。

验证集如下图所示(训练集数据量太大,不宜展示,可用代码自测)

8dd037b42208418005b017fa0ee64ce5.png

另外,假如

这样的比例(即验证集所占份额不只一份),可否进行操作呢?

同样是可行的,但是在如何生成reindex上就要动动脑筋,想想怎么做。

我这里使用了lambda 函数,以便针对不同比例测试集。具体的请看源代码。总之,得到的 reindex 应该如下:

fe39e14d105dada1e6140fa110c99717.png

同样的,针对每个验证集的给出的下标,挑选对应的数据即可。而剩下的按顺序形成对应的训练集。

由此得到的验证集如下图所示:

7a76d9d3b98ab7c8a9a68947f9fafe8f.png

它应该是一个11长度的列表,每个元素是由两个ndarray类型的数组组成的列表。

最后,附上包装好的函数代码文件。

import numpy as np
def crossvolid(mat, radio = (9,2)):
    long = len(mat)
    #pdb.set_trace()
    if len(radio) == 2:
        flag = radio[1]
    elif len(radio) == 3:
        flag = sum(radio[1:])
    if flag >= 4:
        raise ValueError
    
    index = list(range(sum(radio)))
    for i in range(flag-1):
        index.append(i)
    if flag == 1:
        fun = lambda index,i:[index[i]]
    if flag == 2:
        fun = lambda index,i:(index[i],index[i+1])
    if flag == 3:
        fun = lambda index,i:(index[i],index[i+1],index[i+2])
    reindex = [fun(index,i) for i in range(len(index)) if i<len(index)-flag+1]
    assert len(reindex) == sum(radio)
    
    every = round(long/sum(radio)+0.5)
    divide = []
    for i in range(sum(radio)):
        if i != sum(radio):
            sub = mat[i*every:(i+1)*every]
            divide.append(sub)
        else:
            sub = mat[i*every:]
            divide.append(sub)
    assert len(divide) == sum(radio)
    valid = [[divide[j] for j in i] for i in reindex]
    train = [[divide[j] for j in range(sum(radio)) if j not in i] for i in reindex]
    return train,valid
if __name__== '__main__':
    data = np.arange(1,96)
    train,valid = crossvolid(data)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值