随机种子在系统之间兼容吗?

2024-05-19 09:15:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用python的sklearn包创建了一个随机林模型,其中我将seed设置为例如1234。对于产品化模型,我们使用pyspark。如果我传递相同的超参数和相同的种子值,即1234,它会得到相同的结果吗?在

基本上,随机种子数在不同的系统之间有效吗?在


Tags: 模型参数系统sklearn种子pysparkseed种子数
3条回答

好吧,这正是通过一些实验和提供的代码片段可以解决的问题。。。在

总之,一般的答案似乎是坚定的:不仅在Python和Spark MLlib之间,甚至在Spark子模块之间,或者Python&Numpy之间。。。在

下面是一些在Databricks community cloud中运行的可复制代码(其中pyspark已经导入并初始化了相关上下文):

import sys

import random
import pandas as pd
import numpy as np
from pyspark.sql.functions import rand, randn
from pyspark.mllib import random as r  # avoid conflict with native Python random module

print("Spark version " + spark.version)
print("Python version %s.%s.%s" % sys.version_info[:3])
print("Numpy version " + np.version.version)

# Spark version 2.3.1 
# Python version 3.5.2 
# Numpy version 1.11.1

s = 1234 # RNG seed


# Spark SQL random module:
spark_df = sqlContext.range(0, 10)
spark_df = spark_df.select("id", randn(seed=s).alias("normal"), rand(seed=s).alias("uniform"))


# Python 3 random module:
random.seed(s)
x = [random.uniform(0,1) for i in range(10)] # random.rand() gives exact same results

random.seed(s)
y = [random.normalvariate(0,1) for i in range(10)]

df = pd.DataFrame({'uniform':x, 'normal':y})


# numpy random module
np.random.seed(s)
xx = np.random.uniform(size=10)  # again, np.random.rand(10) gives exact same results

np.random.seed(s)
yy = np.random.randn(10)

numpy_df = pd.DataFrame({'uniform':xx, 'normal':yy})


# Spark MLlib random module
rdd_uniform = r.RandomRDDs.uniformRDD(sc, 10, seed=s).collect()
rdd_normal = r.RandomRDDs.normalRDD(sc, 10, seed=s).collect()

rdd_df = pd.DataFrame({'uniform':rdd_uniform, 'normal':rdd_normal})

结果如下:

原生Python 3:

^{pr2}$

纽比:

# numpy_df

     normal  uniform
0  0.471435 0.191519
1 -1.190976 0.622109 
2  1.432707 0.437728
3 -0.312652 0.785359
4 -0.720589 0.779976
5  0.887163 0.272593
6  0.859588 0.276464 
7 -0.636524 0.801872 
8  0.015696 0.958139
9 -2.242685 0.875933

Spark SQL:

# spark_df.show()

+ -+          +         -+ 
| id|              normal|            uniform|
+ -+          +         -+
|  0|  0.9707422835368164| 0.9499610869333489| 
|  1|  0.3641589200870126| 0.9682554532421536|
|  2|-0.22282955491417034|0.20293463923130883|
|  3|-0.00607734375219...|0.49540111648680385|
|  4|  -0.603246393509015|0.04350782074761239|
|  5|-0.12066287904491797|0.09390549680302918|
|  6|  0.2899567922101867| 0.6789838400775526|
|  7|  0.5827830892516723| 0.6560703836291193|
|  8|   1.351649207673346| 0.7750229279150739|
|  9|  0.5286035772104091| 0.6075560897646175|
+ -+          +         -+

火花MLlib:

# rdd_df

     normal  uniform 
0 -0.957840 0.259282 
1  0.742598 0.674052 
2  0.225768 0.707127 
3  1.109644 0.850683 
4 -0.269745 0.414752 
5 -0.148916 0.494394 
6  0.172857 0.724337
7 -0.276485 0.252977
8 -0.963518 0.356758
9  1.366452 0.703145

当然,即使上述结果相同,也不能保证scikit learn中的随机森林的结果与pyspark Random Forest的结果完全相同。。。在

尽管答案是否定的,但我真的看不出这会对任何ML系统的部署产生怎样的影响,也就是说,如果结果在很大程度上取决于RNG,那么肯定有些事情是不对的。。。在

是的,(伪)随机数生成器是完全确定的,并且在给定相同输入的情况下总是返回相同的输出。当然,如果生成随机数的环境在不同系统中是相同的(不同版本可能会有所不同)。在

在过去,prng的可移植性不是一个既定的条件。机器体系结构、溢出处理以及所使用的算法及其实现语言的差异意味着结果可能也确实不同,即使它们名义上是基于相同的数学公式。1979年,Schrage(见1194页here)创建了一个便携式素模乘性线性同余发生器,并证明它可以用机器和语言独立的方式实现“……只要机器能代表-231到23-1区间内的所有整数。”他给出了一个具体的检查实现者可以使用来测试他们的实现,指定1000个结果应该被赋予一个特定的种子值。自从Schrage的工作以来,设计独立于平台和语言的算法已经成为一种规范。在

Python的默认生成器是一个mersenetwister,在Mersenne Twister home page上可以使用各种平台和语言无关的MT实现。如果Python将来会切换它的默认生成器,那么兼容性将得不到保证,除非您使用上面链接中提供的独立Python实现之一。在

相关问题 更多 >

    热门问题