python加权随机_加权随机采样 (Weighted Random Sampling)

一个集合里有 n 个元素,每个元素有不同的权重,现在要不放回地随机抽取 m 个元素,每个元素被抽中的概率为元素的权重占总权重的比例。要怎么做呢?

现在考虑只抽取一个元素,假设权重之和为 1 。我们可以从 [0, 1] 中随机得到一个权重,假设为 0.71 ,而后从第一个元素开始,不断累加它们的权重,直到有一个元素的累加权重包含 0.71 ,则选取该元素。下面是个示意图:

要选取 m 个元素,则可以按上面的方法先选取一个,将该元素从集合中去除,再反复按上面的方法抽取剩余的元素。这种方法的复杂度是 O(mn) ,并且将元素从集合中删除其实不太方便实现。

当然,最重要的是这个算法需要多次遍历数据,不适合用在流处理的场景中。

Algorithm A 是论文 Weighted Random Sampling 中提出的,步骤如下:

对于集合 $V$ 中的元素 $v_i \in V$,选取均匀分布的随机数 $u_i = rand(0, 1)$ ,计算元素的特征 $k_i = u_i^{(1/w_i)}$

将集合按 $k_i$ 排序,选取前 $m$ 大的元素。

算法的正确性在作者 2006 年的论文 Weighted random sampling with a reservoir 里给了详细的证明。论文中给出了算法的两个变种 A-Res 与 A-ExpJ,它们都能在一次扫描中得到 m 个样本。非常适合在流处理的场合中。

A-Res(Algorithm A With a Reservoir) 是 Algorithm 的“蓄水池”版本,即维护含有 m 个元素的结果集,对每个新元素尝试去替换结果集中权重最小的元素。步骤如下:

将集合 $V$ 的前 $m$ 个元素放入结果集合 $R$。

对于结果集里的每个元素,计算特征值 $k_i = u_i^{(1/w_i)}$,其中 $u_i = rand(0, 1)$

对 $i = m+1, m+2, \dots, n$ 重复步骤 4 ~ 6

将结果集中最小的特征 $k$ 作为当前的阈值 $T$

对于元素 $v_i$,计算特征 $k_i = u_i^{(1/w_i)}$,其中 $u_i = rand(0, 1)$

如果 $k_i > T$ 则将 $R$ 中拥有最小 $k$ 值的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值