1 概率分布概述
-
共轭意味着它有共轭分布的关系。
在贝叶斯概率论中,如果后验分布 p(θx)与先验概率分布 p(θ)在同一概率分布族中,则先验和后验称为共轭分布,先验称为似然函数的共轭先验。
-
多分类表示随机方差大于 2。
-
n 次意味着我们也考虑了先验概率 p(x)。
2 分布概率与特征
2.1 均匀分布(连续)
均匀分布在 [a,b] 上具有相同的概率值,是简单概率分布。
示例代码:
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), (10, 20)]:
a, b = ls[0], ls[1]
x, y, u, s = uniform(x, a, b)
plt.plot(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
plt.legend()
plt.show()
运行代码显示:
2.2 伯努利分布(离散)
-
先验概率 p(x)不考虑伯努利分布。因此,如果我们对最大似然进行优化,那么我们很容易被过度拟合。
-
利用二元交叉熵对二项分类进行分类。它的形式与伯努利分布的负对数相同。
示例代码:
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))
plt.legend()
plt.show()
运行代码显示:
2.3 二项分布(离散)
-
参数为 n 和 p 的二项分布是一系列 n 个独立实验中成功次数的离散概率分布。
-
二项式分布是指通过指定要提前挑选的数量而考虑先验概率的分布。
示例代码:
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)]
return y, np.mean(y), np.std(y)
for ls in [(0.5, 20), (0.7, 40), (0.5, 40)]:
p, n_experiment = ls[0], ls[1]
x = np.arange(n_experiment)
y, u, s = binomial(n_experiment, p)
plt.scatter(x, y, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
plt.legend()
plt.show()
运行代码显示:
2.4 多伯努利分布,分类分布(离散)
-
多伯努利称为分类分布。
-
交叉熵和采取负对数的多伯努利分布具有相同的形式。
示例代码:
import random
import numpy as np
from matplotlib import pyplot as plt
def categorical(p, k):
return p[k]
n_experiment = 100
p = [0.2, 0.1, 0.7]
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, label=r'$\mu=%.2f,\ \sigma=%.2f$' % (u, s))
plt.legend()
plt.show()
运行代码显示:
2.5 多项式分布(离散)
多项式分布与分类分布的关系与伯努尔分布与二项分布的关系相同。
示例代码:
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.show()
运行代码显示:
2.6 β分布(连续)
-
β分布与二项分布和伯努利分布共轭。
-
利用共轭,利用已知的先验分布可以更容易地得到后验分布。
-
当β分布满足特殊情况(α=1,β=1)时,均匀分布是相同的。
示例代码:
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.show()
运行代码显示:
2.7 Dirichlet 分布(连续)
-
dirichlet 分布与多项式分布是共轭的。
-
如果 k=2,则为β分布。
示例代码:
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.show()
运行代码显示:
2.8 伽马分布(连续)
-
如果 gamma(a,1)/gamma(a,1)+gamma(b,1)与 beta(a,b)相同,则 gamma 分布为β分布。
-
指数分布和卡方分布是伽马分布的特例。
代码示例:
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.show()
运行代码显示:
2.9 指数分布(连续)
指数分布是 α 为 1 时 γ 分布的特例。
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 [0.5, 1, 1.5]:
x = np.arange(0, 20, 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.show()
运行代码显示
2.10 高斯分布(连续)
高斯分布是一种非常常见的连续概率分布。
示例代码:
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(-100, 100) # 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.show()
运行代码显示:
2.11 标准正态分布(连续)
标准正态分布为特殊的高斯分布,平均值为 0,标准差为 1。
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(-100, 100) # 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.show()
运行代码显示:
2.12 卡方分布(连续)
-
k 自由度的卡方分布是 k 个独立标准正态随机变量的平方和的分布。
-
卡方分布是 β 分布的特例
示例代码:
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.show()
运行代码显示
2.13 t 分布(连续)
t 分布是对称的钟形分布,与正态分布类似,但尾部较重,这意味着它更容易产生远低于平均值的值。
示例代码:
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, 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.show()
运行代码显示