大师兄的Python机器学习笔记:数据重抽样

大师兄的Python机器学习笔记:数据预处理
大师兄的Python机器学习笔记:实现评估模型

一、重抽样方法

1. 关于重抽样方法(Resampling Methods)

重抽样是统计学的重要工具,主要为了实现以下目标:

  • 估计样本统计量(如中位数、方差、分位数等)的精度;
  • 在做显著性检验(significance tests)时交换数据点的标签;
  • 用随机的样本子集验证模型的有效性。
2. 重抽样方法的种类

重抽样的方法包括:

  • 自助法(Booststraping)
  • 刀切法(Jackknife)
  • 置换验证(permutation tests)
  • 交叉验证(Cross-validation)
    ... ...
3. 关于交叉验证(Cross-Validation)
  • 交叉验证是一种模型验证技术,它主要用于估计一个预测模型的准确性。
  • 首先将样本分割成训练集和检验集两部分。
  • 其中训练集用来训练预测模型,检验集用来检验模型的准确性。
  • 在训练集上建模,在检验集评价分析模型。
  • 为了降低变异度,需要做多轮交叉验证,平均评价指标。

二、交叉验证的实现

1. 简单验证法(train_test_split)
  • 随机将样本数据分为两份,用训练集来训练模型,在测试集上验证模型及参数。
  • 优点:简单,只需要将数据分成两份。
  • 缺点:只进行了一次划分,数据结果偶然性大。
  • 实现方法一:自己写算法
>>>import os
>>>import pandas as pd
>>>from random import randrange,seed

>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def to_float(data):
>>>    # 将数据改为浮点数
>>>    for column in data:
>>>        if column =='date':continue # 跳过日期
>>>        if str(data[column][1]).isdigit(): # 如果是数字
>>>            data[column] = data[column].astype('float') # 将列转为浮点数
>>>    return data

>>>def train_test_split(dataset,train=0.6):
>>>    # train_test_split
>>>    seed(100)
>>>    train_basket = []
>>>    train_size = train*len(dataset)
>>>    dataset_copy = list(dataset)

>>>    while len(train_basket)<train_size:
>>>        random_choose_some_element = randrange(len(dataset_copy))
>>>        train_basket.append((dataset_copy.pop(random_choose_some_element)))

>>>    return train_basket,dataset_copy
>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = to_float(read_csv(file_path))#
>>>    data_cases = data['cases'] # 用新冠案例数做数据
>>>    train_basket,test_basket = train_test_split(data_cases)
>>>    print(f'共有数据:{len(data_cases)}个\n其中训练数据:{len(train_basket)}个\n测试数据:{len(test_basket)}')
共有数据:56541个
其中训练数据:33925个
测试数据:22616个
  • 实现方法二:用sklearn包中的算法
>>> import os
>>> import pandas as pd
>>> from sklearn.model_selection import train_test_split
>>> def read_csv(file):
>>>     # 获得文件中的数据
>>>     return pd.read_csv(file)

>>> def to_float(data):
>>>     # 将数据改为浮点数
>>>     for column in data:
>>>         if column =='date':continue # 跳过日期
>>>         if str(data[column][1]).isdigit(): # 如果是数字
>>>             data[column] = data[column].astype('float') # 将列转为浮点数
>>>     return data

>>> if __name__ == '__main__':
>>>     file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>     data = to_float(read_csv(file_path))#
>>>     data_cases = data['cases'] # 用新冠案例数做数据
>>>     train_basket,test_basket = rain_test_split(data_cases,test_size=0.4,random_state=100,shuffle=True)
>>>     print(f'共有数据:{len(data_cases)}个\n其中训练数据:{len(train_basket)}个\n测试数据:len(test_basket)}')
共有数据:56541个
其中训练数据:33924个
测试数据:22617个
2. K折交叉验证(K-Folder Cross Validation)
  • K折交叉验证会把样本数据随机的分成K份,每次随机的选择K-1份作为训练集,剩下的1份做测试集。
  • 相当于做了K次简单验证法。


  • 优点:降低由一次随机划分带来的偶然性,提高其泛化能力,提高对数据的使用效率。
  • 缺点:可能存在一种情况:数据集有5类,抽取出来的也正好是按照类别划分的5类, 造成数据高偏差。
  • 实现方法一:自己写算法
>>>import os
>>>import pandas as pd
>>>from random import randrange,seed

