浅析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 相关文章推荐
压缩包密码破解示例分享(类似典破解)
Jan 17 Python
python访问类中docstring注释的实现方法
May 04 Python
用Python计算三角函数之acos()方法的使用
May 15 Python
Python基础语言学习笔记总结(精华)
Nov 14 Python
python list是否包含另一个list所有元素的实例
May 04 Python
python环形单链表的约瑟夫问题详解
Sep 27 Python
python实现批量视频分帧、保存视频帧
May 31 Python
Django REST framework 分页的实现代码
Jun 19 Python
在django view中给form传入参数的例子
Jul 19 Python
python实现桌面托盘气泡提示
Jul 29 Python
Django Admin中增加导出Excel功能过程解析
Sep 04 Python
wxPython实现整点报时
Nov 18 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实现邮件群发的源码
2013/06/18 PHP
php在线解压ZIP文件的方法
2014/12/30 PHP
PHP基于MySQLI函数封装的数据库连接工具类【定义与用法】
2017/08/11 PHP
JavaScript入门教程(9) Document文档对象
2009/01/31 Javascript
代码触发js事件(click、change)示例应用
2013/12/13 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
JavaScript实现计算字符串中出现次数最多的字符和出现的次数
2015/03/12 Javascript
Javascript的表单验证-提交表单
2016/03/18 Javascript
js实现密码强度检测【附示例】
2016/03/30 Javascript
基于jQuery实现表格的查看修改删除
2016/08/01 Javascript
JS封装的选项卡TAB切换效果示例
2016/09/20 Javascript
JS根据生日月份和日期计算星座的简单实现方法
2016/11/24 Javascript
jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】
2017/03/21 jQuery
高性能的javascript之加载顺序与执行原理篇
2018/01/14 Javascript
vue element-ui 绑定@keyup事件无效的解决方法
2018/03/09 Javascript
Angular 容器部署的方法
2018/04/17 Javascript
vue-router传参用法详解
2019/01/19 Javascript
JS实现带阴历的日历功能详解
2019/01/24 Javascript
使用Angular自定义字段校验指令的方法示例
2019/02/01 Javascript
react 不用插件实现数字滚动的效果示例
2020/04/14 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
2020/11/07 Javascript
[01:36:17]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第一场 1月31日
2021/03/11 DOTA
Python简单定义与使用二叉树示例
2018/05/11 Python
python爬虫的数据库连接问题【推荐】
2018/06/25 Python
python3解析库pyquery的深入讲解
2018/06/26 Python
python实现将读入的多维list转为一维list的方法
2018/06/28 Python
PyQt5 窗口切换与自定义对话框的实例
2019/06/20 Python
python基于Selenium的web自动化框架
2019/07/14 Python
python装饰器原理与用法深入详解
2019/12/19 Python
python turtle工具绘制四叶草的实例分享
2020/02/14 Python
Python如何批量获取文件夹的大小并保存
2020/03/31 Python
英国首屈一指的票务公司:See Tickets
2019/05/11 全球购物
什么是serialVersionUID
2016/03/04 面试题
毕业生就业推荐表自我鉴定
2014/03/20 职场文书
CSS3 制作的悬停缩放特效
2021/04/13 HTML / CSS
用React Native制作一个简单的游戏引擎
2021/05/27 Javascript