Scikit 学习中的随机状态(伪随机数)

Random state (Pseudo-random number) in Scikit learn

我想在scikit learn中实现一个机器学习算法,但是我不明白这个参数random_state是做什么的?我为什么要使用它?

我也搞不懂什么是伪随机数。

train_test_split 将数组或矩阵拆分为随机训练和测试子集。这意味着每次你 运行 它而不指定 random_state,你都会得到不同的结果,这是预期的行为。例如:

运行 1:

>>> a, b = np.arange(10).reshape((5, 2)), range(5)
>>> train_test_split(a, b)
[array([[6, 7],
        [8, 9],
        [4, 5]]),
 array([[2, 3],
        [0, 1]]), [3, 4, 2], [1, 0]]

运行 2

>>> train_test_split(a, b)
[array([[8, 9],
        [4, 5],
        [0, 1]]),
 array([[6, 7],
        [2, 3]]), [4, 2, 0], [3, 1]]

变了。另一方面,如果您使用 random_state=some_number,那么您可以保证 运行 1 的输出将等于 [ 的输出=37=] 2,即您的拆分将始终相同。 实际 random_state 数字是 42、0、21 是什么并不重要,重要的是每次使用 42 时,第一次拆分时总是会得到相同的输出。 如果您想要可重现的结果(例如在文档中),这将很有用,这样每个人在 运行 示例时都可以始终看到相同的数字。 在实践中我会说,你应该在测试东西时将 random_state 设置为某个固定数字,但是如果你真的需要随机(而不是固定)拆分,然后在生产中将其删除。

关于你的第二个问题,伪随机数生成器是一种生成几乎真正随机数的数字生成器。为什么它们不是真正随机的超出了这个问题的范围,并且在您的情况下可能无关紧要,您可以查看 here 形成更多详细信息。

如果您没有在代码中指定 random_state,那么每次您 运行(执行)您的代码时都会生成一个新的随机值,并且训练数据集和测试数据集会有不同每次值。

但是,如果像 random_state = 42 这样分配固定值,那么无论您执行代码多少次,结果都将是相同的。即,训练和测试数据集中的值相同。

sklearn.model_selection.train_test_split(*arrays, **options)[source]

将数组或矩阵拆分为随机训练和测试子集

Parameters: ... 
    random_state : int, RandomState instance or None, optional (default=None)

如果是int,random_state是随机数生成器使用的种子;如果是 RandomState 实例,random_state 是随机数生成器;如果None,随机数生成器是np.random使用的RandomState实例。 来源:http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html

'''关于随机状态,sklearn中很多随机化算法都会用到它来决定传递给伪随机数生成器的随机种子。因此,它不管理算法行为的任何方面。因此,在验证集中表现良好的随机状态值与在新的、未见过的测试集中表现良好的随机状态值并不对应。事实上,根据算法的不同,你可能会通过改变训练样本的顺序看到完全不同的结果。''' 来源:https://stats.stackexchange.com/questions/263999/is-random-state-a-parameter-to-tune

如果您没有在代码中提及 random_state,那么每当您执行代码时都会生成一个新的随机值,并且每次训练和测试数据集都会有不同的值。

但是,如果您每次都为 random_state(random_state = 1 或任何其他值)使用特定值,结果将相同,即训练和测试数据集中的值相同。 参考以下代码:

import pandas as pd 
from sklearn.model_selection import train_test_split
test_series = pd.Series(range(100))
size30split = train_test_split(test_series,random_state = 1,test_size = .3)
size25split = train_test_split(test_series,random_state = 1,test_size = .25)
common = [element for element in size25split[0] if element in size30split[0]]
print(len(common))

无论您 运行 代码多少次,输出都将是 70。

70

尝试删除 random_state 和 运行 代码。

import pandas as pd 
from sklearn.model_selection import train_test_split
test_series = pd.Series(range(100))
size30split = train_test_split(test_series,test_size = .3)
size25split = train_test_split(test_series,test_size = .25)
common = [element for element in size25split[0] if element in size30split[0]]
print(len(common))

现在每次执行代码时输出都会不同。

random_state 数字以随机方式拆分测试和训练数据集。除了此处解释的内容之外,重要的是要记住 random_state 值会对模型的质量产生重大影响(我所说的质量本质上是指预测的准确性)。例如,如果您采用某个数据集并使用它训练回归模型,而不指定 random_state 值,则每次您训练的模型在测试数据上的准确度结果都有可能不同。 因此,重要的是找到最佳 random_state 值,以便为您提供最准确的模型。然后,该数字将用于在另一个场合(例如另一个研究实验)中重现您的模型。 为此,可以通过将随机数分配给 random_state 参数来在 for 循环中拆分和训练模型:

for j in range(1000):

            X_train, X_test, y_train, y_test = train_test_split(X, y , random_state =j,     test_size=0.35)
            lr = LarsCV().fit(X_train, y_train)

            tr_score.append(lr.score(X_train, y_train))
            ts_score.append(lr.score(X_test, y_test))

        J = ts_score.index(np.max(ts_score))

        X_train, X_test, y_train, y_test = train_test_split(X, y , random_state =J, test_size=0.35)
        M = LarsCV().fit(X_train, y_train)
        y_pred = M.predict(X_test)`

如果没有运行domstate,系统将使用内部生成的运行domstate。因此,当您多次 运行 程序时,您可能会看到不同的 train/test 数据点,并且行为将不可预测。如果您的模型有问题,您将无法重新创建它,因为您不知道 运行 程序时生成的 运行dom 编号。

如果您看到树分类器——无论是 DT 还是 RF,它们都会尝试使用最佳计划进行尝试。虽然大多数时候这个计划可能是相同的,但在某些情况下,树可能会有所不同,因此预测也会有所不同。当您尝试调试模型时,您可能无法重新创建为其构建树的同一实例。因此,为了避免所有这些麻烦,我们在构建 DecisionTreeClassifier 或 RandomForestClassifier 时使用 random_state。

PS:您可以深入了解如何在 DecisionTree 中构建树,以便更好地理解这一点。

运行domstate 基本上用于在每次 运行 时重现您的问题。如果您不在 traintestsplit 中使用 运行domstate,则每次进行拆分时,您可能会得到一组不同的训练和测试数据点,并且在遇到问题时无法帮助您进行调试。

来自医生:

如果是int,运行domstate是运行dom数生成器使用的seed;如果是RandomState实例,运行domstate就是运行dom数生成器;如果None,运行dom数生成器是np.random使用的RandomState实例。

好吧,什么是“随机状态”以及为什么使用它,上面的人已经很好地回答了这个问题。我将尝试回答这个问题 “为什么我们在训练机器学习模型时经常选择随机状态 42?为什么我们不选择 12 或 32 或 5?” 有科学解释吗?

许多学生和从业者使用这个数字(42)作为随机状态,因为它被许多在线课程的教师使用。他们经常将随机状态或 numpy 种子设置为数字 42,学习者不假思索地遵循相同的做法。

具体来说,42与AI或ML无关。它实际上是一个通用数字,在机器学习中,实际随机数是什么并不重要,如 scikit API 文档中所述,任何 INTEGER 都足够手头的任务。

42 参考了 银河系漫游指南。生命宇宙和一切的答案是一个笑话。没有其他意义。

参考文献:

  1. Wikipedia: on Hitchhikers guide to galaxy
  2. Stack Exchange: Why the Number 42 is preferred when indicating something random
  3. Why the Number 42
  4. Quora: Why the Number 42 is preferred when indicating something random
  5. YouTube: Nice Simple video explaining use of random state in train-test-split