浅析Python中的随机采样和概率分布


Posted in Python onDecember 06, 2021

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

1. random.choice

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

import random
res1 = random.choice([0, 1, 2, 3, 4])
print(res1) # 3

2. random.choices(有放回)

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

random.choices(population, weights=None, *, cum_weights=None, k=1)

population: 欲采样的序列

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

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

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

res2 = random.choices([0, 1, 2, 3, 4], weights=[10, 0, 30, 60, 0], k=3)
# 注意population不是关键字参数,在函数调用时不能写成population=[0,1,2,3,4]来传参
# 关于关键字参数和位置参数,可以参看我的博客《Python技法2:函数参数的进阶用法》https://www.cnblogs.com/orion-orion/p/15647408.html
print(res2) # [3, 3, 2]

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

res3 = random.choices([0, 1, 2, 3, 4], cum_weights=[10, 10, 40, 100, 100], k=3)
print(res3) # [0, 3, 3]

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

3. numpy.sample(无放回)

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

random.sample(population, k, *, counts=None)¶

population: 欲采样的序列

k: 采样元素个数

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

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

res3 = random.sample([0, 1, 2, 3, 4], k=3)
print(res3) # [3, 2, 1]

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

res4 = random.sample([0, 1, 2, 3, 4], k=3, counts=[1, 2, 2, 2, 1])
print(res4) # [3, 2, 2]

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

4.rng.choices 和 rng.sample

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

rng_seed = 1234
rng = random.Random(rng_seed)
res5 = rng.choices(
     population=[0,1,2,3,4],
     weights=[0.1, 0, 0.3, 0.6, 0],
     k=3,
)
print(res5) # [3, 3, 0]

res6 = rng.sample(
     population=[0, 1, 2, 3, 4],
     k=3,
)
print(res6) # [4, 0, 2]

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

def sample_clients(self):
        """
        sample a list of clients without repetition

        """
        rng_seed = (seed if (seed is not None and seed >= 0) else int(time.time()))
        self.rng = random.Random(rng_seed)

        if self.sample_with_replacement:
            self.sampled_clients = \
                self.rng.choices(
                    population=self.clients,
                    weights=self.clients_weights,
                    k=self.n_clients_per_round,
                )
        else:
            self.sampled_clients = self.rng.sample(self.clients, k=self.n_clients_per_round)

5. numpy.random.choices

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

random.choice(a, size=None, replace=True, p=None)

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

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

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

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

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

import numpy as np
res1 = np.random.choice(5, 3, replace=True)
print(res1) # [1 1 4]

res2 = np.random.choice(5, 3, replace=False)
print(res2) # [2 1 4]

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

res3 = np.random.choice(5, 3, p=[0.1, 0, 0.3, 0.6, 0])
print(res3)  # [2 3 3]

res4 = np.random.choice(5, 3, replace=False, p=[0.1, 0, 0.3, 0.6, 0])
print(res4) # [3 2 0]

参考文献

https://github.com/omarfoq/FedEM

https://www.python.org/

https://numpy.org/

到此这篇关于浅析Python中的随机采样和概率分布的文章就介绍到这了,更多相关Python内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
深入解析Python设计模式编程中建造者模式的使用
Mar 02 Python
Python使用PIL库实现验证码图片的方法
Mar 11 Python
python利用rsa库做公钥解密的方法教程
Dec 10 Python
对pandas中apply函数的用法详解
Apr 10 Python
python f-string式格式化听语音流程讲解
Jun 18 Python
Python 列表去重去除空字符的例子
Jul 20 Python
Django框架组成结构、基本概念与文件功能分析
Jul 30 Python
Spring实战之使用util:命名空间简化配置操作示例
Dec 09 Python
Python填充任意颜色,不同算法时间差异分析说明
May 16 Python
将tf.batch_matmul替换成tf.matmul的实现
Jun 18 Python
使用Python webdriver图书馆抢座自动预约的正确方法
Mar 04 Python
pandas DataFrame.shift()函数的具体使用
May 24 Python
python程序的组织结构详解
Python中异常处理用法
Nov 27 #Python
python中的3种定义类方法
Nov 27 #Python
5道关于python基础 while循环练习题
Nov 27 #Python
Python中的pprint模块
Nov 27 #Python
python 多态 协议 鸭子类型详解
Nov 27 #Python
Python机器学习实战之k-近邻算法的实现
You might like
PHP+SQL 注入攻击的技术实现以及预防办法
2011/01/27 PHP
thinkPHP5框架中widget的功能与用法详解
2018/06/11 PHP
Javascript Boolean、Nnumber、String 强制类型转换的区别详细介绍
2012/12/13 Javascript
jquery.blockUI.js上传滚动等待效果实现思路及代码
2013/03/18 Javascript
jQuery模拟黑客帝国矩阵效果实例
2015/06/28 Javascript
JavaScript计算某一天是星期几的方法
2015/08/05 Javascript
前端开发之CSS原理详解
2017/03/11 Javascript
phantomjs导出html到pdf的方法总结
2017/10/19 Javascript
浅析node应用的timing-attack安全漏洞
2018/02/28 Javascript
如何把vuejs打包出来的文件整合到springboot里
2018/07/26 Javascript
vue自定义全局共用函数详解
2018/09/18 Javascript
Vue项目中最新用到的一些实用小技巧
2018/11/06 Javascript
vue基础之v-bind属性、class和style用法分析
2019/03/11 Javascript
利用es6 new.target来对模拟抽象类的方法
2019/05/10 Javascript
[02:38]DOTA2超级联赛专访Loda 认为IG世界最强
2013/05/27 DOTA
Windows下Python使用Pandas模块操作Excel文件的教程
2016/05/31 Python
利用TensorFlow训练简单的二分类神经网络模型的方法
2018/03/05 Python
python 获取list特定元素下标的实例讲解
2018/04/09 Python
django框架面向对象ORM模型继承用法实例分析
2019/07/29 Python
Python 动态导入对象,importlib.import_module()的使用方法
2019/08/28 Python
python调用Matplotlib绘制分布点图
2019/10/18 Python
matplotlib.pyplot.matshow 矩阵可视化实例
2020/06/16 Python
如何利用Python给自己的头像加一个小国旗(小月饼)
2020/10/02 Python
Selenium关闭INFO:CONSOLE提示的解决
2020/12/07 Python
美国女性服饰销售网站:Nasty Gal(坏女孩)
2016/07/26 全球购物
linux面试题参考答案(2)
2015/12/06 面试题
营销主管自我评价怎么写
2013/09/19 职场文书
大专生自我评价
2014/01/28 职场文书
技术总监管理岗位职责
2014/03/09 职场文书
搞笑婚礼主持词
2014/03/13 职场文书
廉洁家庭事迹材料
2014/05/15 职场文书
学生穿着不得体检讨书
2014/10/12 职场文书
幼儿园班级管理心得体会
2016/01/07 职场文书
TV动画《八十龟酱观察日记》第四季宣传PV公布
2022/04/06 日漫
MySQL数据库如何使用Shell进行连接
2022/04/12 MySQL
SpringBoot Http远程调用的方法
2022/08/14 Java/Android