>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def to_float(data):
>>>    # 将数据改为浮点数
>>>    for column in data:
>>>        if column =='date':continue # 跳过日期
>>>        if str(data[column][1]).isdigit(): # 如果是数字
>>>            data[column] = data[column].astype('float') # 将列转为浮点数
>>>    return data

>>>def k_fold_cross_validation_split(dataset,folds=10):
>>>    seed(100)
>>>    basket_for_splitted_data = []
>>>    fold_size = int(len(dataset)/folds)
>>>    dataset_copy = list(dataset)

>>>    for i in range(folds):
>>>        basket_for_random_choosen_fold = []
>>>        while len(basket_for_random_choosen_fold) < fold_size:
>>>            random_choose_some_element = randrange(len(dataset_copy))
            >>>>basket_for_random_choosen_fold.append(dataset_copy.pop(random_choose_some_element))
>>>        basket_for_splitted_data.append(basket_for_random_choosen_fold)

>>>    return basket_for_splitted_data

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = to_float(read_csv(file_path))#
>>>    data_cases = data['cases'] # 用新冠案例数做数据
>>>    basket_for_splitted_data = k_fold_cross_validation_split(data_cases)
>>>    for i in range(len(basket_for_splitted_data)):
>>>        print(f"分组{i+1}共有数据:{len(basket_for_splitted_data[i])}")
分组1共有数据:5654
分组2共有数据:5654
分组3共有数据:5654
分组4共有数据:5654
分组5共有数据:5654
分组6共有数据:5654
分组7共有数据:5654
分组8共有数据:5654
分组9共有数据:5654
分组10共有数据:5654
  • 实现方法二:用sklearn包中的算法
>>>import os
>>>import pandas as pd
>>>from random import randrange,seed
>>>from sklearn.model_selection import KFold

>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def to_float(data):
>>>    # 将数据改为浮点数
>>>    for column in data:
>>>        if column =='date':continue # 跳过日期
>>>        if str(data[column][1]).isdigit(): # 如果是数字
>>>            data[column] = data[column].astype('float') # 将列转为浮点数
>>>    return data

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = to_float(read_csv(file_path))#
>>>    data_cases = data['cases'] # 用新冠案例数做数据
>>>    kf = KFold(n_splits=10)
>>>    basket_for_splitted_data = kf.split((data_cases))
>>>    i = 0
>>>    while True:
>>>        i+=1
>>>        try:
>>>            print(f'第{i}组数据:{next(basket_for_splitted_data)}')
>>>        except StopIteration as e:
>>>            break
第1组数据:(array([ 5655,  5656,  5657, ..., 56538, 56539, 56540]), array([   0,    1,    2, ..., 5652, 5653, 654]))
第2组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([ 5655,  5656,  5657, ..., 11306, 11307, 1308]))
第3组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([11309, 11310, 11311, ..., 16960, 16961, 6962]))
第4组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([16963, 16964, 16965, ..., 22614, 2615, 2616]))
第5组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([22617, 22618, 22619, ..., 28268, 8269, 8270]))
第6组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([28271, 28272, 28273, ..., 33922, 3923, 3924]))
第7组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([33925, 33926, 33927, ..., 39576, 9577, 9578]))
第8组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([39579, 39580, 39581, ..., 45230, 5231, 5232]))
第9组数据:(array([    0,     1,     2, ..., 56538, 56539, 56540]), array([45233, 45234, 45235, ..., 50884, 0885, 0886]))
第10组数据:(array([    0,     1,     2, ..., 50884, 50885, 50886]), array([50887, 50888, 50889, ..., 56538, 6539, 56540]))
3. 留一交叉验证(Leave-one-out Cross Validation)
  • 与K折交叉验证法类似,但是每次只留下一个样本做测试集,其它样本做训练集,如果有k个样本,则需要训k次,测试k次。
  • 相当于做了k*n次简单验证法。


  • 优点:样本利用率最高。
  • 缺点:速度慢,消耗资源。
  • 实现方法一:自己写算法
>>>import os
>>>import pandas as pd

>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def to_float(data):
>>>    # 将数据改为浮点数
>>>    for column in data:
>>>        if column =='date':continue # 跳过日期
>>>        if str(data[column][1]).isdigit(): # 如果是数字
>>>            data[column] = data[column].astype('float') # 将列转为浮点数
>>>    return data

