【问题标题】:Are random seeds compatible between systems?随机种子在系统之间是否兼容?
【发布时间】:2019-02-17 00:28:13
【问题描述】:

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

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

【问题讨论】:

  • 你可以为此编写一个测试用例。输入种子,生成100个随机数,检查是否是预期的。

标签: python random scikit-learn pyspark apache-spark-mllib


【解决方案1】:

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

Python 的默认生成器是 Mersenne twister,Mersenne Twister home page 上提供了各种独立于平台和语言的 MT 实现。如果 Python 将来切换其默认生成器,则除非您使用上面链接中提供的独立 Python 实现之一,否则无法保证兼容性。

【讨论】:

    【解决方案2】:

    嗯,这正是真正可以通过提供的一些实验和代码 sn-ps 来解决的问题......

    无论如何,一般的答案似乎是坚定的否:不仅在 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:

    # df
    
         normal  uniform
    0  1.430825 0.966454
    1  1.803801 0.440733 
    2  0.321290 0.007491 
    3  0.599006 0.910976 
    4 -0.700891 0.939269 
    5  0.233350 0.582228
    6 -0.613906 0.671563
    7 -1.622382 0.083938
    8  0.131975 0.766481
    9  0.191054 0.236810
    

    麻木:

    # 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|
    +---+--------------------+-------------------+
    

    Spark 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 随机森林的结果完全相同 ...

    尽管答案是否定的,但我真的看不出这会如何影响任何 ML 系统的部署,即如果结果关键地依赖于 RNG,那么肯定有什么问题不对……

    【讨论】:

      猜你喜欢
      • 2015-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 2012-07-19
      • 2014-06-01
      相关资源
      最近更新 更多