飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

Python中的随机采样和概率分布(二)

时间:2021-12-07  作者:orion-orion  
Python中的随机采样和概率分布(二)在上一篇博文《Python中的随机采样和概率分布(一)》中,我们介绍了Python中最简单的随机采样函数。接下来我们更进一步,来看看如何从一个概率分布中采样,我们以几个机器学习中最常用的概率分布为例,包括二项(binomial)分布/伯努利(Bernoulli)分布、多项(multinomial)分布、均匀(uniform)分布和狄利克雷(Dirichlet)分布。

在上一篇博文《Python中的随机采样和概率分布(一)》(链接:https://域名/orion-orion/p/域名)中,我们介绍了Python中最简单的随机采样函数。接下来我们更进一步,来看看如何从一个概率分布中采样,我们以几个机器学习中最常用的概率分布为例。

1. 二项(binomial)/伯努利(Bernoulli)分布

1.1 概率质量函数(pmf)

\[P(X = x;\space n, \space p)=\left(\begin{array}{c}n \\ x\end{array}\right) p^{x}(1-p)^{n-x}\\x=0,1,2,...n; \space 0\leqslant p \leqslant 1\]

当\(n=1\)时,则取到下列极限情况,是为参数为\(p\)的二项分布:

\[P(X = x;\space p)= p^{x}(1-p)^{1-x}\\x=0,1; \space 0\leqslant p \leqslant 1\]

二项分布\(P(X = x;\space n, \space p)\)可以表示进行独立重复试验\(n\)次,每次有两成功和失败可能结果(分别对应概率\(p\)和\(1-p\)),共成功\(x\)次的概率。

1.2 函数原型

域名mial(n, p, size=None)

参数:
n: int or array_like of ints   对应分布函数中的参数 n,>=0,浮点数会被截断为整形。
p: float or array_like of floats   对应分布函数参数\(p\), >=0并且<=1。
size: int or tuple of ints, optional   如果给定形状为\((m, n, k)\),那么\(m\times n \times k\)个随机样本会从中抽取。默认为None,即返回一个一个标量随机样本。

返回:
out: ndarray or scalar  从带参数的概率分布中采的随机样本,每个样本表示独立重复实验\(n\)次中成功的次数。

1.3 使用样例

设进行独立重复实验10次,每次成功概率为0.5,采样样本表示总共的成功次数(相当于扔10次硬币,正面朝上的次数)。总共采20个样本。

import numpy as npn, p = 10, .5 s = 域名mial(n, p, 20)print(s) # [4 5 6 5 4 2 4 6 7 2 4 4 2 4 4 7 6 3 5 6]

可以粗略的看到,样本几乎都在5周围上下波动。
我们来看一个有趣的例子。一家公司钻了9口井,每口井成功的概率为0.1,所有井都失败了,发生这种情况的概率是多少?
我们总共采样2000次,来看下产生0结果的概率。

s = sum(域名mial(9, 0.1, 20000) == 0)/域名t(s) # 域名

可见,所有井失败的概率为域名,这个概率还是蛮大的。

2. 多项(multinomial)分布

2.1 概率质量函数(pmf)

\[P(\bm{X} = \bm{x};\space n, \space \bm{p})=\frac{n !}{x_{1} ! \cdots x_{k} !} p_{1}^{x_{1}} \cdots p_{k}^{x_{k}}\\\bm{x}=(x_1, x_2, ..., x_k), x_i \in \{0, ..., n\}, \space \sum_{i}{x_i}=n; \\\bm{p}=(p_1, p_2, ..., p_k), 0\leqslant p_i \leqslant 1, \space \sum_{i}{p_i}=1\]

当\(k=2\)时,则取到下列极限情况,是为参数为\(n\),\(p\)的二项分布:

\[P(X = x;\space n, \space p)=\frac{n !}{x !(n-x) !} p^{x}(1-p)^{n-x}\\x=0,1,2,...n; \space 0\leqslant p \leqslant 1\]

也就是说,多项分布式二项分布的推广:仍然是独立重复实验\(n\)次,但每次不只有成功和失败两种结果,而是\(k\)种可能的结果,每种结果的概率为\(p_i\)。多项分布是一个随机向量的分布,\(\bm{x}=(x_1, x_2, ..., x_k)\)意为第\(i\)种结果出现\(x_i\)次,\(P(\bm{X} = \bm{x};\space n, \space p)\)也就表示第\(i\)种结果出现\(x_i\)次的概率。

2.2 函数原型

域名inomial(n, pvals, size=None)

参数:
n: int   对应分布函数中的参数 n
pvals: sequence of floats   对应分布函数参数\(\bm{p}\), 其长度等于可能的结果数\(k\),并且有\(0 \leqslant p_i \leqslant 1\)。
size: int or tuple of ints, optional   为输出形状大小,因为采出的每个样本是一个随机向量,默认最后一维会自动加上\(k\),如果给定形状为\((m, n)\),那么\(m\times n\)个维度为\(k\)的随机向量会从中抽取。默认为None,即返回一个一个\(k\)维的随机向量。

返回:
out: ndarray   从带参数的概率分布中采的随机向量,长度为可能的结果数\(k\),如果没有给定size,则shape为(k,)

2.3 使用样例

设进行独立重复实验20次,每次情况的概率为1/6,采样出的随机向量表示每种情况出现次数(相当于扔20次六面骰子,点数为0, 1, 2, ..., 5出现的次数)。总共采1个样本。

s = 域名inomial(20, [1/6.]*6, size=1)print(s) # [[4 2 2 3 5 4]]

当然,如果不指定size,它直接就会返回一个一维向量了

s = 域名inomial(20, [1/6.]*6)print(s) # [4 1 4 3 5 3]

如果像进行多次采样,改变size即可:

s = 域名inomial(20, [1/6.]*6, size=(2, 2))print(s)# [[[4 3 4 2 6 1]# [5 2 1 6 3 3]]# [[5 4 1 1 6 3]# [2 5 2 5 4 2]]]

这个函数在论文<sup>[1]</sup>的实现代码<sup>[2]</sup>中用来设置每一个client分得的样本数:

for cluster_id in range(n_clusters): weights = 域名chlet(alpha=alpha * 域名(n_clients)) clients_counts[cluster_id] = 域名inomial(clusters_sizes[cluster_id], weights) # 一共扔clusters_sizes[cluster_id]次筛子,该函数返回骰子落在某个client上各多少次,也就对应着该client应该分得的样本数

3.均匀(uniform)分布

3.1 概率密度函数(pdf)

\[p(x; \space a, \space b)=\frac{1}{b-a}\]

均匀分布可用于随机地从连续区间\([a, b)\)内进行采样。

3.2 函数原型

域名orm(low=0.0, high=1.0, size=None)

参数:
low: float or array_like of floats, optional   对应分布函数中的下界参数 a,默认为0。
high: float or array_like of floats   对应分布函数中的下界参数 b,默认为1.0。
size: int or tuple of ints, optional   为输出形状大小,如果给定形状为\((m, n, k)\),那么\(m\times n\times k\)的样本会从中抽取。默认为None,即返回一个单一标量。

返回:
out: ndarray or scalar   从带参数的均匀分布中采的随机样本

3.3 使用样例

s = 域名orm(-1,0,10)print(s)# [-域名594 -域名8902 -域名4099 -域名407 -域名5644 -域名8294# -域名6197 -域名6765 -域名9953 -域名4785]

4. 狄利克雷(Dirichlet)分布

4.1 概率密度函数(pdf)

\[P(\bm{x}; \bm{\alpha}) \propto \prod_{i=1}^{k} x_{i}^{\alpha_{i}-1} \\\bm{x}=(x_1,x_2,...,x_k),\quad x_i > 0 , \quad \sum_{i=1}^k x_i = 1\\\bm{\alpha} = (\alpha_1,\alpha_2,..., \alpha_k). \quad \alpha_i > 0\]

4.2 函数原型

域名chlet(alpha, size=None)

参数:
alpha: sequence of floats, length k   对应分布函数中的参数向量 \(\alpha\),长度为\(k\)。
size: int or tuple of ints, optional   为输出形状大小,因为采出的每个样本是一个随机向量,默认最后一维会自动加上\(k\),如果给定形状为\((m, n)\),那么\(m\times n\)个维度为\(k\)的随机向量会从中抽取。默认为None,即返回一个一个\(k\)维的随机向量。

返回:
out: ndarray   采出的样本,大小为\((size, k)\)。

4.3 使用样例

设\(\bm{\alpha}=(10, 5, 3)\)(意味着\(k=3\)),\(size=(2, 2)\),则采出的样本为\(2\times 2\)个维度为\(k=3\)的随机向量。

s = 域名chlet((10, 5, 3), size=(2, 2))print(s)# [[[域名7647 域名0451 域名1902]# [域名1077 域名409 域名4833]]# [[域名3167 域名6547 域名0285]# [域名1943 域名9597 域名846 ]]]

这个函数在论文[1]的实现代码[2]中用来生成符合狄利克雷分布的权重向量

for cluster_id in range(n_clusters): # 为每个client生成一个权重向量,文章中分布参数alpha每一维都相同 weights = 域名chlet(alpha=alpha * 域名(n_clients)) clients_counts[cluster_id] = 域名inomial(clusters_sizes[cluster_id], weights)

参考文献

  • [1] Marfoq O, Neglia G, Bellet A, et al. Federated multi-task learning under a mixture of distributions[J]. Advances in Neural Information Processing Systems, 2021, 34.
  • [2]https://域名/omarfoq/FedEM
  • [3]https://域名/
  • [4]https://域名/

标签:Python编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。