6.2 随机变量

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

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

CDFX(x)=P(Xx)CDF_X(x) = P(X\leq x)

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

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

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

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

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

class Exponential(RandomVariable): 
  def __init__(self, lam): 
    self.lam = lam 

  def generate(self): 
    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个服从参数为λ的指数分布的随机数进行求和。这里是它的一个实现:

class Erlang(RandomVariable): 
  def __init__(self, lam, k): 
    self.lam = lam 
    self.k = k 
    self.expo = Exponential(lam) 

  def generate(self): 
    total = 0 
    for i in range(self.k): 
      total += self.expo.generate() 
    return total

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

习题6-4

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