>>>def leave_one_out_Cross_Validation(dataset):
>>>    basket_for_splitted_data = []
>>>    fold_size = int(len(dataset))
>>>    dataset_copy = list(dataset)

>>>    for i in range(fold_size):
>>>        train = dataset_copy.copy()
>>>        test = dataset_copy[i]
>>>        del train[i]
>>>        basket_for_splitted_data.append((test,train))

>>>    return basket_for_splitted_data

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = to_float(read_csv(file_path))#
>>>    data_cases = data['cases'] # 用新冠案例数做数据
>>>    basket_for_splitted_data = leave_one_out_Cross_Validation(data_cases)
>>>    print(f'数据共有{len(basket_for_splitted_data)}列')
数据共有56541列
  • 实现方法二:用sklearn包中的算法
>>> import os
>>> import pandas as pd
>>> from sklearn.model_selection import LeaveOneOut

>>> def read_csv(file):
>>>     # 获得文件中的数据
>>>     return pd.read_csv(file)

>>> def to_float(data):
>>>     # 将数据改为浮点数
>>>     for column in data:
>>>         if column =='date':continue # 跳过日期
>>>         if str(data[column][1]).isdigit(): # 如果是数字
>>>             data[column] = data[column].astype('float') # 将列转为浮点数
>>>     return data

>>> if __name__ == '__main__':
>>>     file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>     data = to_float(read_csv(file_path))#
>>>     data_cases = data['cases'] # 用新冠案例数做数据
>>>     loo = LeaveOneOut()
>>>     basket_for_splitted_data = loo.split(data_cases)
>>>     i = 0
>>>     while True:
>>>         i += 1
>>>         try:
>>>             print(f'第{i}组数据:{next(basket_for_splitted_data)}')
>>>         except StopIteration as e:
>>>             break
... ...
第56539组数据:(array([    0,     1,     2, ..., 56537, 56539, 56540]), array([56538]))
第56540组数据:(array([    0,     1,     2, ..., 56537, 56538, 56540]), array([56539]))
第56541组数据:(array([    0,     1,     2, ..., 56537, 56538, 56539]), array([56540]))
4 自助法(Bootstrapping)
  • 自助法可以理解为有放回采样或重复采样的交叉验证。
  • 比如我们有m个样本,每次在这m个样本中随机采集一个样本,放入训练集,采样完后把样本放回。这样重采集m次,我们得到m个样本组成的训练集。
  • 优点:训练集的样本总数和原数据集一样都是 m个,在数据集比较小的时候有用。
  • 缺点:这样产生的训练集的数据分布和原数据集的不一样了,会引入估计偏差。
  • 实现方法一:自己写算法
>>>import os
>>>import pandas as pd
>>>from random import randint,seed

>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def to_float(data):
>>>    # 将数据改为浮点数
>>>    for column in data:
>>>        if column =='date':continue # 跳过日期
>>>        if str(data[column][1]).isdigit(): # 如果是数字
>>>            data[column] = data[column].astype('float') # 将列转为浮点数
>>>    return data

>>>def bootstrapping(dataset,times=10):
>>>    seed(100)
>>>    basket_for_splitted_data = []
>>>    dataset_copy = list(dataset)

>>>    for i in range(times):
>>>        train = dataset_copy.copy()
>>>        test = dataset_copy[randint(0,len(dataset_copy))]
>>>        train.remove(test)
>>>        basket_for_splitted_data.append((test,train))
>>>    return basket_for_splitted_data

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = to_float(read_csv(file_path))#
>>>    data_cases = data['cases'] # 用新冠案例数做数据
>>>    basket_for_splitted_data = bootstrapping(data_cases)
>>>    for i in range(len(basket_for_splitted_data)):
>>>        print(f'第{i+1}组数据:{basket_for_splitted_data[i][0]},{basket_for_splitted_data[i][1][:5]}...')
第1组数据:3.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第2组数据:8.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第3组数据:3067.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第4组数据:132.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第5组数据:35.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第6组数据:2.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第7组数据:78.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第8组数据:32.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第9组数据:1.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
第10组数据:5.0,[1.0, 1.0, 1.0, 1.0, 1.0]...
  • 实现方法二:用pandas包中的算法
>>>import os
>>>import pandas as pd

