6.2 随机变量

随机变量(random variable)代表产生随机数的过程。随机变量一般用大写字母表示,如X。当你看到一个随机变量时,可以把它想成从某个分布函数抽出来的值。

累积分布函数(cumulative distribution function)的形式化定义为:

CDFX(x) = P(Xx)

到目前为止,我一直在尽量避免使用这类数学符号,因为这些符号总有点难以理解。这个公式对累积分布函数进行了定义:随机变量X的累积分布函数在某个特定的值x上的函数值被定义为随机变量X小于等于x的概率。

从计算机人士的角度看,我们可以将随机变量设想成一个提供方法的对象,将该方法命名为generate,它能利用随机过程产生一些值。

例如,下面的代码可以用来表示随机变量的一个类:

  1. class RandomVariable(object):
  2. """Parent class for all random variables."""

一个服从指数分布的随机变量:

  1. class Exponential(RandomVariable):
  2. def __init__(self, lam):
  3. self.lam = lam
  4. def generate(self):
  5. return random.expovariate(self.lam)

init方法接受一个参数λ并将其作为属性存储起来,generate 返回了一个服从参数为λ的指数分布的随机数。

每调用一次generate都将得到一个不同的数值。得到的数值称为随机数(random variate)。这就是在random模块中很多函数的名字都包含variate的原因。

如果仅仅是为了产生服从指数分布的随机数,或许不用费心地定义一个新类,可能直接用 random.expovariate实现就行了。但是对于其他分布,用RandomVariable对象会是更好的选择。例如,爱尔朗分布(Erlang distribution)是一个连续型分布,有两个参数λk。(参考 http://wikipedia.org/wiki/Erlang_distribution)。

一种产生服从爱尔朗分布的随机数的方法是,将k个服从参数为λ的指数分布的随机数进行求和。这里是它的一个实现:

  1. class Erlang(RandomVariable):
  2. def __init__(self, lam, k):
  3. self.lam = lam
  4. self.k = k
  5. self.expo = Exponential(lam)
  6. def generate(self):
  7. total = 0
  8. for i in range(self.k):
  9. total += self.expo.generate()
  10. return total

init方法产生一个给定参数的指数分布对象,generate可以调用它。通常, init方法可以接受任意一组参数,而generate函数则能实现任意随机过程。

习题6-4

请编写一个服从耿贝尔分布(Gumbel distribution)的随机变量的类的定义。(耿贝尔分布请参考 http://wikipedia.org/wiki/Gumbel_distribution。)