赞
踩
在机器学习中,采用概率视角来理解数据特征,比较常用的有多种概率分布函数,本文对其作基本的总结。具体而言,主要有均匀分布、高斯分布、伯努利分布、泊松分布、二项分布、多项式分布、贝塔分布、贝塔-二项分布、负二项分布、狄里克雷分布,伽马分布等。
按随机变量的所属类型即离散型和连续型,概率分布分为离散型随机变量概率分布和连续型变量概率分布。
想象投掷一枚硬币n次,令变量表示头朝上出现的次数,如果定义参数为单次投掷硬币头朝上的概率,则称服从二项分布,表示为 ,相应的概率质量函数pmf(连续变量称pdf)定义如下:
其中系数表达式定义如下
相应的系数就是通常所说的二项式系数,表示从可供选项数目n中选出k个选项的总方案数。二项分布的展示效果及代码如下。
-
- import numpy as np
- from matplotlib import pyplot as plt
-
- import operator as op
- from functools import reduce
-
- def const(n, r):
- r = min(r, n-r)
- numer = reduce(op.mul, range(n, n-r, -1), 1)
- denom = reduce(op.mul, range(1, r+1), 1)
- return numer / denom
-
- def binomial(n, p):
- q = 1 - p
- #y = [const(n, k) * (p ** k) * (q ** (n-k)) for k in range(n)]
- xlist = []
- ylist = []
- for k in range(n):
- x = k
- y = const(n, k) * (p ** k) * (q ** (n-k))
- xlist.append(x)
- ylist.append(y)
- return xlist, ylist, np.mean(ylist), np.std(ylist)
-
- for ls in [(0.5, 20), (0.7, 40), (0.5, 40)]:
- p, n_experiment = ls[0], ls[1]
- #x = np.arange(n_experiment)
- x, y, u, s = binomial(n_experiment, p)
- plt.scatter(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
-
- plt.legend()
- #plt.savefig('./graph/binomial.png')
- plt.show()
想象投掷一枚硬币,得到的结果是正面(头像)朝上和反面朝上,用变量来定义这个事件,则,则称这个事件服从伯努利分布,表示为 ,其中参数为头朝上的概率,相应的概率质量函数pmf(连续变量称pdf)定义如下:
上式可简化表示为:
由上可知,伯努利分布是二项分布一个特例,即。伯努利分布的展示效果及代码如下。
-
- import random
- import numpy as np
- from matplotlib import pyplot as plt
-
- def bernoulli(p, k):
- return p if k else 1 - p
-
- n_experiment = 100
- p = 0.6
- x = np.arange(n_experiment)
- y = []
- for _ in range(n_experiment):
- pick = bernoulli(p, k=bool(random.getrandbits(1)))
- y.append(pick)
-
- u, s = np.mean(y), np.std(y)
- plt.scatter(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s), marker="o", c= "red")
- plt.legend()
- #plt.savefig('./graph/bernoulli.png')
- plt.show()
多项分布是二项分布的推广。二项分布做n次伯努利试验,规定了每次试验的结果只有两个比如0,1,常用于模拟双面硬币的投掷结果。如果现在还是做n次试验,但每次试验的结果可以有个(比如投掷骰子),且个结果发生的概率互斥且和为1,则发生其中一个结果次的概率就是多项分布。令表示随机变量,对应的是上述投掷结果,其中表示的是第面朝上的次数,则相应的pmf如下:
其中表示第面朝上的概率,系数表达式定义如下
上述系数就是通常所说的多项式系数。具体而言,多项式系数的推导可理解为:
一共有 种方法确定第一个子集,第一个子集确定后,从剩下的中确定第二个子集的可选方法,再从剩下的中确定第三个子集,以此类推,第个子集中有可选方法, 是投掷的总次数。
经过消去约简后得到:
多项分布的展示效果及代码如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- import operator as op
- from functools import reduce
-
- def factorial(n):
- return reduce(op.mul, range(1, n + 1), 1)
-
- def const(n, a, b, c):
- """
- return n! / a! b! c!, where a+b+c == n
- """
- assert a + b + c == n
-
- numer = factorial(n)
- denom = factorial(a) * factorial(b) * factorial(c)
- return numer / denom
-
- def multinomial(n):
- """
- :param x : list, sum(x) should be `n`
- :param n : number of trial
- :param p: list, sum(p) should be `1`
- """
- # get all a,b,c where a+b+c == n, a<b<c
- ls = []
- for i in range(1, n + 1):
- for j in range(i, n + 1):
- for k in range(j, n + 1):
- if i + j + k == n:
- ls.append([i, j, k])
-
- y = [const(n, l[0], l[1], l[2]) for l in ls]
- x = np.arange(len(y))
- return x, y, np.mean(y), np.std(y)
-
- for n_experiment in [20, 21, 22]:
- x, y, u, s = multinomial(n_experiment)
- plt.scatter(x, y, label=r'$trial=%d$' % (n_experiment))
-
- plt.legend()
- #plt.savefig('./graph/multinomial.png')
- plt.show()
基于上述的分析, 随机变量,如果取,则对于投掷K面的骰子(特别注意:此时可使用指示函数来表示每个面的取值结果,相当于每个面只有0或1的可能,共K个面,不等于常见的骰子取1-6),得到的就是由0,1组成的向量,特别地,如果投掷得到第k面,对应的就是第k个向量。在这种情况下,我们可以将想象为有K种状态的分类随机变量,那么就是它的dummy encoding。也就是
如果K=3,那么我们就将1,2,3三种状态编码为(1,0,0),(0,1,0),(0,0,1),这就是现在所谓的one-hot encoding,此时可以理解为K面只有一面“hot”,对应的pmf可简化为:
上述的类别分布常用于对不同的类别进行编码,Gustavo Lacerda也建议称之为multinoulli distribution 与 multinomial distribution进行对应。上述四种最基本的离散分布对比:
类别分布的展示效果及代码实现如下。
- import random
- import numpy as np
- from matplotlib import pyplot as plt
-
- def categorical(p, k):
- return p[k]
-
- n_experiment = 100
- p = [0.3, 0.1, 0.6]
- x = np.arange(n_experiment)
- y = []
- for _ in range(n_experiment):
- pick = categorical(p, k=random.randint(0, len(p) - 1))
- y.append(pick)
-
- u, s = np.mean(y), np.std(y)
- plt.scatter(x, y, c = "red", label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
- plt.legend()
- #plt.savefig('./graph/categorical.png')
- plt.show()
负二项分布的定义不唯一,我们以上述伯努利试验不断重复多次为例,定义在单次伯努利试验中的成功概率为,也就是前述的,失败的概率是。我们观察这个序列,直到发生预定义的成功次数, 那么我们看到的失败次数X将具有负二项(或Pascal)分布,记为:。
我们可以类似地使用负二项分布来模拟某台机器在它发生故障之前的工作天数(r = 1)。对应的pmf如下。
其中r是成功的次数,k是失败的次数,p是成功的概率。在这个公式中,均值与方差分别如下:
表达式右侧括号中的项就是二项式系数,并且定义如下
从k+r-1 个样本而不是k+r 个样本中选择了k个失败,因为根据定义, k+r 个样本中的最后一个试验是成功的。上述系数展开式最右边一项继续展开为:
这也就是所谓的“负二项”的来历。
通过最后一个表达式和二项式系数,对于每个和。
因此概率质量函数的项满足求和为1。
要理解概率质量函数的上述定义,需要注意每个特定序列的 r 次成功和k 次失败的概率是,因为k + r次试验的结果是独立发生的。由于第r次成功总是最后出现,所以仍然需要 从剩余的k+r-1 次试验中选择失败的 k次试验。上述二项式系数,给出了k+r-1 的精确解释。负二项分布的展示效果及代码如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- import operator as op
- from functools import reduce
-
- def factorial(n):
- return reduce(op.mul, range(1, n + 1), 1)
-
-
- def const(k, r):
- numer = factorial(k+r-1)
- denom = factorial(r-1) * factorial(k)
- return numer / denom
-
-
- def negative_binomial(ns, rs, p):
- q = 1 - p
- xlist = []
- ylist = []
- ks = ns - rs # total failed times
- for x in range(ks):
- r = ns - x # success times r
- y = const(x, r) * (q ** x) * (p ** r)
- xlist.append(x)
- ylist.append(y)
- return xlist, ylist, np.mean(ylist), np.std(ylist)
-
-
- def negative_binomial_total(ns, rs, p):
- q = 1 - p
- xlist = list(range(rs,ns))
- ylist = []
-
- for x in xlist:
- k = x - rs # failed times k
- y = const(k, rs) * (q ** k) * (p ** rs)
- ylist.append(y)
- return xlist, ylist, np.mean(ylist), np.std(ylist)
-
- fig,axes = plt.subplots(2,1, figsize=(11,7)) #get 1x1 subplots
- axes[0].set_xlabel("failed times(k)", fontsize="12") #set the coordinate axis-x label
- axes[0].set_ylabel("Probability", fontsize="12") #set the coordinate axis-y label
- axes[0].set_title(u"Negative Binomial Distribution",fontsize=12)
-
- axes[1].set_xlabel("total times(n)", fontsize="12") #set the coordinate axis-x label
- axes[1].set_ylabel("Probability", fontsize="12") #set the coordinate axis-y label
- #axes[1].set_title(u"Negative Binomial Distribution",fontsize=12)
-
- for ls in [(0.1, 3, 30), (0.5, 14, 30), (0.8, 23, 30), (0.3, 9, 30)]:
- p, n_sucess, n_experiment = ls[0], ls[1], ls[2]
- x, y, u, s = negative_binomial(n_experiment, n_sucess, p)
- xt, yt, ut, st = negative_binomial_total(n_experiment, n_sucess, p)
- axes[0].scatter(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
- axes[1].scatter(xt, yt, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (ut, st))
-
-
- axes[0].legend()
- axes[1].legend()
- #plt.savefig('./graph/binomial.png')
- plt.show()
泊松分布由法国数学家 Siméon Denis Poisson 于1837年于他的概率论著作中首次发表。泊松分布适合于描述单位时间内随机事件发生的次数的概率分布。如某一服务设施在一定时间内受到的服务请求的次数,电话交换机接到呼叫的次数、汽车站台的候客人数、机器出现的故障数、自然灾害发生的次数、DNA序列的变异数、放射性原子核的衰变数、激光的光子数分布等等。泊松分布通常用于对小概率事件进行建模。如果令,有一个泊松分布,那么定义相应的分布参数,对应的表示为,得到的pmf如下
直观理解可参阅 知乎--马同学-如何直观的理解泊松分布。泊松分布的展示效果及代码如下。
- 当 k 小于 λ 时,k 每增加 1 累积概率增速会逐渐加大
- 而当 k 大于 λ 后,累积概率的降速也会逐渐加大。
- import numpy as np
- from matplotlib import pyplot as plt
-
- import operator as op
- from functools import reduce
-
- def poisson(x, lamb):
- xlist = []
- ylist = []
- for k in x:
- xlist.append(k)
- numer = np.exp(-lamb)*(lamb**k)
- denom = reduce(op.mul, range(1, int(k+1)), 1)
- y = numer/denom
- ylist.append(y)
- return xlist, ylist, np.mean(ylist), np.std(ylist)
-
- for lamb in [0.5, 1, 1.5, 2, 5, 8]:
-
- x = np.arange(0, 20, 1, dtype=np.int32)
- x, y, u, s = poisson(x, lamb=lamb)
- plt.plot(x, y, '-o', label=r'$\mu=%.2f,\ \sigma=%.2f,'
- r'\ \lambda=%.2f$' % (u, s, lamb))
- plt.legend()
- #plt.savefig('./graph/exponential.png')
- plt.show()
对于上述伯努利试验,获得一次成功所需的伯努利试验次数的概率分布,在集合上表示为。几何分布给出了第一次成功发生需要k个独立试验的概率,每个试验的成功概率为p,失败的概率为1-p。如果每次试验的成功概率为p,则第k次试验(共k次试验中)第一次成功的概率为:
其中 。几何分布的展示效果及代码如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def geometric(n, p):
- q = 1 - p
- xlist = []
- ylist = []
- for k in range(n):
- x = k
- y = q ** (k-1) * p
- xlist.append(x)
- ylist.append(y)
- return xlist, ylist, np.mean(ylist), np.std(ylist)
-
- for ls in [(0.5, 10), (0.7, 15), (0.3, 20)]:
- p, n_experiment = ls[0], ls[1]
- #x = np.arange(n_experiment)
- x, y, u, s = geometric(n_experiment, p)
- plt.plot(x, y, '-o', label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
-
- plt.legend()
- #plt.savefig('./graph/binomial.png')
- plt.show()
超几何分布可视为几何分布的一种扩展,描述了从有限个物件(其中包含个指定种类的物件)中抽出个物件,采取不放回方式,成功抽出该指定种类的物件的次数。超几何分布中的参数是,超几何分布记作 。假定一个箱子中共有100颗球,70颗为白球,30颗为红球,从中不放回地拿出10个球,那么共取出 个红球的概率(pmf)为:
超几何分布的展示效果及代码实现如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- import operator as op
- from functools import reduce
-
- def const(ns, ks):
- ks = min(ks, ns-ks)
- numer = reduce(op.mul, range(ns, ns-ks, -1), 1)
- denom = reduce(op.mul, range(1, ks+1), 1)
- return numer / denom
-
- def hyper_geometric(N, M, n):
- xlist = []
- ylist = []
- for k in range(n):
- x = k
- y = const(M, k) * const(N-M, n-k) / const(N, n)
- xlist.append(x)
- ylist.append(y)
- return xlist, ylist, np.mean(ylist), np.std(ylist)
-
- for ls in [(10, 30, 100), (15, 60, 100), (20, 80, 100)]:
- ns, Ms, Ns = ls[0], ls[1], ls[2]
- #x = np.arange(n_experiment)
- x, y, u, s = hyper_geometric(Ns, Ms, ns)
- plt.plot(x, y, '-o', label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
-
- plt.legend()
- #plt.savefig('./graph/binomial.png')
还是以投掷骰子为例,比如结果是1到6。得到任何一个结果的概率是相等的,这就是均匀分布的基础。与伯努利分布不同,均匀分布的所有可能结果各自的个数也是相等的。如果变量服从均匀分布的,则pdf可表示为:
均匀分布也是常见的用于模拟等概率事件的分布函数,均匀分布效果展示及代码实现如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def uniform(x, a, b):
-
- y = [1 / (b - a) if a <= val and val <= b
- else 0 for val in x]
-
- return x, y, np.mean(y), np.std(y)
-
- x = np.arange(-100, 100) # define range of x
- for ls in [(-50, 50),(-15, 20), (20, 40), (10, 20)]:
- a, b = ls[0], ls[1]
- x, y, u, s = uniform(x, a, b)
- plt.plot(x, y, label=r'mean=%.2f, variance=%.2f' % (u, s))
-
- plt.legend()
- #plt.savefig('./graph/uniform.png')
- plt.show()
根据Kevin P. Murphy的总结,现在广泛提及的高斯分布这一提法存在误导性,并非由高斯首先提出。按照时间先后,高斯分布由数学家Moivre首先发现,而此时Laplace还未出生,然后Laplace 揭示了该分布的一些特殊性质(此时高斯还只有六岁),此后在1800~1810年随着高斯将高斯分布结合天体运动与最小二乘法分析误差的估计得到广泛推广应用,高斯分布(正态分布)从首次出现到最终确立,其时间简史为:
1705年, J. Bernoulli 的著作《猜测的艺术》问世,提出伯努利大数定律;
1730-1733年,棣莫弗Moivre从二项分布的渐进公式得到正态密度函数(高斯分布的雏形)首次提出中心极限定理;
1780年, P. S. M. Laplace建立中心极限定理的一般形成;
1805年,勒让德Legendre 发明最小二乘法;
1809年,高斯引入正态误差理论,不但补充了最小二乘法,而且首次导出高斯分布;
1811年,拉普拉斯利用中心极限定理论证高斯分布;
1837年,海根G.Hagen 提出元误差学说,自此之后,逐步正式确立误差服从高斯分布。
高斯分布的pdf表示如下
其中分别表示均值和方差。高斯分布得到广泛使用可总结有以下几个原因:
1) 高斯分布的定义只有两个参数,且这两个参数即均值与方差,抓取了一个概率分布最基本的属性特征。
2)根据中心极限定理,任意一个独立随机变量的和都趋于高斯分布,这使得它能够较好的模拟残差或噪声的分布特征。
3)在满足给定均值与均方差的约束前提下,高斯分布基于的假设最少,不确定性最大则具有最大的熵值。
4)高斯分布的数学形式相对简单,易于积分或微分运算,在其它分布函数中得到广泛的扩展应用。
高斯分布的展示效果及代码如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def gaussian(x, n):
- u = x.mean()
- s = x.std()
-
- # divide [x.min(), x.max()] by n
- x = np.linspace(x.min(), x.max(), n)
-
- a = ((x - u) ** 2) / (2 * (s ** 2))
- y = 1 / (s * np.sqrt(2 * np.pi)) * np.exp(-a)
-
- return x, y, x.mean(), x.std()
-
- x = np.arange(-150, 150) # define range of x
- x, y, u, s = gaussian(x, 10000)
-
- plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
- plt.legend()
- #plt.savefig('./graph/gaussian.png')
- plt.show()
正态分布是高斯分布标准化后的结果,此时均值为0,均方差为1。相应的的pdf如下:
正态分布的展示效果及代码如下。
-
- import numpy as np
- from matplotlib import pyplot as plt
-
- def normal(x, n):
- u = x.mean()
- s = x.std()
-
- # normalization
- x = (x - u) / s
-
- # divide [x.min(), x.max()] by n
- x = np.linspace(x.min(), x.max(), n)
-
- a = ((x - 0) ** 2) / (2 * (1 ** 2))
- y = 1 / (s * np.sqrt(2 * np.pi)) * np.exp(-a)
-
- return x, y, x.mean(), x.std()
-
- x = np.arange(-150, 150) # define range of x
- x, y, u, s = normal(x, 10000)
-
- plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
- plt.legend()
- #plt.savefig('./graph/normal.png')
- plt.show()
对于上述高斯分布当 ,概率分布中的所有质量都集中在一个点上,使得概率分布图变得无限“瘦长”,此时
这里的 称之为狄拉克-德尔塔函数(Dirac delta function),也称之为狄拉克分布,也称之为退化概率密度函数(degenerate pdf),亦可定义为
积分形式如下:
上述函数的一个重要的属性是具有筛选特性(sifting property),即能够从一个求和或积分式中筛选出单项:
狄拉克-德尔塔函数的展示效果及代码实现如下。
- import numpy as np
- import matplotlib.pyplot as plt
-
- def dirac_delta(x,sig):
- res = np.zeros_like(x)
- res[(-(1/(2*sig))<=x) & (x<=(1/(2*sig)))] = 1
- return res
-
- x = np.linspace(-5,5,1000)
-
- for sigma in np.arange(1,5,0.1):
- plt.cla()
- plt.grid()
- plt.title('Dirac Delta function',size=12)
- plt.xlabel('x',size=10)
- plt.ylabel("$\delta(x)$",size=12)
- plt.ylim(0,1)
- plt.plot(x,dirac_delta(x,sigma),color='red')
- plt.pause(0.5)
-
- plt.show()
假设我们有一组
上述这个分布就称为数据集
其中,
经验分布的展示效果及代码实现如下。
- import numpy as np
- import statsmodels.api as sm # recommended import according to the docs
- import matplotlib.pyplot as plt
-
- sample = np.random.uniform(0, 1, 5)
- ecdf = sm.distributions.ECDF(sample)
-
- x = np.linspace(min(sample), max(sample))
- y = ecdf(x)
- plt.step(x, y)
- plt.show()
学生分布由英国统计学家威廉·西利·戈塞特 Gosset 在爱尔兰吉尼斯啤酒厂工作期间提出并发表。为了满足吉尼斯董事关于研究人员发表科学研究不提及啤酒、吉尼斯或人员的姓氏的要求,Gosset 以他的笔名“学生”予以首次发表。学生分布的pdf如下
标准化后即,则上述简化为:
高斯分布对数据中的离群点比较敏感,比如具有明显长尾效应的数据点采用高斯分布建模,则得到的分布易受到噪声影响,主要原因在于log-probability 以中心位置仅仅只是二次衰减。而学生分布可视为高斯分布的一个扩展,在远离中心位置快速衰减(阶次高于2),几乎不受离群点的影响。学生分布的展示效果及代码实现如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def gamma_function(n):
- cal = 1
- for i in range(2, n):
- cal *= i
- return cal
-
- def student_t(x, freedom, n):
-
- # divide [x.min(), x.max()] by n
- x = np.linspace(x.min(), x.max(), n)
-
- c = gamma_function((freedom + 1) // 2) \
- / np.sqrt(freedom * np.pi) * gamma_function(freedom // 2)
- y = c * (1 + x**2 / freedom) ** (-((freedom + 1) / 2))
-
- return x, y, np.mean(y), np.std(y)
-
- for freedom in [1, 2, 3, 5]:
-
- x = np.arange(-10, 10) # define range of x
- x, y, _, _ = student_t(x, freedom=freedom, n=10000)
- plt.plot(x, y, label=r'$v=%d$' % (freedom))
-
- plt.legend()
- plt.savefig('./graph/student_t.png')
- plt.show()
柯西分布又称为洛伦兹分布( Cauchy distribution/Lorentiz distribution),是学生分布的一个特例,即相应的自由度参数。
柯西分布的展示效果及代码实现如下。
- import numpy as np
- import math
- from matplotlib import pyplot as plt
-
- def cauchy(x, mu, sigma):
- c = 1/(math.pi * sigma)
- y = (1 + ((x -mu)/sigma)**2)**(-1) * c
- return x, y, np.mean(y), np.std(y)
-
- for ls in [(0, 1), (1, 2), (2, 0.5), (2, 5),(3, 2) ]:
- a, b = ls[0], ls[1]
-
- x = np.arange(-4, 20, 0.01, dtype=np.float)
- x, y, u, s = cauchy(x, mu = a, sigma =b)
- plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$'% (a, b))
- plt.legend()
- #plt.savefig('./graph/gamma.png')
- plt.show()
拉普拉斯分布又称为双侧指数分布,它的概率密度函数pdf表示如下:
其中参数分别表示位置参数和比例参数(或缩放参数),且。相应地主要参数有:
拉普拉斯分布在0位置相比高斯分布有更多的概率密度设置,这个特性使得它增强稀疏的作用。对拉普拉斯取负对数可以得到正则化的形式,而不同于高斯分布得到的正则化形式,这有利于得到稀疏解。laplace分布的展示效果及代码实现如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def laplace(x, mu, b):
-
- y = np.exp(-abs(x-mu)/b)/(2*b)
- return x, y, np.mean(y), np.std(y)
-
- for ls in [(0, 1), (1, 5), (3, 1), (2, 2)]:
- a1, a2 = ls[0], ls[1]
-
- x = np.arange(-10, 10, 0.01, dtype=np.float)
- x, y, u, s = laplace(x, mu=a1, b=a2)
- plt.plot(x, y, label=r'$\mu=%d,\ b=%d$' % (a1, a2))
- plt.legend()
- #plt.savefig('./graph/gamma.png')
- plt.show()
gamma 分布是一类非常重要的基础分布,因为很多常用的分布函数可视作伽马分布的一个特例,它的分布函数pdf主要有两个参数形状参数 和尺度参数 来定义,具体如下
上式中,称之为gamma函数,根据定义可知伽马函数具有如下性质:
gamma分布具有如下性质
当时,伽马分布可视为n个指数分布的和。
伽马分布实际上将指数分布与泊松分布联系在一起。
1.指数分布解决的问题是,要发生一个随机事件需要等待多长的时间
2.伽马分布解决的问题是,要发生n个随机事件需要等待多长时间(每个事件发生概率符合指数分布)
3.泊松分布解决的问题是在特定的时间内,发生n次随机事件的概率(小概率事件)
伽马分布的展示效果及代码如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def gamma_function(n):
- cal = 1
- for i in range(2, n):
- cal *= i
- return cal
-
- def gamma(x, a, b):
- c = (b ** a) / gamma_function(a)
- y = c * (x ** (a - 1)) * np.exp(-b * x)
- return x, y, np.mean(y), np.std(y)
-
- for ls in [(1, 1), (2, 1), (3, 1), (2, 2)]:
- a, b = ls[0], ls[1]
-
- x = np.arange(0, 20, 0.01, dtype=np.float)
- x, y, u, s = gamma(x, a=a, b=b)
- plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f,'
- r'\ \alpha=%d,\ \beta=%d$' % (u, s, a, b))
- plt.legend()
- #plt.savefig('./graph/gamma.png')
- plt.show()
指数分布是gamma分布的一个特例,即它的pdf定义如下
指数分布描述了泊松过程中事件之间的距离或时间的分布。这里,称之为rate参数,代表单位时间内的事件数量(比如每2h接到3个投诉电话或每10h设备发生一次故障),x 代表时间。指数分布与泊松分布存在一定的关联性,因为指数分布也是泊松过程的体现。泊松分布处理固定时间段内事件发生的次数(对次数建模),属于离散性概率分布,而指数分布通常涉及到某个特定事件发生之前的时间量(对时间建模), 属于连续概率分布。
假设某个人通常每2小时接到 1 个电话。现在计算一个电话在下一小时内打来的概率?
解决方案: 假设每2小时 1 个电话。因此,预计每小时接到半个电话。所以可以取 λ = 0.5
因此,计算过程如下:
,
因此,下一小时内电话到达的概率为 0.303265.
指数分布的展示效果及代码如下。
-
- import numpy as np
- from matplotlib import pyplot as plt
-
- def exponential(x, lamb):
- y = lamb * np.exp(-lamb * x)
- return x, y, np.mean(y), np.std(y)
-
- for lamb in [1, 2, 3]:
-
- x = np.arange(0, 6, 0.01, dtype=np.float)
- x, y, u, s = exponential(x, lamb=lamb)
- plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f,'
- r'\ \lambda=%d$' % (u, s, lamb))
- plt.legend()
- #plt.savefig('./graph/exponential.png')
- plt.show()
k个独立的标准正态分布变量的平方和服从自由度为k的卡方分布。卡方分布是伽马分布的一个特例,相应的pdf定义如下:
比如定义k个随机变量是相互独立,符合标准正态分布的随机变量(数学期望为0、方差为1) ,那么 ,其中S的定义如下
卡方分布常用于对样本估计的假设检验与置信区间的计算。卡方分布的展示效果及代码如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def gamma_function(n):
- cal = 1
- for i in range(2, n):
- cal *= i
- return cal
-
- def chi_squared(x, k):
-
- c = 1 / (2 ** (k/2) * gamma_function(k//2))
- y = c * (x ** (k/2 - 1)) * np.exp(-x /2)
-
- return x, y, np.mean(y), np.std(y)
-
- for k in [2, 3, 4, 6]:
- x = np.arange(0, 10, 0.01, dtype=np.float)
- x, y, _, _ = chi_squared(x, k)
- plt.plot(x, y, label=r'$k=%d$' % (k))
-
- plt.legend()
- #plt.savefig('./graph/chi-squared.png')
- plt.show()
贝塔分布是关于概率的概率分布,由于贝塔分布是对概率建模,所以它的定义域 的取值在0-1之间,相应的pdf对应如下:
其中系数项分母定义如下:
观察贝塔分布的前置项,可以视为满足概率分布的归一化参数,直观的对比贝塔与二项分布:
二项分布和 beta 分布的区别在于前者对次数建模,模拟成功的次数 (x);而后者对概率建模,模拟成功的概率 (p)。 换句话说,概率是二项分布的参数,在 Beta分布中,概率是一个随机变量。
关于参数的解释:
可以将α-1 视为成功的次数,将β -1 视为失败的次数,就像二项式中的x和n-x项一样。 可以选择 α 和 β 参数,如果认为成功的概率非常高,假设为 90%,则将 α 设置为 90,将β 设置为 10。反之,如果不这么认为,β 为 90,α 为 10。 随着α变大(更成功的事件),大部分概率分布将向右移动,而β的增加使分布向左移动(更多失败)。 此外,如果α和β都增加,分布将变窄,因为更加确定。
贝塔分布与伽马分布一样,也是一种非常常用的基础分布,对于贝塔分布的一个特例,即,我们就能得到均匀分布。贝塔分布的展示效果及代码实现如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def gamma_function(n):
- cal = 1
- for i in range(2, n):
- cal *= i
- return cal
-
- def beta(x, a, b):
-
- gamma = gamma_function(a + b) / \
- (gamma_function(a) * gamma_function(b))
- y = gamma * (x ** (a - 1)) * ((1 - x) ** (b - 1))
- return x, y, np.mean(y), np.std(y)
-
- for ls in [(1, 3), (5, 1), (2, 2), (2, 5)]:
- a, b = ls[0], ls[1]
-
- # x in [0, 1], trial is 1/0.001 = 1000
- x = np.arange(0, 1, 0.001, dtype=np.float)
- x, y, u, s = beta(x, a=a, b=b)
- plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f,'
- r'\ \alpha=%d,\ \beta=%d$' % (u, s, a, b))
- plt.legend()
- #plt.savefig('./graph/beta.png')
- plt.show()
作为一种复合分布,beta-binomial是二项分布的共轭分布,可以认为二项分布中的参数是从 beta 分布中随机抽取的,即
上式中不是一个常量,而是作为变量且服从如下贝塔分布
由此得到贝塔-二项分布的pdf如下
使用beta 函数的性质,上式可以写成如下
贝塔-二项分布的展示效果及代码实现如下。
- import numpy as np
- from matplotlib import pyplot as plt
-
- def gamma_function(n):
- cal = 1
- for i in range(2, n):
- cal *= i
- return cal
-
- def beta_binom(n, a, b):
-
- multipliers3 = gamma_function(a + b) / \
- (gamma_function(a) * gamma_function(b))
-
- xlist = list(range(1,n))
- ylist = []
-
- for x in xlist:
-
- multipliers1 = gamma_function(n + 1) / \
- (gamma_function(x+1) * gamma_function(n-x+1))
-
- multipliers2 = gamma_function(x + a) * gamma_function(n-x+b) / \
- (gamma_function(n+a+b))
-
- y = multipliers1 *multipliers2 * multipliers3
- ylist.append(y)
-
- return xlist, ylist, np.mean(ylist), np.std(ylist)
-
- for ls in [(1, 3, 15), (5, 1, 15), (2, 2, 15), (2, 5, 15)]:
- a, b, n = ls[0], ls[1], ls[2]
-
- # x in [0, 1], trial is 1/0.001 = 1000
- xn = np.arange(0, 100, 1, dtype=np.int32)
- x, y, u, s = beta_binom(n=n, a=a, b=b)
- plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f,'
- r'\ \alpha=%d,\ \beta=%d$' % (u, s, a, b))
- plt.legend()
- #plt.savefig('./graph/beta.png')
- plt.show()
帕累托分布常用于模拟具有明显长尾特性的分布,对应的pmf如下。
帕累托分布的展示效果及代码如下。
- import numpy as np
- import matplotlib.pyplot as plt
- k, m = 6., 2. # distribution width、specify mode
- s = (np.random.pareto(k, 1000) + 1) * m
- # draw histgram
- count, bins, _ = plt.hist(s, 100, density=True)
-
- # draw line graph
- fit = k * m ** k / (bins ** (k + 1))
- plt.plot(bins, max(count) * fit / max(fit), linewidth=2, color='r')
- plt.show()
Dirichlet分布可以看做是分布之上的分布,是(多项)分布的概率的概率,是一类在实数域以正单纯形(standard simplex)为支撑集(support)的高维连续概率分布,是Beta分布在高维情形的推广,在LDA文本数据挖掘中得到了广泛应用。Dirichlet分布的pdf如下
\(Dir(\mathbf x| \boldsymbol \alpha) =\frac{1}{B(\boldsymbol \alpha)}\coprod_{k=1}^{K}x_k^{\alpha_k-1}\mathbb{I}(\mathbf x \in S_K)\\)
其中,
当K=2时,上式退化为贝塔分布的归一化因子,其中 。
Dirichlet分布的展示效果及代码如下。
- from random import randint
- import numpy as np
- from matplotlib import pyplot as plt
-
- def normalization(x, s):
- """
- :return: normalizated list, where sum(x) == s
- """
- return [(i * s) / sum(x) for i in x]
-
- def sampling():
- return normalization([randint(1, 100),
- randint(1, 100), randint(1, 100)], s=1)
-
- def gamma_function(n):
- cal = 1
- for i in range(2, n):
- cal *= i
- return cal
-
- def beta_function(alpha):
- """
- :param alpha: list, len(alpha) is k
- :return:
- """
- numerator = 1
- for a in alpha:
- numerator *= gamma_function(a)
- denominator = gamma_function(sum(alpha))
- return numerator / denominator
-
- def dirichlet(x, a, n):
- """
- :param x: list of [x[1,...,K], x[1,...,K], ...], shape is (n_trial, K)
- :param a: list of coefficient, a_i > 0
- :param n: number of trial
- :return:
- """
- c = (1 / beta_function(a))
- y = [c * (xn[0] ** (a[0] - 1)) * (xn[1] ** (a[1] - 1))
- * (xn[2] ** (a[2] - 1)) for xn in x]
- x = np.arange(n)
- return x, y, np.mean(y), np.std(y)
-
- n_experiment = 1200
- for ls in [(6, 2, 2), (3, 7, 5), (6, 2, 6), (2, 3, 4)]:
- alpha = list(ls)
-
- # random samping [x[1,...,K], x[1,...,K], ...], shape is (n_trial, K)
- # each sum of row should be one.
- x = [sampling() for _ in range(1, n_experiment + 1)]
-
- x, y, u, s = dirichlet(x, alpha, n=n_experiment)
- plt.plot(x, y, label=r'$\alpha=(%d,%d,%d)$' % (ls[0], ls[1], ls[2]))
-
- plt.legend()
- #plt.savefig('./graph/dirichlet.png')
- plt.show()
Multivariate Gaussian
Multivariate Student
其它分布还有Erlang分布、逆伽马(Inverse Gamma)分布、逆高斯(Inverse Gaussian)分布,对应分布函数可以视为上述分布的一种特殊形式或变体,具体的含义不再详述。
1. MLAPP
2.PRML
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。