>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def to_float(data):
>>>    # 将数据改为浮点数
>>>    for column in data:
>>>        if column =='date':continue # 跳过日期
>>>        if str(data[column][1]).isdigit(): # 如果是数字
>>>            data[column] = data[column].astype('float') # 将列转为浮点数
>>>    return data

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = to_float(read_csv(file_path))#
>>>    data_cases = data['cases'] # 用新冠案例数做数据
>>>    train = data_cases.sample(n=10,replace=True)

>>>    for i in range(10):
>>>        test= data_cases.loc[data_cases.index.difference([train.index[i]])].copy()
>>>        print(f'第{i+1}组数据:{train.values[i]},{test.values}...')
第1组数据:9.0,[ 1.  1.  1. ... 56.  4.  4.]...
第2组数据:11.0,[ 1.  1.  1. ... 56.  4.  4.]...
第3组数据:18.0,[ 1.  1.  1. ... 56.  4.  4.]...
第4组数据:1.0,[ 1.  1.  1. ... 56.  4.  4.]...
第5组数据:0.0,[ 1.  1.  1. ... 56.  4.  4.]...
第6组数据:3.0,[ 1.  1.  1. ... 56.  4.  4.]...
第7组数据:3.0,[ 1.  1.  1. ... 56.  4.  4.]...
第8组数据:27.0,[ 1.  1.  1. ... 56.  4.  4.]...
第9组数据:1.0,[ 1.  1.  1. ... 56.  4.  4.]...
第10组数据:2.0,[ 1.  1.  1. ... 56.  4.  4.]...
5 分层交叉验证(StratifiedKFold)
  • 对测试集按类型比例分层,对每层进行无放回抽样。


>>>import os
>>>import pandas as pd
>>>import numpy as np
>>>from sklearn.model_selection import StratifiedKFold

>>>def to_float(func):
>>>    def wrapper(*args,**kwargs):
>>>        # 将数据改为浮点数
>>>        data = func(*args,**kwargs)
>>>        for column in data:
>>>            if column == 'date': continue  # 跳过日期
>>>            if str(data[column][1]).isdigit():  # 如果是数字
>>>                data[column] = data[column].astype('float')  # 将列转为浮点数
>>>        return data
>>>    return wrapper

>>>@to_float
>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def startfiledkfold(dataset,k_set=10):
>>>    skf = StratifiedKFold(n_splits=k_set)
>>>    value = np.array(dataset.values)
>>>    target = np.ones([int(dataset.shape[0]),1],int)
>>>    return skf.split(value,target)

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = read_csv(file_path)#
>>>    data_cases = data['cases'] # 用新冠案例数做数据

>>>    for train,test in startfiledkfold(data_cases):
>>>        print(f"train:{train},test:{test}")
train:[ 5655  5656  5657 ... 56538 56539 56540],test:[   0    1    2 ... 5652 5653 5654]
train:[    0     1     2 ... 56538 56539 56540],test:[ 5655  5656  5657 ... 11306 11307 11308]
train:[    0     1     2 ... 56538 56539 56540],test:[11309 11310 11311 ... 16960 16961 16962]
train:[    0     1     2 ... 56538 56539 56540],test:[16963 16964 16965 ... 22614 22615 22616]
train:[    0     1     2 ... 56538 56539 56540],test:[22617 22618 22619 ... 28268 28269 28270]
train:[    0     1     2 ... 56538 56539 56540],test:[28271 28272 28273 ... 33922 33923 33924]
train:[    0     1     2 ... 56538 56539 56540],test:[33925 33926 33927 ... 39576 39577 39578]
train:[    0     1     2 ... 56538 56539 56540],test:[39579 39580 39581 ... 45230 45231 45232]
train:[    0     1     2 ... 56538 56539 56540],test:[45233 45234 45235 ... 50884 50885 50886]
train:[    0     1     2 ... 50884 50885 50886],test:[50887 50888 50889 ... 56538 56539 56540]
6 留P交叉验证(LeavePOut)
  • 与留一交叉验证类似,但是每次留下p个样本做测试集。
>>>import os
>>>import pandas as pd
>>>import numpy as np
>>>from sklearn.model_selection import LeavePOut

>>>def to_float(func):
>>>    def wrapper(*args,**kwargs):
>>>        # 将数据改为浮点数
>>>        data = func(*args,**kwargs)
>>>        for column in data:
>>>            if column == 'date': continue  # 跳过日期
>>>            if str(data[column][1]).isdigit():  # 如果是数字
>>>                data[column] = data[column].astype('float')  # 将列转为浮点数
>>>        return data
>>>    return wrapper

