机器学习中首要环节就是数据集的处理,其中数据集的处理从个人理解(如有错误敬请谅解)的角度来说包括两个方面:数据集划分和数据清理。其中数据集划分是指训练集、验证集和测试集的数据类别划分;数据清理是指数据的清洗、删除等等方面。这两天主要学的就是如何划分数据集。
一、数据集划分(交叉验证)
划分数据集的目的主要是为了后期训练模型参数的准确性以及测试结果的准确性,避免下列问题:
1.训练集和测试集分布不均匀,主要是指实际项目的数据集中如分类任务中1000个样本,其中A类样本和B类样本均为500个,但是在划分训练集和测试集的时候,训练集选了650个A类和50个B类样本,结果导致训练出来的模型偏向于A类样本,在测试或者实际预测的时候导致B类数据分类不正确;
2.训练集和测试集分布不均匀,主要是指实际项目的数据集中如分类任务中1000个样本,其中A类样本950个和B类样本为50个.那么在实际划分训练集和测试集的时候可能出现的极端情况就是选取了650个A类样本和50个B类样本,测试集中B类样本数为0,上述情况可导致模型测试不真实,与实际不符合。
二、基于sklearn的数据集划分(交叉验证)
交叉验证是指数据集按照一定的规律进行划分,包括样本数据的重复使用,即把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。在此基础上可以得到多组不同的训练集和测试集,当前训练集中的某样本在下次可能成为测试集中的样本,即所谓“交叉”。
其中博主主要使用的是python编程语言,所以应用测试都是基于sklearn库哈。当前使用的sklearn库是0.20.0
1.KFold(K折):将所有的样例划分为 个组,称为折叠 (fold) (如果 , 这等价于 Leave One Out(留一) 策略),都具有相同的大小(如果可能)。预测函数学习时使用 个折叠中的数据,最后一个剩下的折叠会用于测试。
2.RepeatedKFold(RK折)
,重复 K-Fold n 次。当需要运行时可以使用它 KFold
n 次,在每次重复中产生不同的分割。
3.LeaveOneOut
(LOO) 是一个简单的交叉验证。每个学习集都是通过除了一个样本以外的所有样本创建的,测试集是被留下的样本。
4.LeavePOut
与 LeaveOneOut
非常相似,因为它通过从整个集合中删除P个样本来创建所有可能的训练/测试集。
5.ShuffleSplit
迭代器 将会生成一个用户给定数量的独立的训练/测试数据划分。样例首先被打散然后划分为一对训练测试集合。
其中由于标签的种类分布不均匀,这时不能采用上述的方法。此时应采用分层抽样方法,个人理解为就是基于标签的数据层进行划分,如数据集中有A类样本80%,B类样本20%,划分数据集的时候不管采用哪种方法应遵循训练集和测试集的样本标签比例保持为80%和20%。
6.StratifiedKFold
是 k-fold 的变种,会返回 stratified(分层) 的折叠:每个小集合中, 各个类别的样例比例大致和完整数据集中相同。
7.StratifiedShuffleSplit 。此交叉验证对象是StratifiedKFold和ShuffleSplit的合并,返回分层的随机折叠。折叠是通过保留每个类别的样品百分比来进行的。
如果潜在的生成过程产生依赖样本的 groups ,那么 i.i.d. 假设将会被打破。这样的数据分组是特定于域的。一个例子是从多个患者收集医学数据,从每个患者身上采集多个样本。而这样的数据很可能取决于个人群体。 在我们的例子中,每个样本的患者 ID 将是其 group identifier (组标识符)。
8.GroupKFold
是 k-fold 的变体,它确保同一个 group 在测试和训练集中都不被表示。
9.LeaveOneGroupOut
是一个交叉验证方案,它根据第三方提供的 array of integer groups (整数组的数组)来提供样本。这个组信息可以用来编码任意域特定的预定义交叉验证折叠。每个训练集都是由除特定组别以外的所有样本构成的。
10.LeavePGroupsOut
类似于 LeaveOneGroupOut
,但为每个训练/测试集删除与 组有关的样本。
11.GroupShuffleSplit
迭代器是 ShuffleSplit
和 LeavePGroupsOut
的组合,它生成一个随机划分分区的序列,其中为每个分组提供了一个组子集。
时间序列数据的特点是时间 (autocorrelation(自相关性)) 附近的观测之间的相关性。 然而,传统的交叉验证技术,例如 KFold
和 ShuffleSplit
假设样本是独立的且分布相同的,并且在时间序列数据上会导致训练和测试实例之间不合理的相关性(产生广义误差的估计较差)。 因此,对 “future(未来)” 观测的时间序列数据模型的评估至少与用于训练模型的观测模型非常重要。为了达到这个目的,一个解决方案是由 TimeSeriesSplit
提供的。
12.
TimeSeriesSplit
是 k-fold 的一个变体,它首先返回 折作为训练数据集,并且( k+1) 折作为测试数据集。 请注意,与标准的交叉验证方法不同,连续的训练集是超越前者的超集。 另外,它将所有的剩余数据添加到第一个训练分区,它总是用来训练模型。这个类可以用来交叉验证以固定时间间隔观察到的时间序列数据样本。
下面是实际的sklearn调用代码。
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 5 09:10:35 2019@author: kofzh
"""import numpy as np
from sklearn.model_selection import StratifiedShuffleSplit,ShuffleSplit,LeavePOut,LeaveOneOut,StratifiedKFold,KFold,RepeatedKFoldX=np.array([[1,2,3,4],[11,12,13,14],[21,22,23,24],[31,32,33,34],[41,42,43,44],[51,52,53,54],[61,62,63,64],[71,72,73,74]
])y=np.array([1,1,0,0,1,1,0,0])'''适合样本便签分类均匀的数据集'''
#K折
kf =KFold(n_splits=4,random_state=1)
print("KFold")
for train,test in kf.split(X,y):print('Train:%s | Test:%s '%(train,test),'\n')#print(X[train],X[train])#RK折,其中n_splits为数据集分成的份数,n_repeats为Test数据集中单一数据出现的次数,默认为10
random_state= 12883823
rkf= RepeatedKFold(n_splits=4,n_repeats=4,random_state=random_state)
print("RKFold")
for train,test in rkf.split(X,y):print('Train:%s | Test:%s '%(train,test),'\n')#print(X[train],X[train])#loo,测试集样本留一,其余均为训练集。感觉和K折的n_splits=样本数一样
loo = LeaveOneOut()
print("loo")
for train,test in loo.split(X,y):print('Train:%s | Test:%s '%(train,test),'\n')#lpo,删除p个样本,p>1时样本会重叠
lpo = LeavePOut(p=2)
print("lpo")
for train,test in lpo.split(X,y):print('Train:%s | Test:%s '%(train,test),'\n')#随机训练集和测试集划分
ss= ShuffleSplit(n_splits=4,test_size=0.25,random_state=0)
print("ss")
for train,test in ss.split(X,y):print('Train:%s | Test:%s '%(train,test),'\n')
'''''''''''''''''''''''''''''''''适合样本便签分类不均匀的数据集'''
#sK折,K折的变种,主要不同为数据集的标签分布与训练集的各个标签类别基本一致
x2 = np.ones(10)
y2 = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
sf = StratifiedKFold(n_splits =3,random_state=0)
print("St")
for train,test in sf.split(x2,y2):print('Train:%s | Test:%s '%(train,test),'\n')#SSS折,SS折的变种,主要不同为数据集的标签分布与训练集的各个标签类别基本一致
sss = StratifiedShuffleSplit(n_splits =3,test_size=2)
print("Sss")
for train,test in sss.split(x2,y2):print('Train:%s | Test:%s '%(train,test),'\n')
'''''''''''''''''''''''''''''''''适合样本以组为分类的数据集'''
from sklearn.model_selection import GroupKFold,LeaveOneGroupOut,LeavePGroupsOut,GroupShuffleSplit
x3 = [0.1, 0.2, 2.2, 2.4, 2.3, 4.55, 5.8, 8.8, 9, 10]
y3 = ["a", "b", "b", "b", "c", "c", "c", "d", "d", "d"]
groups = [1, 1, 1, 2, 2, 2, 3, 3, 3, 3]#gk折,k折的变种,主要不同为数据集的标签分布与组类别有关
gkf = GroupKFold(n_splits =3 )
print("gkf")
for train,test in gkf.split(x3,y3,groups= groups):print('Train:%s | Test:%s '%(train,test),'\n')#gloo折,loo折的变种,主要不同为数据集的标签分布与组类别有关
gLOO = LeaveOneGroupOut( )
print("gLOO")
for train,test in gLOO.split(x3,y3,groups= groups):print('Train:%s | Test:%s '%(train,test),'\n')#glPo折,lPo折的变种,主要不同为数据集的标签分布与组类别有关
gLPO = LeavePGroupsOut(n_groups = 2)
print("gLPO")
for train,test in gLPO.split(x3,y3,groups= groups):print('Train:%s | Test:%s '%(train,test),'\n')#gss折,LeavePGroupsOut和Shuffle的组合
x4 = [0.1, 0.2, 2.2, 2.4, 2.3, 4.55, 5.8, 0.001]
y4 = ["a", "b", "b", "b", "c", "c", "c", "a"]
groups = [1, 1, 2, 2, 3, 3, 4, 4]
gss = GroupShuffleSplit(n_splits=4, test_size=0.2, random_state=0)
print("gss")
for train, test in gss.split(x4, y4, groups=groups):print("%s %s" % (train, test))
'''''''''''''''''''''''''''''''''适合样本基于时间序列的数据集'''
from sklearn.model_selection import TimeSeriesSplit
x5 = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]])
y5 = np.array([1, 2, 3, 4, 5, 6])tss = TimeSeriesSplit(n_splits=3)
print(tss)
TimeSeriesSplit(max_train_size=None, n_splits=3)
print("tss")
for train, test in tss.split(x5):print("%s %s" % (train, test))
其实总结可知:上述方法主要分为5类,K折和RK折、LOO折、LPO折、SS折。其余均是基于样本数据标签的分布或者其他原因的变种方法。
三、基于时间序列的数据集划分
从上述基于时间序列的数据集划分的时候,发现只能从过去N个时刻(N可自行设置)预测未来1个时刻的数据,不能满足我们想要的过去N个时刻预测未来M个时刻的数据,当然了大佬可以自行写代码完成,但是对于我等小弟最好是找个现成成熟的代码来完成。由于涉及到相应的商业机密,不能将源代码放出来,不过可以将相应的参考链接给出来,可以自行优化即可。
https://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python/
四、总结:
从数学角度来说,交叉验证以及数据清洗都是更准确的生成放入模型进行训练的X和Y罢了。。。
参考文献:
1.https://sklearn.apachecn.org/docs/0.21.3/30.html
2.https://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python/
3.https://blog.csdn.net/weixin_39306118/article/details/89527635