【问题标题】:what is the difference between scipy.stats module and numpy.random module, between similar methods that both modules have?scipy.stats 模块和 numpy.random 模块之间有什么区别,两个模块都有类似的方法?
【发布时间】:2017-12-02 16:49:32
【问题描述】:

我在 python 中研究了一些分布函数:

均匀分布、二项分布、伯努利分布、正态分布

我发现 scipy 和 numpy 中存在几乎相同的功能。

>>> from scipy.stats import binom
>>> rv = binom(n, p)

>>> import numpy as np
>>> s = np.random.binomial(n, p, 1000)

查看我发现 scipy 内部使用 numpy 的代码:

https://github.com/scipy/scipy/blob/master/scipy/stats/_discrete_distns.py

https://github.com/numpy/numpy/blob/master/numpy/random/mtrand/distributions.c

那么,我的问题是拥有 2 个相同分布函数副本的主要动机是什么?

scipy 库提供了哪些 numpy 中没有的附加功能?

每个模块中方法的完整列表在这里:

Numpy 随机模块:https://docs.scipy.org/doc/numpy/reference/routines.random.html

Scipy 统计模块:https://docs.scipy.org/doc/scipy/reference/stats.html

我找到了两个模块之间一些基本区别的参考:Difference between random draws from scipy.stats....rvs and numpy.random

【问题讨论】:

    标签: python numpy scipy


    【解决方案1】:

    scipy 库提供了哪些 numpy 中没有的附加功能?

    如果您查看单个发行版之一的文档(例如,beta),您可以看到附加功能。 numpy 函数只允许绘制随机值。 scipy 分布有很多额外的方法来处理其他事情,比如百分位数、累积分布函数,以及平均值和标准差等统计数据。

    scipy 提供给您的某些信息不能直接从 numpy 函数中计算出来。 numpy 函数只为您提供单独的随机绘制的值,但 scipy 以数学方式表示分布,并且可以在不实际绘制任何值的情况下计算一些东西。例如,scipy 分布返回的许多统计数据都是用精确的数学公式计算的。您可以在链接到的源代码中看到,例如 binom_gen._stats 直接计算平均值、标准差等。要使用 numpy 找到平均值,您必须绘制一堆值(理论上是无限数)并计算它们的平均值; scipy 抽象地完成它而不绘制任何值。 scipy 分布公开了 numpy 无法获得的分布的数学细节。

    【讨论】:

    • 所以 Scipy 为我们提供了额外的统计组件以及生成的值。我们可以自己计算,因为我们有这个值。但我们不必这样做。这是一个有用的区别,谢谢。还有什么?
    • @VikashSingh:这不仅仅是计算可以从值计算的东西的问题。例如,scipy 分布返回的许多统计数据都是用精确的数学公式计算的。您可以在链接到的源中看到,例如,binom_gen._stats 直接计算平均值、标准差等。如果没有(理论上)绘制无限数量的值,您无法仅从 numpy 版本中获得此信息。 scipy 分布公开了 numpy 无法获得的分布的数学细节。
    • 感谢布伦。您能否将其也添加到您的答案中。我会将其标记为已解决:) PS:如果可以,请更详细地解释一下,对于像我这样在统计方面经验很少的外行。
    【解决方案2】:

    scipy 生成一个随机变量,而 numpy 生成随机数。当你使用np.random.binomial(n, p, 1)时,它只是随机变量(binom(n, p))的realization

    在概率和统计中,一个实现或观察值 随机变量是实际观察到的值(实际上 发生)。随机变量本身就是决定如何 观察产生。统计量计算自 没有部署统计模型的实现通常被称为 “经验的”,如经验分布函数或经验 概率。

    一般来说,numpy 所做的就是掷骰子数次。另一方面,scipy 告诉您连续获得两个 6 的概率是多少。如果你掷硬币一百次,预期的反面数是多少。

    当然,您可以在 numpy 中运行模拟并近似这些值(掷硬币 100 万次,反面数约为 50 万)。然而,这只是一个实验的结果。一个随机变量告诉你理论解(对于二项式,这是 np 其中 n 是试验次数,p 是概率。所以你会得到正好 500千。


    这是一个小演示:

    import scipy.stats as ss
    import numpy as np
    
    n, p = 10**4, 0.3
    rv  = ss.binom(n, p)
    

    获取随机变量的均值和标准差

    rv.mean()
    Out: 3000.0
    
    rv.std()
    Out: 45.825756949558397
    

    从该分布中生成 100 个随机数:

    prng = np.random.RandomState(0)    
    random_numbers = prng.binomial(n, p, size=100)
    

    计算平均值和标准差:

    random_numbers.mean()
    Out: 3004.8099999999999
    random_numbers.std()
    Out: 47.336813369723146
    

    再生成 100 个:

    prng = np.random.RandomState(1)
    random_numbers = prng.binomial(n, p, size=100)
    

    不同的均值和标准差:

    random_numbers.mean()
    Out: 2990.96
    
    random_numbers.std()
    Out: 46.245631145006548
    

    样本量越大,均值和标准差越接近分布均值和分布标准差:

    random_numbers = prng.binomial(n, p, size=10**7)
    
    random_numbers.mean()
    Out: 2999.9639155
    
    random_numbers.std()
    Out: 45.854409513250303
    

    【讨论】:

    • 感谢艾汉。我从中得到的是 scipy 暴露了内部数学方法,其中 numpy 给了我们输出数字。
    • @VikashSingh 是的,没错。
    猜你喜欢
    • 2013-01-11
    • 2015-11-25
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 2010-10-02
    • 2016-07-08
    • 2011-04-10
    相关资源
    最近更新 更多