>>>@to_float
>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def leave_p_out(dataset,p=10):
>>>    # 留P划分
>>>    lpo = LeavePOut(p=p)
>>>    return lpo.split(dataset)

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = read_csv(file_path)#
>>>    data_cases = data['cases'] # 用新冠案例数做数据

>>>    for train,test in leave_p_out(data_cases):
>>>        print(f"train:{train},test:{test}")
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35299]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35300]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35301]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35302]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35303]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35304]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35305]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35306]
train:[    8    10    11 ... 61968 61969 61970],test:[    0     1     2     3     4     5     6     7     9 35307]
... ...
7 分组交叉验
  • 分组交叉验证是为了进一步测试模型的泛化能力,留出一组特定的不属于测试集和训练集的数据。

1) GroupKFold

  • k折交叉验证的变体,它确保同一个组在测试和训练集中都不被表示。
  • GroupKFold和分层交叉验证比较像,不过测试集是按照一定分组进行打乱的,即先分堆,然后把这些堆打乱,每个堆里的顺序还是固定不变的。

2) LeaveOneGroupOut

  • 根据第三方提供的整数组的数组提供的样本。
  • 这个组信息可以用来编码任意域特定的预定义交叉验证折叠。

3) LeavePGroupsOut

  • 类似于 LeaveOneGroupOut ,只是一个是单组,一个是多组。

4) GroupShuffleSplit

  • 是 ShuffleSplit 和 LeavePGroupsOut 的组合,它生成一个随机划分分区的序列,其中为每个分组提供了一组子集。
  • 有放回抽样。
>>>import os,random
>>>import pandas as pd
>>>import numpy as np
>>>from sklearn.model_selection import GroupKFold,LeaveOneGroupOut,LeavePGroupsOut,GroupShuffleSplit

>>>def to_float(func):
>>>    def wrapper(*args,**kwargs):
>>>        # 将数据改为浮点数
>>>        data = func(*args,**kwargs)
>>>        for column in data:
>>>            if column == 'date': continue  # 跳过日期
>>>            if str(data[column][1]).isdigit():  # 如果是数字
>>>                data[column] = data[column].astype('float')  # 将列转为浮点数
>>>        return data
>>>    return wrapper

>>>@to_float
>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def group_k_fold(dataset,groups,p=2):
>>>    gkf = GroupKFold(n_splits=p)
>>>    return gkf.split(dataset,groups=groups)

>>>def leave_one_group_out(dataset,groups):
>>>    logo = LeaveOneGroupOut()
>>>    return logo.split(dataset,groups=groups)

>>>def leave_p_group_out(dateset,groups,g=2):
>>>    lpgo = LeavePGroupsOut(n_groups=g)
>>>    return lpgo.split(dateset,groups=groups)

>>>def group_shuffle_split(dataset,groups,n=2):
>>>    gss = GroupShuffleSplit(n_splits=n)
>>>    return gss.split(dataset,groups=groups)

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = read_csv(file_path)#
>>>    data_cases = data['cases'] # 用新冠案例数做数据
>>>    groups = np.array([random.randint(1,5) for x in range(len(data_cases))])

>>>    print("GroupKFold:")
>>>    for train,test in group_k_fold(data_cases,groups):
>>>        print(f"train:{train},test:{test}")

>>>    print("\nLeaveOneGroupOut:")
>>>    for train,test in leave_one_group_out(data_cases,groups):
>>>        print(f"train:{train},test:{test}")

>>>    print("\nLeavePGroupOut:")
>>>    for train, test in leave_p_group_out(data_cases,groups):
>>>       print(f"train:{train},test:{test}")

>>>    print("\nGroupShuffleSplit:")
>>>    for train, test in group_shuffle_split(data_cases,groups):
>>>        print(f"train:{train},test:{test}")
GroupKFold:
train:[    0     2     5 ... 61962 61965 61967],test:[    1     3     4 ... 61968 61969 61970]
train:[    1     3     4 ... 61968 61969 61970],test:[    0     2     5 ... 61962 61965 61967]

LeaveOneGroupOut:
train:[    0     2     4 ... 61966 61967 61969],test:[    1     3    11 ... 61964 61968 61970]
train:[    0     1     2 ... 61967 61968 61970],test:[    4    10    22 ... 61963 61966 61969]
train:[    0     1     2 ... 61968 61969 61970],test:[    5     6    14 ... 61962 61965 61967]
train:[    0     1     2 ... 61968 61969 61970],test:[    9    13    18 ... 61943 61950 61956]
train:[    1     3     4 ... 61968 61969 61970],test:[    0     2     7 ... 61939 61948 61951]

