天天看点

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

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

Python(包括其包Numpy)中包含了了许多概率算法,包括基础的随机采样以及许多经典的概率分布生成。我们这个系列介绍几个在机器学习中常用的概率函数。先来看最基础的功能——随机采样。它包括了random.choice、random.choices、numpy.random.choices等函数

Python(包括其包Numpy)中包含了了许多概率算法,包括基础的随机采样以及许多经典的概率分布生成。我们这个系列介绍几个在机器学习中常用的概率函数。先来看最基础的功能——随机采样。

如果我们只需要从序列里采一个样本(所有样本等概率被采),只需要使用<code>random.choice</code>即可:

当然,很多时候我们不只需要采一个数,而且我们需要设定序列中每一项被采的概率不同。此时我们可以采用<code>random.random.choices</code>函数, 该函数用于有放回的(即一个数据项可以被重复采多次)对一个序列进行采样。其函数原型如下:

<code>population</code>: 欲采样的序列

<code>weights</code>: 每个样本被赋予的权重(又称相对权重),决定每个样本被采的概率,如[10, 0, 30, 60, 0]

<code>cum_weights</code>: 累积权重,相对权重[10, 0, 30, 60, 0]相当于累积权重[10, 10, 40, 100, 100]

我们从<code>[0, 1, 2, 3, 4]</code>中按照相对权重采样3个样本如下:

从<code>[0, 1, 2, 3, 4]</code>中按照累积权重采样3和样本如下:

注意,相对权重<code>weights</code>和累计权重<code>cum_weights</code>不能同时传入,否则会报<code>TypeError</code>异常<code>'Cannot specify both weights and cumulative weights'</code>。

<code>random.sample</code>是无放回,如果我们需要无放回采样(即每一项只能采一次),那我们需要使用<code>random.sample</code>。需要注意的是,如果使用该函数,将无法定义样本权重。该函数原型如下:

<code>k</code>: 采样元素个数

<code>counts</code>: 用于population是可重复集合的情况,定义集合元素的重复次数。<code>sample(['red', 'blue'], counts=[4, 2], k=5)</code>等价于<code>sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)</code>

我们无放回地对序列<code>[0, 1, 2, 3, 4]</code>采样3次如下:

无放回地对可重复集合<code>[0, 1, 1, 2, 2, 3, 3, 4]</code>采样3次如下:

如果<code>counts</code>长度和<code>population</code>序列长度不一致,会抛出异常<code>ValueError</code>:<code>"The number of counts does not match the population"</code>。

还有一种有放回采样实现方法是我在论文[1]的代码[2]中学习到的。即先定义一个随机数生成器,再调用随机数生成器的<code>choices</code>方法或<code>sample</code>方法,其使用方法和<code>random.choice</code>/<code>random.sample</code>函数相同。

这两个函数在论文[1]的实现代码[2]中用来随机选择任务节点<code>client</code>:

从序列中按照权重分布采样也可以采用<code>numpy.random.choice</code>实现。其函数原型如下:

<code>a</code>: 1-D array-like or int   如果是1-D array-like,那么样本会从其元素中抽取。如果是int,那么样本会从<code>np.arange(a)</code>中抽取;

<code>size</code>: int or tuple of ints, optional   为输出形状大小,如果给定形状为\((m, n, k)\),那么\(m\times n\times k\)的样本会从中抽取。默认为None,即返回一个单一标量。

<code>replace</code>: boolean, optional   表示采样是又放回的还是无放回的。若<code>replace=True</code>,则为又放回采样(一个值可以被采多次),否则是无放回的(一个值只能被采一次)。

<code>p</code>: 1-D array-like, optional   表示<code>a</code>中每一项被采的概率。如果没有给定,则我们假定<code>a</code>中各项被采的概率服从均匀分布(即每一项被采的概率相同)。

从<code>[0,1,2,3,4,5]</code>中重复/不重复采样3次如下:

同样是<code>[0,1,2,3,4,5]</code>中重复/不重复采样3次,现在来看我们为每个样本设定不同概率的情况:

[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://github.com/omarfoq/FedEM

[3] https://www.python.org/

[4] https://numpy.org/

数学是符号的艺术,音乐是上界的语言。