2019年3月更新:最近略忙,不,是超忙,更的会慢些,我先把《神经网络与深度学习》翻译完。
最近看了一些有关网络和图的文章,遇到一些陌生的概率分布,学习之后,在这里一并描述,持续更新,文末配有 Python Matplotlib
代码,用语通俗,错误难免,还请读者斧正,函数具体如下:
我将用一个微博转发数据集 [12] 贯穿本文来说明一些分布的特性,数据集包含119,313条微博,每条微博最少被转发过10次,其中包含的信息有哪些人转发了这条微博,以及每次转发的时间。
定义:
F X ( x ) = P ( X ≤ x ) F_X(x) = P(X \le x) FX(x)=P(X≤x)
两个关键点,一个 X X X, 一个 x x x,前者代表随机变量,后者代表一个实值。
举个例子,掷骰子,可能出现的结果 X ∈ { 1 , 2 , 3 , 4 , 5 , 6 } X \in \{1, 2, 3, 4, 5, 6\} X∈{1,2,3,4,5,6}, P ( X ) = 1 / 6 P(X) = 1/6 P(X)=1/6,假如我们让 x = 6 x = 6 x=6,投一次骰子,结果小于等于 x x x 的概率是多少呢?答案是1。如果取 x = 0 x = 0 x=0, 因为不可能投出小于等于零的骰子,所以概率 P ( X ≤ 0 ) = 0 P(X \le 0) = 0 P(X≤0)=0。
这个简单的例子表明,累积分布函数在 x → − ∞ x \rarr -\infty x→−∞ 时等于 0 0 0,在 x → ∞ x \rarr \infty x→∞ 时等于 1 1 1,而且是非减、右连续的。
如图所示,给定任意一个 X X X,例如 3 3 3,可知投的骰子的数小于等于 3 3 3 的概率为 0.5 0.5 0.5。
再用微博举一个例子,微博转发数满足下面这个累积分布:
对于一条微博,它转发数小于某个 x x x 的概率是多少,可以很方便地在图中看出来。
假如现在有一正态分布 X ∼ N ( 1.7 , 0. 2 2 ) X \sim N(1.7, 0.2^2) X∼N(1.7,0.22) 表示一个班级内50个学生的身高分布,其累积分布为:
由图可知,身高低于190厘米的概率大约是 0.75 0.75 0.75,显然,正态分布的标准差设的有点大了。
定义:
F ˉ X ( x ) = P ( X > x ) = 1 − F X ( x ) \bar{F}_X(x) = P(X > x) = 1 - F_X(x) FˉX(x)=P(X>x)=1−FX(x)
定义很简单,用 1 1 1 减去原始的累积分布函数 F X ( x ) F_X(x) FX(x),还是上面那个例子:
由图可知,身高大于170厘米的概率大约为 0.55 0.55 0.55。
又名 Percent Point Function,或者Inversed Cumulative Distribution Function,含义一目了然,就是CDF的反函数。以指数分布为例:
比较两图可知,函数互为反函数。分位函数顾其名思其义,它的一大作用是分位点,以常见的四分位为例,对于 λ = 1 \lambda = 1 λ=1 指数分布,其四分位数分别为0.287、0.693、1.386,它们的含义是把样本从小到大排列,位于25%、50%、75%的数字 [13, 14]。也就是说,有25%的数字小于0.287,有25%的数字大于1.386。类似的还有二分位数和百分位数。分位函数广泛应用于统计学和蒙特卡洛方法 [15]。
又称负指数分布, X ∼ exp ( λ ) X \sim \exp(\lambda) X∼exp(λ),常用来描述事件发生的间隔时间,话不多说上公式:
f ( x ; λ ) = { λ e − λ x x ≥ 0 , 0 x < 0. f(x;\lambda) = \begin{cases} \lambda e^{-\lambda x} & x \ge 0, \\ 0 & x < 0. \end{cases} f(x;λ)={λe−λx0x≥0,x<0.
概率密度函数(PDF):
λ \lambda λ 越小表示单位时间内事件发生的次数越少。由图可知,随着 x x x 的增加,事件发生的概率越来越小。
累积分布函数(CDF):
F ( x ; λ ) = { 1 − e − λ x x ≥ 0 , 0 x < 0. F(x;\lambda) = \begin{cases} 1 - e^{-\lambda x} & x \ge 0, \\ 0 & x < 0. \end{cases} F(x;λ)={1−e−λx0x≥0,x<0.
由指数分布的CDF图可知,随着时间的增加,事件发生的概率越来越大。
重尾分布很有意思,先扔公式:
lim x → ∞ e t x Pr [ X > x ] = ∞ for all t > 0 \lim_{x \rarr \infty} e^{tx} \text{Pr}[X > x] = \infty \;\;\;\; \text{ for all } t > 0 x→∞limetxPr[X>x]=∞ for all t>0
明天再写,告辞。
我回来了,继续。我们上面介绍了指数分布,它的概率密度函数的尾巴长长的,像老鼠尾巴 ,而且越往后,其值越小, 1 / e x 1/e^x 1/ex。重尾分布不一样,它越往后尾巴不一定越小。对于一个常规老鼠,它的尾巴占身体重量的比例是很少的,如果一个老鼠的尾巴超级长,它尾巴重量的占比将不断上升,最后甚至超过身体的重量。有没有想到那个著名的二八定律 [8] ?它也叫帕累托分布(Pareto Distribution) [5],对于这个整体的分布来说,不起眼的尾巴,其重要性甚至超过了本体,比如20%的人掌握了80%的财富等等,这个定律在自然界、社会、经济等方面都有体现 [7]。回到原题,重尾分布的尾在哪并不重要,可以在右也可以在左,也可以左右都有,一般来说在右边。它的定义有一些分歧,一部分学者认为重尾分布的 power moments 是无限的,另外一部分学者认为重尾分布不具有一个有限的方差。重尾分布有三个重要的子类,(1)Fat-tailed distribution(2)Long-tailed distribution(3)Subexponential distribution,次指数分布。后面再提。
总的来说,当一个分布的尾巴很长,而且不是越长值越小,那么它就可以被称为重尾分布,其尾巴虽然看着不起眼,但在整体中占着主导地位。
在查找资料的过程中,我发现大家对重尾分布的理解有着很大的偏差,定义也不甚明确,下面主要用我自己的理解来说明。
角度一:转发数很高的微博占比很少,但是效果很出众。我们用正态分布和微博数据集分布的CCDF做一个对比,因为微博数据集的平均转发数为174.01, 所以正态分布的均值设为174.01,标准差设为150,共生成119,313个值:
很明显,微博数据集的尾巴要比正态分布厚很多,对于正态分布,概率衰减的非常快,而对于微博,随机变量 X X X 大于某个 x x x 的值的概率衰减的很慢。这意味着对于一条新的微博,它未来的转发数超过 x x x 的概率要比正态分布大很多。如果微博转发数服从正态分布,那么对于一条新微博,它的转发数超过1,000的概率几乎为0,而微博的真实分布说明对于一条新微博,其转发数超过1,000的概率高达2.5%。
如果把所有微博按转发数排序从大到小,前20%的微博的转发数占了总转发数的84.65%:
角度二: 如果用转发数区间(单位为10)表示横坐标,用微博数表示纵坐标:
由图可知,转发超过500的微博寥寥无几,大部分集中在 [ 0 , 200 ] [0, 200] [0,200] 这个区间内,这个分布的尾巴在图里看起来毫无价值。但是尾巴中从 [ 1000 , ∞ ] [1000, \infty] [1000,∞] 这个区间内的微博,贡献了84.65%的转发量。这个尾巴可算的上是重尾了。-_-
扔公式先:
lim x → ∞ Pr [ X > x + t ∣ X > x ] = 1 \lim_{x \rarr \infty} \text{Pr} [X > x + t | X > x] = 1 x→∞limPr[X>x+t∣X>x]=1
Pr [ X > x ] \text{Pr}[X > x] Pr[X>x] 就是我们前面说过的CCDF。长尾分布与重尾分布相似但不同,长尾分布都是重尾分布,但重尾分布不一定是长尾分布。微博数据集虽然符合重尾分布,但是,根据常识我们知道,一条微博被转发1,000次和被转发2,000次的概率是不一样的,显然有
lim x → ∞ Pr [ X > 2000 ∣ X > 1000 ] < 1 \lim_{x \rarr \infty} \text{Pr} [X > 2000 | X > 1000] < 1 x→∞limPr[X>2000∣X>1000]<1
长尾分布的潜在含义在于,如果 X X X 超越了某个 x x x,它一定会超越更大的 x x x。
对于两个符合同一分布函数 F F F 的随机变量 X 1 , X 2 X_1, X_2 X1,X2,它们分布函数的卷积操作,定义为:
Pr [ X 1 + X 2 ≤ x ] = F ∗ 2 ( x ) = ∫ − ∞ ∞ F ( x − y ) d F ( y ) . \text{Pr}[X_1 + X_2 \le x] = F^{*2}(x) = \int_{-\infty}^{\infty} F(x - y)dF(y). Pr[X1+X2≤x]=F∗2(x)=∫−∞∞F(x−y)dF(y).
可以推广到多个随机变量 X 1 , X 2 , … , X n X_1, X_2, \dots, X_n X1,X2,…,Xn。尾分布函数为 F ˉ ( x ) = 1 − F ( x ) \bar{F}(x) = 1 - F(x) Fˉ(x)=1−F(x).
如果分布 F F F 的正半部分满足如下条件,则其符合次指数分布:
F ∗ n ‾ ( x ) ∼ n F ‾ ( x ) as x → ∞ \overline{F^{*n}} (x) \sim n \overline{F}(x) \;\;\;\; \text{as }x \rarr \infty F∗n(x)∼nF(x)as x→∞
其中 n ≥ 1 n \ge 1 n≥1。次指数分布在各种风险模型中广泛应用,直观的理解就是, n n n 个随机变量,它们的和超过某个 x x x 的概率,和它们中最大的 X m a x X_{max} Xmax 超过 x x x 的概率等价。以保险行业为例,假设理赔金额满足次指数分布。如果你有10个保单,它们最终总的理赔金额超过10万的概率,和它们中某个金额最大的保单的单个理赔金额超过10万的概率等价。这就是说,另外9个保单的理赔金总和在后者面前几乎可以忽略不计:
Pr [ X 1 + X 2 + ⋯ + X n > x ] ∼ Pr [ m a x ( X 1 , X 2 , … , X n ) ] x → ∞ \text{Pr}[X_1+ X_2 + \dots + X_n > x] \sim \text{Pr}[max(X_1, X_2, \dots, X_n)] \;\;\;\; x \rarr \infty Pr[X1+X2+⋯+Xn>x]∼Pr[max(X1,X2,…,Xn)]x→∞
这也侧面说明,大部分的理赔金由少部分几个保单产生。容易证明,次指数分布都是长尾分布,长尾分布不一定是次指数分布。经济危机、地震灾害等都可视为次指数分布 [6]。其在现实中的意义是极小概率发生的事件造成了极大影响 [11]。
肥尾分布一般指其尾部按幂率进行衰减,不过也不绝对,某些衰减的慢些的分布也被视为肥尾分布 [2, 3, 9],例如对数正态分布、对数逻辑分布、帕累托分布等。
先扔公式:
Pr [ X > x ] ∼ x − α as x → ∞ , α > 0 \text{Pr} [X > x] \sim x^{-\alpha} \;\;\;\; \text{as } x \rarr \infty, \;\;\;\; \alpha > 0 Pr[X>x]∼x−αas x→∞,α>0
当 α \alpha α 不很大的时候,如果一个分布满足上述条件(即CCDF等价 x − α x^{-\alpha} x−α),则它可以称为肥尾分布。
说起 α \alpha α,我就想到美猴王头上的紧箍,今年春天,中美合拍,文体两开花,哦呸。还有一些概念涉及到重尾密度(Heavy-tailed Density)、尾部指数(Tail-index),我也没搞懂,有兴趣的可以自己看看。
CDF公式投喂:
F ‾ ( x ) = Pr [ X > x ] = { 1 − ( x m x ) a x ≥ x m , 0 x < x m . \overline{F}(x) = \text{Pr}[X > x] = \begin{cases} 1-(\frac {x_m}{x})^a & x \ge x_m, \\ 0 & x < x_m. \end{cases} F(x)=Pr[X>x]={1−(xxm)a0x≥xm,x<xm.
其中 x m x_m xm 是 X X X 的一个最小正值, α \alpha α 是一个正参数。
扔完公式扔图:
帕累托分布一开始用来描述八二定律(叫二八定律也行),即20%的人掌握着80%的财富 [5],其实这一条件是在尾部指数 α ≈ 1.16 \alpha \approx 1.16 α≈1.16 的时候取到的:
mu = 1.7
sigma = 0.2
n_bins = 50
np.random.seed(3197747)
height = np.random.normal(mu, sigma, n_bins)
plt.hist(height, n_bins, density=True, histtype='step', cumulative=True)
plt.axis([1.3, 2.0, 0, 1])
plt.xticks([1.4, 1.5, 1.6, 1.7, 1.8, 1.9])
plt.xlabel('Height')
plt.ylabel('Probability')
plt.show()
lmbda_list = [0.5, 1, 1.5]
x = 1 - np.random.random(10000)
fig, ax = plt.subplots()
for lmbda in lmbda_list:
# y = [(1 - np.e ** (-1 * lmbda * x_)) for x_ in x[:]]
y = [-math.log(x_)/lmbda for x_ in x]
label = '$\lambda = $' + str(lmbda)
ax.plot(sorted(y), label=label)
plt.title('Quantile Function')
plt.xticks(np.arange(0, 10001, 2000), ('0', '0.2', '0.4', '0.6', '0.8',
'1'))
plt.xlabel('$P(X \leq x)$')
plt.ylabel('$x$')
plt.legend()
plt.show()
# Probability Density Function
lmbda_list = [0.5, 1, 1.5]
x = np.arange(0, 10, 0.001)
fig, ax = plt.subplots()
for lmbda in lmbda_list:
y = [(lmbda * np.e ** (-1 * lmbda * x_)) for x_ in x[:]]
label = '$\lambda = $' + str(lmbda)
ax.plot(x, y, label=label)
plt.title('Probability Density Function')
plt.xlabel('$x$')
plt.ylabel('$P(x)$')
plt.legend()
plt.show()
# CDF
lmbda_list = [0.5, 1, 1.5]
x = np.arange(0, 12, 0.001)
fig, ax = plt.subplots()
for lmbda in lmbda_list:
y = [(1 - np.e ** (-1 * lmbda * x_)) for x_ in x[:]]
label = '$\lambda = $' + str(lmbda)
ax.plot(x, y, label=label)
plt.title('Cumulative Distribution Function')
plt.xlabel('$x$')
plt.ylabel('$P(X \leq x$')
plt.legend()
plt.show()
# PDF
fig, ax = plt.subplots()
alpha = [1, 2, 3]
x_m = [1, 1, 2]
for i in range(len(alpha)):
x = np.arange(x_m[i], 10, 0.001)
y = [(alpha[i]*pow(x_, alpha[i])/(pow(x_, alpha[i]+1))) for x_ in x]
label = '$x_m = ' + str(x_m[i]) + ' ,\\alpha = $' + str(alpha[i])
ax.plot(x, y, label=label)
plt.xlabel('$x$')
plt.ylabel('$Pr[X = x]$')
plt.title('PDF')
plt.xticks(np.arange(0, 11))
plt.legend()
plt.show()
# CDF
fig, ax = plt.subplots()
alpha = [1, 2, 3]
x_m = [1, 1, 2]
for i in range(len(alpha)):
np.random.seed(3197747)
x = 1 - np.random.random(10000)
# reverse function
y = [(alpha[i] * pow(x_m[i], alpha[i]) / x_) ** (1 / (alpha[i] + 1))
for x_ in x]
label = '$x_m = ' + str(x_m[i]) + ' ,\\alpha = $' + str(alpha[i])
ax.hist(y, len(y), cumulative=True, density=True, histtype='step',
label=label)
plt.xlim(0, 5)
plt.xlabel('$x$')
plt.ylabel('$Pr[X < x]$')
plt.title('Pareto Distribution CDF')
plt.legend(loc=2)
plt.show()