Scikit-learn中的随机状态在数据集分割中的应用

57

有人能告诉我为什么我们在分割训练集和测试集时将随机种子设为零吗?

X_train, X_test, y_train, y_test = \
    train_test_split(X, y, test_size=0.30, random_state=0)

我曾经看到过像这样的情况,其中随机状态被设置为1!

X_train, X_test, y_train, y_test = \
    train_test_split(X, y, test_size=0.30, random_state=1)
这个随机状态在交叉验证中会有什么后果?

1
@Scott Hunter,这个来自于sklearn.cross_validation。但是当随机状态为零和一时,对训练和测试分割有什么影响呢? - Shelly
1
train_test_split 的文档说什么? - Scott Hunter
1
@Scott Hunter http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html - Shelly
3
确保每次运行脚本时,你都可以获得相同的分割。请了解一下伪随机数生成器。 (例如数字32525352与0或1具有相同的效果;它只是一个映射到某些内部状态的常量)。如果不这样做,则会基于时间进行种子处理,在大多数运行中会产生不同的结果。 - sascha
2
可能是Scikit learn中的随机状态(伪随机数)的重复问题。 - Ricky Geng
显示剩余3条评论
10个回答

68

无论random_state是0还是1或任何其他整数都没有关系。重要的是,如果您想验证代码的多次运行处理结果,它应该设置为相同的值。顺便说一下,我在scikit的许多官方示例以及其他地方看到过random_state=42的使用。

如其名称所示,random_state用于初始化内部随机数生成器,该生成器将决定将数据分成训练和测试索引。在文档中,它指出:

如果random_state为None或np.random,则返回一个随机初始化的RandomState对象。

如果random_state是整数,则用它来生成一个新的RandomState对象。

如果random_state是一个RandomState对象,则通过它传递。

这是为了在多次运行代码时检查和验证数据。设置random_state为固定值将确保每次运行代码时生成相同序列的随机数。除非过程中存在其他随机性,否则产生的结果将始终相同。这有助于验证输出。


1
@mathlover 我也观察到了我的输出同样具有随机性。我所发现的是,当你为"random_state"设置一些值时,像我这种情况下的"mean_absolute_error"输出就会被固定(我的意思是每次运行它都会输出相同的结果)。 - 0xPrateek
当值本身并不重要时,为什么不只使用布尔值? - Ben
@Ben 因为在 numpy 中,random_state 参数提供的值将作为伪随机数生成器的种子。当未设置时,大多数实现将使用当前系统时间作为种子。因此,仅将其设置为布尔值是不合适的。 - Vivek Kumar
1
随机种子通常被设置为42,因为来自《银河系漫游指南》的“生命、宇宙和万物的终极问题的答案是42”。但我认为大多数人都知道这一点。如果您感兴趣,请参见... https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life,_the_Universe,_and_Everything_(42) - Joey
这个东西的用途和K折交叉验证一样,不同之处在于你不需要将数据分成10份(fold=10),然后再将它们分成训练数据和测试数据。 - Anggia Bagaskara
显示剩余4条评论

18

当random_state设置为一个整数时,train_test_split将为每次执行返回相同的结果。

当random_state设置为None时,train_test_split将为每次执行返回不同的结果。

请参考以下示例:

from sklearn.model_selection import train_test_split

X_data = range(10)
y_data = range(10)

for i in range(5):
    X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size = 0.3,random_state = 0) # zero or any other integer
    print(y_test)

print("*"*30)

for i in range(5): 
    X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size = 0.3,random_state = None)
    print(y_test)

输出:

[2, 8, 4]

[2, 8, 4]

[2, 8, 4]

[2, 8, 4]

[2, 8, 4]


[4, 7, 6]

[4, 3, 7]

[8, 1, 4]

[9, 5, 8]

[6, 4, 5]


15

如果在代码中不提到random_state,那么每次执行代码时都会生成一个新的随机值,因此每次训练集和测试集将拥有不同的值。

但是,如果你每次都使用特定的random_state值(如random_state = 1或其他任何值),结果将始终相同,即训练集和测试集中的数值相同。


8
随机状态(random_state)会随机选取数据,但有一个变化。这个变化是对于特定的随机状态值,数据的顺序将保持不变。需要理解的是,它不是布尔值。如果你传递从0开始到任何整数的值作为随机状态,那么它将成为该状态的永久顺序。例如:在random_state=0的情况下,你得到的顺序将保持不变。之后,如果你执行random_state=5,然后再回到random_state=0,你会得到相同的顺序。而且所有整数的0都会保持一致。但是random_state=None每次都是随机分割的。如果仍有疑问,请参考this

5

如果你的代码中没有指定random_state,那么每次运行代码时都会生成一个新的随机值,因此每次训练和测试数据集将会有不同的值。

然而,如果指定了一个固定的值,例如random_state = 0或1或42,那么无论你执行代码的次数如何,结果都将是相同的,即训练和测试数据集中的数值相同。


5

默认情况下random_state为None,这意味着每次运行程序时,由于训练集和测试集之间的分割会有所不同,您将获得不同的输出。

当random_state = 任何整数值时,每次运行程序时,由于训练集和测试集之间的分割不会变化,您将获得相同的输出。


3

random_state是一个整数值,它表示选择训练集和测试集的随机组合。当您将test_size设置为1/4时,会生成一组训练集和测试集的排列组合,并且每个组合都有一个状态。

假设你有一个数据集 ---> [1,2,3,4]

Train   |  Test   | State
[1,2,3]    [4]      **0**
[1,3,4]    [2]      **1**
[4,2,3]    [1]      **2**
[2,4,1]    [3]      **3**

我们需要它是因为在模型参数调整时,同一状态会一遍又一遍地被考虑。这样可以保证准确性不受任何干扰。
但是在随机森林模型中也有类似的情况,但与变量有关的方式不同。

2
我们使用random_state参数来保证每个epoch后训练数据集的初始洗牌可重现性。"最初的回答"

1

对于我们的模型进行多次执行,随机状态确保训练和测试数据集的数据值相同。它固定了train_test_split的数据顺序。


怎样确保相同的分割呢?我的意思是,你能解释一下算法吗? - RafiO

0
假设我们的数据集有一个特征和10个数据点。X=[0,1,2,3,4,5,6,7,8,9],如果指定0.3(30%为测试集)作为测试数据百分比,则会有10C3=120种不同的数据组合。[请参考链接中的图片进行表格说明:https://istack.dev59.com/FZm4a.webp]
根据指定的随机数,系统将选择随机状态并分配训练和测试数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接