创建连续分布是非常简单的.

    令人高兴的是,pdf也能被自动计算出来:

    1. >>>
    2. >>> deterministic.pdf(np.arange(-3, 3, 0.5))
    3. array([ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
    4. 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
    5. 5.83333333e+04, 4.16333634e-12, 4.16333634e-12,
    6. 4.16333634e-12, 4.16333634e-12, 4.16333634e-12])

    注意这种用法的性能问题,参见“性能问题与注意事项”一节。这种缺乏信息的通用计算可能非常慢。
    而且再看看下面这个准确性的例子:

    1. >>> from scipy.integrate import quad
    2. >>> quad(deterministic.pdf, -1e-1, 1e-1)
    3. (4.163336342344337e-13, 0.0)

    但这并不是对pdf积分的正确的结果,实际上结果应为1.让我们将积分变得更小一些。

    这样看上去好多了,然而,问题本身来源于pdf不是来自包给定的类的定义。

    继承rv_discrete

    通用信息

    通用信息可以从 rv_discrete的 docstring中得到。

    1. >>> from scipy.stats import rv_discrete
    2. >>> help(rv_discrete)

    从中我们得知:

    接下来,还有一些进一步的要求:

    • keyword必须给出。
    • Xk必须是整数
    • 小数的有效位数应当被给出。

    事实上,如果最后两个要求没有被满足,一个异常将被抛出或者导致一个错误的数值。

    一个例子

    1. >>> npoints = 20 # number of integer support points of the distribution minus 1
    2. >>> npointsh = npoints / 2
    3. >>> nbound = 4 # bounds for the truncated normal
    4. >>> normbound = (1+1/npointsf) * nbound # actual bounds of truncated normal
    5. >>> gridlimitsnorm = (grid-0.5) / npointsh * nbound # bin limits for the truncnorm
    6. >>> gridlimits = grid - 0.5 # used later in the analysis
    7. >>> grid = grid[:-1]
    8. >>> probs = np.diff(stats.truncnorm.cdf(gridlimitsnorm, -normbound, normbound))
    9. >>> gridint = grid

    然后我们可以继承rv_discrete类

    现在我们已经定义了这个分布,我们可以调用其所有常规的离散分布方法。

    1. >>> print 'mean = %6.4f, variance = %6.4f, skew = %6.4f, kurtosis = %6.4f'% \
    2. ... normdiscrete.stats(moments = 'mvsk')
    3. mean = -0.0000, variance = 6.3302, skew = 0.0000, kurtosis = -0.0076
    4. >>> nd_std = np.sqrt(normdiscrete.stats(moments='v'))

    测试上面的结果

    让我们产生一个随机样本并且比较连续概率的情况。

    1. >>> n_sample = 500
    2. >>> np.random.seed(87655678) # fix the seed for replicability
    3. >>> rvs = normdiscrete.rvs(size=n_sample)
    4. >>> rvsnd = rvs
    5. >>> f, l = np.histogram(rvs, bins=gridlimits)
    6. >>> sfreq = np.vstack([gridint, f, probs*n_sample]).T
    7. >>> print sfreq
    8. [[ -1.00000000e+01 0.00000000e+00 2.95019349e-02]
    9. [ -7.00000000e+00 2.00000000e+00 1.65568919e+00]
    10. [ -6.00000000e+00 1.00000000e+00 4.62125309e+00]
    11. [ -5.00000000e+00 9.00000000e+00 1.10137298e+01]
    12. [ -4.00000000e+00 2.60000000e+01 2.24137683e+01]
    13. [ -3.00000000e+00 3.70000000e+01 3.89503370e+01]
    14. [ -2.00000000e+00 5.10000000e+01 5.78004747e+01]
    15. [ -1.00000000e+00 7.10000000e+01 7.32455414e+01]
    16. [ 0.00000000e+00 7.40000000e+01 7.92618251e+01]
    17. [ 1.00000000e+00 8.90000000e+01 7.32455414e+01]
    18. [ 2.00000000e+00 5.50000000e+01 5.78004747e+01]
    19. [ 3.00000000e+00 5.00000000e+01 3.89503370e+01]
    20. [ 4.00000000e+00 1.70000000e+01 2.24137683e+01]
    21. [ 5.00000000e+00 1.10000000e+01 1.10137298e+01]
    22. [ 6.00000000e+00 4.00000000e+00 4.62125309e+00]
    23. [ 7.00000000e+00 3.00000000e+00 1.65568919e+00]
    24. [ 8.00000000e+00 0.00000000e+00 5.06497902e-01]
    25. [ 9.00000000e+00 0.00000000e+00 1.32294142e-01]
    26. [ 1.00000000e+01 0.00000000e+00 2.95019349e-02]]


    构造具体的分布 - 图2

    接下来,我们可以测试,是否我们的样本取自于一个normdiscrete分布。这也是在验证
    是否随机数是以正确的方式产生的。

    1. >>> print 'chisquare for normdiscrete: chi2 = %6.3f pvalue = %6.4f' % (ch2, pval)

    P值在这个情况下是不显著地,所以我们可以断言我们的随机样本的确是由此分布产生的。