我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文继续描述机器学习里面的sklearn的内容,拿到合适的样本数据集之后,有一个可选的操作就是对样本数据集进行切割,从而分割出用于训练的数据集,和用于验证的数据集。这就引出了本文的数据集切割函数:train_test_split()

苏南大叔:sklearn,如何理解数据集切割函数train_test_split()? - train-test-split
sklearn,如何理解数据集切割函数train_test_split()?(图5-1)

大家好,这里是苏南大叔的“平行空间笔记本”博客,记录苏南大叔和计算机代码的故事。本文将对train_test_split()函数的用法,进行简要的分析。本文测试环境:win10python@3.11.0pip@23.0.1scikit-learn@1.2.2

函数原型

函数定义在<python>\Lib\site-packages\sklearn\model_selection\_split.py文件中,函数定义如下:

def train_test_split(
    *arrays,
    test_size=None,
    train_size=None,
    random_state=None,
    shuffle=True,
    stratify=None,
):

苏南大叔:sklearn,如何理解数据集切割函数train_test_split()? - train_test_split函数定义
sklearn,如何理解数据集切割函数train_test_split()?(图5-2)

数据输入Xy

train_test_split()函数的操作对象主要是数据集数据Xy,这个数据集可以是pandasDataFrame类型,也可以是numpyndarray类型。

根据函数定义里面的说明,允许的类型有很多:
Allowed inputs are lists, numpy arrays, scipy-sparse matrices or pandas dataframes.

具体可以参考:

现在假设通过下面的方式,获得了X(data)以及y(target)数据。

import pandas as pd
data = pd.read_csv("iris.csv",skiprows=1,names=["a","b","c","d","label"])
X = data.iloc[:,:-1]
y = data.iloc[:,-1:]

_pandas.read_csv()拿到的是个dataframe对象,使用.iloc[]进行成员数据定位。

苏南大叔:sklearn,如何理解数据集切割函数train_test_split()? - 获得数据
sklearn,如何理解数据集切割函数train_test_split()?(图5-3)

其实这一步也算个split,对吧?这一步是纵向来一刀,把数据一分为二。下一步train_test_split()是横向再来一刀,从二块数据变成四块数据。

数据输出traintest

这里输出四个值的原因,在于输入了两个值X(data)以及y(target),输出是输入的两倍。

train_test_split()函数的返回值数量,非常罕见,一共有四个返回值。分别是:

分类归属名称
训练集dataX_train
训练集targety_train
测试集dataX_test
测试集targety_test

如果还是以鸢尾花数据为例的话,切分的结果的范例,如下图所示:

苏南大叔:sklearn,如何理解数据集切割函数train_test_split()? - 数据切分
sklearn,如何理解数据集切割函数train_test_split()?(图5-4)

关于list类型可以进行的操作,参考文章:

参数控制

根据函数原型定义可以知道:一共下面几个参数可以作调整。

训练集和测试集

test_size : float or int, default=None

If float, should be between 0.0 and 1.0 and represent the proportion of the dataset to include in the test split. If int, represents the absolute number of test samples. If None, the value is set to the complement of the train size. If ``train_size`` is also None, it will be set to 0.25. 

train_size : float or int, default=None

If float, should be between 0.0 and 1.0 and represent the proportion of the dataset to include in the train split. If int, represents the absolute number of train samples. If None, the value is automatically set to the complement of the test size.
参数默认值用途数据类型
test_sizeNone测试集比例或数量float/int
train_sizeNone训练集比例或数量float/int

拿到的数据集将被分为测试集和训练集,设置其中一个就可以了。

  • 传递的是小于1的类似0.3小数点数据的话,就理解为比例【推荐】。
  • 如果传递的是大于1的类似5这样的整形的话,就理解为确切的数量(很难判断是否越界)。
  • 两者都不做设置的话,则测试集的比例是0.25,训练集比例是0.75
  • 以测试集test为主要数据分割标准。
  • 理论上来说,test_sizetrain_size相加,应该是全部数据。但事实上,两者相加也可以只是一部分数据。

控制随机状态

random_state : int, RandomState instance or None, default=None

Controls the shuffling applied to the data before applying the split. Pass an int for reproducible output across multiple function calls. See :term:`Glossary <random_state>`. 

shuffle : bool, default=True

Whether or not to shuffle the data before splitting. If shuffle=False then stratify must be None. 

stratify : array-like, default=None

If not None, data is split in a stratified fashion, using this as the class labels. Read more in the :ref:`User Guide <stratification>`.

这几个参数就控制了数据分割的随机状态,客观上也控制了最终的准确率是否一成不变。

参数默认值用途数据类型
random_stateNone数据混洗随机数种子int
shuffleTrue分割前是否洗牌bool
stratifyNone分层决定谁是目标标签array-like
  • random_state【随便写个数字】,自身不是随机的,是控制逻辑中的随机数的种子,不同的随机数种子划分的结果不同。实际操作中,这个random_state就是程序员随手写的一个固定的整数值,完全无感。设置的唯一意义在于:控制后续输出的可复制性一致性。(获得一个可控的随机结果,自己体会)
  • shuffle洗牌【默认洗牌】,默认要打乱数据的顺序,进行洗牌。如果设为不洗牌的话(那就不能设置stratify),每次拿到的训练集和测试集合都会是一致的,所以最终的准确率测试也会保持一致。
  • stratify保持比例【不建议设置】,是为了分割前后数据的分布保持一致。设置stratify的时候,就不能洗牌(shuffle=True)。stratify=某个集合,训练集中的数据比例会和测试集中的对应比例都会和“某个集合”一致。在苏南大叔实际的测试中,这“某个集合”只能等于y,否则将各种不符合预期。

苏南大叔:sklearn,如何理解数据集切割函数train_test_split()? - 参数设置解析
sklearn,如何理解数据集切割函数train_test_split()?(图5-5)

苏南大叔对这个参数是这么理解的:

  • 根据shuffle决定是否洗牌。
  • 根据stratify决定是否按分类比例洗牌(比如每个花色各拿五张)。
  • 根据random_state决定是否洗出固定位置上的牌(比如每次都弹出第一张第三张第五张牌)。

类似名词统计

把数据集里面的数据,竖向来一刀,就产生了下面的几组不同名字,但是相同意义的变量名称:

机器学习代码里train_test_split()函数原型里鸢尾花数据集读取结果里
Xfeaturesdata
yresultlabel

再通过train_test_split()横向来一刀,就再次产生了_train(训练集)和_test(测试集)的概念区别。

参考文章

总结

使用train_test_split()函数的主要场景,就是需要对数据集进行切割成训练集和测试集的情况。也就是模型的初始训练阶段。那么,如果时机成熟的情况下,并不需要对数据进行验证测试呢?所有拿到的数据集都用来模型训练呢?就并不需要train_test_split()函数了。

您是否同意苏南大叔的观点呢?欢迎留言。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python    sklearn