蓄水池抽样

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

1. 蓄水池的容积为1

(1)问题

如何随机从n个对象中选择一个对象,这n个对象是按序排列的,但是在此之前你不知道n的值?

(2)算法与证明

算法:我们先将第一个对象作为备选放入蓄水池,也就是说第一个对象被放入蓄水池的概率为1,以1/21/21/2的概率选择第二个,以1/31/31/3的概率选择第三个,以此类推,以1/m1/m1/m的概率选择第m个对象。当该过程结束时,每一个对象具有相同的选中概率,即1/n1/n1/n

证明:第m个对象最终被选中的概率P=选择m的概率*其后面所有对象不被选择的概率,即

P=1m×(mm+1×m+1m+2×⋅⋅⋅×n−1n)=1nP=\frac{1}{m}\times(\frac{m}{m+1}\times\frac{m+1}{m+2}\times···\times\frac{n-1}{n})=\frac{1}{n}P=m1×(m+1m×m+2m+1××nn1)=n1

由于这里处理的对象是以流的形式出现的,所以当第m个对象出现时,在已有的数据中选中第m个对象的概率为1m\frac{1}{m}m1,当第m+1个对象出现时没选中第m+1个对象的概率为mm+1\frac{m}{m+1}m+1m,以此类推。

所以在实际问题的处理中,只需要对每个新增的对象按照1m\frac{1}{m}m1的概率来选择就好了。

(3)代码实现

假设我们要在n行的文本文件中随机选取一行,但事先不知道n为多少,则代码如下:

m = 0
s = null
for line in 文本文件:
    m = m+1
    r = (0,1)之间的随机数
    if r < 1/m:
        s = line

2.蓄水池的容积为m

(1)问题

如何随机从n个对象中选择m个对象,这n个对象是按序排列的,但是在此之前你不知道n的值?

(2)算法与证明

前m个对象被选中的概率为1,当我们读到第i-1行时(i-1大于m),我们假设前i-1个对象被选中的概率均为mi−1\frac{m}{i-1}i1m,那么,当我们读到第i行的时候,前i-1行中每一行被选中的概率为上一次被选中的概率乘以这一次没有被选中的概率,即为
P=mi−1×(1−mi×1m)=kiP=\frac{m}{i-1}\times(1-\frac{m}{i}\times\frac{1}{m})=\frac{k}{i}P=i1m×(1im×m1)=ik

(3)代码

i = 0
s = []
for line in 文本文件:
    i = i+1
    if i <= m:
        s.append(line)
    else:
        j = [1,i]之间的随机数
        if j <= m:
            s[j] = line

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

加权蓄水池抽样是在普通蓄水池抽样基础上,考虑每个元素的权重来进行抽样的方法,以满足不同元素被选中概率不同的需求。 ### 原理 每个数据被选中的概率 \(P_i = \frac{w_i}{W}\),其中 \(W = \sum_{j=1}^{N} w_j\) (\(N\) 为总数据量),\(w_i\) 是第 \(i\) 个元素的权重。这意味着元素的权重越大,被选中的概率就越高[^4]。 ### 算法 以 Go 语言为例,以下是加权蓄水池抽样的算法实现: ```go type WeightedItem struct { Value interface{} // 可以是任意类型的数据 Weight float64 // 权重值(必须为正数) } func WeightedReservoirSample(stream <-chan WeightedItem, k int) []WeightedItem { if k <= 0 { return nil } rand.Seed(time.Now().UnixNano()) reservoir := make([]WeightedItem, k) totalWeight := 0.0 i := 0 for item := range stream { if i < k { reservoir[i] = item totalWeight += item.Weight i++ continue } // 对于后续元素,按权重概率决定是否替换 totalWeight += item.Weight prob := item.Weight / totalWeight if rand.Float64() < prob { reservoir[rand.Intn(k)] = item } } return reservoir[:i] // 如果数据不足k个,返回实际数量 } ``` 该算法首先初始化一个大小为 \(k\) 的蓄水池,将前 \(k\) 个元素放入其中,并计算总权重。对于后续元素,根据其权重计算被选中替换蓄水池中某个元素的概率,若满足条件则进行替换[^4]。 ### 应用 加权蓄水池抽样在多个领域有广泛应用。在处理大数据集时,可用于分层抽样,根据不同层的重要性设置不同的权重,从而更合理地抽取样本。在实际任务中,能解决搜索 query 抽样、商品抽样、网页抽样等问题。例如在搜索 query 抽样中,可根据每个 query 的热门程度设置权重,热门 query 被选中的概率更高,以便更有针对性地进行分析[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

comli_cn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值