LeavePGroupOut:
train:[    0     2     5 ... 61962 61965 61967],test:[    1     3     4 ... 61968 61969 61970]
train:[    0     2     4 ... 61963 61966 61969],test:[    1     3     5 ... 61967 61968 61970]
train:[    0     2     4 ... 61966 61967 61969],test:[    1     3     9 ... 61964 61968 61970]
train:[    4     5     6 ... 61966 61967 61969],test:[    0     1     2 ... 61964 61968 61970]
train:[    0     1     2 ... 61964 61968 61970],test:[    4     5     6 ... 61966 61967 61969]
train:[    0     1     2 ... 61967 61968 61970],test:[    4     9    10 ... 61963 61966 61969]
train:[    1     3     5 ... 61967 61968 61970],test:[    0     2     4 ... 61963 61966 61969]
train:[    0     1     2 ... 61968 61969 61970],test:[    5     6     9 ... 61962 61965 61967]
train:[    1     3     4 ... 61968 61969 61970],test:[    0     2     5 ... 61962 61965 61967]
train:[    1     3     4 ... 61968 61969 61970],test:[    0     2     7 ... 61950 61951 61956]

GroupShuffleSplit:
train:[    0     1     2 ... 61967 61968 61970],test:[    4    10    22 ... 61963 61966 61969]
train:[    0     1     2 ... 61968 61969 61970],test:[    9    13    18 ... 61943 61950 61956]
8 时间序列分割(TimeSeriesSplit)
  • 时间序列分割是K折交叉的变体, 首先返回 k 折作为训练数据集,并且 (k+1) 折作为测试数据集。
  • 另外,它将所有的剩余数据添加到第一个训练分区用来训练模型, 这个类可以用来交叉验证以固定时间间隔察到的时间序列数据样本。
>>>import os
>>>import pandas as pd
>>>from sklearn.model_selection import TimeSeriesSplit

>>>def to_float(func):
>>>    def wrapper(*args,**kwargs):
>>>        # 将数据改为浮点数
>>>        data = func(*args,**kwargs)
>>>        for column in data:
>>>            if column == 'date': continue  # 跳过日期
>>>            if str(data[column][1]).isdigit():  # 如果是数字
>>>                data[column] = data[column].astype('float')  # 将列转为浮点数
>>>        return data
>>>    return wrapper

>>>@to_float
>>>def read_csv(file):
>>>    # 获得文件中的数据
>>>    return pd.read_csv(file)

>>>def time_series_split(dataset,n=10):
>>>    tscv = TimeSeriesSplit(n_splits=n)
>>>    return tscv.split(dataset)

>>>if __name__ == '__main__':
>>>    file_path = os.path.join('D:\\','dataset','us-counties.csv')
>>>    data = read_csv(file_path)#
>>>    data_cases = data['cases'] # 用新冠案例数做数据

>>>    for train,test in time_series_split(data_cases):
>>>        print(f"train:{train},test:{test}")
train:[   0    1    2 ... 5638 5639 5640],test:[ 5641  5642  5643 ... 11271 11272 11273]
train:[    0     1     2 ... 11271 11272 11273],test:[11274 11275 11276 ... 16904 16905 16906]
train:[    0     1     2 ... 16904 16905 16906],test:[16907 16908 16909 ... 22537 22538 22539]
train:[    0     1     2 ... 22537 22538 22539],test:[22540 22541 22542 ... 28170 28171 28172]
train:[    0     1     2 ... 28170 28171 28172],test:[28173 28174 28175 ... 33803 33804 33805]
train:[    0     1     2 ... 33803 33804 33805],test:[33806 33807 33808 ... 39436 39437 39438]
train:[    0     1     2 ... 39436 39437 39438],test:[39439 39440 39441 ... 45069 45070 45071]
train:[    0     1     2 ... 45069 45070 45071],test:[45072 45073 45074 ... 50702 50703 50704]
train:[    0     1     2 ... 50702 50703 50704],test:[50705 50706 50707 ... 56335 56336 56337]
train:[    0     1     2 ... 56335 56336 56337],test:[56338 56339 56340 ... 61968 61969 61970]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341