资讯专栏INFORMATION COLUMN

经典算法:随机抽样

awesome23 / 957人阅读

摘要:最近发现两个比较有意思的随机抽样算法,分享一下随机抽样且保持有序需求一家公司购买了他们的第一批电脑,该公司的业务主要是民意调查,现在要开发一个程序程序的输入是选区名列表以及整数,输出是随机选择的个选区名列表。

最近发现两个比较有意思的随机抽样算法,分享一下

1. 随机抽样且保持有序

需求:

一家公司购买了他们的第一批电脑,该公司的业务主要是民意调查,现在要开发一个程序:程序的输入是选区名列表以及整数 m,输出是随机选择的 m 个选区名列表。通常选区名有几百个,m 通常在 20 ~ 40。

程序描述:

程序的输入包含两个整数 m 和 n,其中 m

简单点来说,就是有 n 个数, 随机取 m 个,并保持有序。

解法:

我们知道了 n 和 m,轮流判断 n 个数组成的列表中每个数的概率(m/n),每次判断后n=n-1,若当前被判断的数被选择,则m=m-1,否则 m 不变。

假设 5 个数选 2 个,那么意味着每个数的概率都是 2/5 。我们以 2/5 的概率去判断第 1 个数,那么结果有两种,选择1,不选择。当判断第 2 个的时候,在以选择了第 1 个数的情况下,选择 2 的概率是 (2-1)/(5-1)=1/4,在以没选择第 1 个数的情况下,选中 2 的概率是 2/(5-1)=2/4,所以第二个数的概率:(2/5)*(1/4) + (3/5)*(2/4) = 2/5。第二个数的概率和第一个数的概率相等。

证明:

实现:

# Python
import random
# 抽样,从n个中抽m个
def sampling(lists, m, n=None):
    selected = []
    if n is None:
        n = len(lists)
    remaining = n-1
    for i in range(n):
        # random.random()返回 0 ~ 1的随机数
        if random.random() * remaining < m:
            selected.append(lists[i])
            m -= 1
        remaining -= 1
    return selected
# test
lists = [i for i in range(10)]
print sampling(lists, 3)
# 结果
>>>[4, 5, 7]
2. 在不知道总数的情况下随机选一个
如何从 n 个对象(可以依次看到这 n 个对象,但事先不知道 n 的值)中随机选取一个?例如,如何在事先不知道文本行数的情况下读取该文件,从中随机选择并输出一行?

解法:

我们先设一个变量叫selected,选择第 1 行赋值给 selected,并以 1/2 的概率选择第 2 行并重新赋值给selected, 以 1/3 的概率选择第 3 行并重新赋值给selected。在这以过程结束时, 每一行的选中概率都是相等的(都是 1/n, 其中 n 是文件的总行数)

要证明这个概率可以从最后一行算起,设最后一行的概率为P(n)=1/n, 倒数第二行的概率为P(n-1)=(1-P(n))*(1/(n-1)) = 1/n,倒数第m-1行概率为:

代码:

# Python
import random

def getRandLine(text):
    i = 1
    selected = ""
    for line in text.splitlines():
        if (random.random() < (1.0/i)):
            selected = line
        i += 1
    return selected
# test
text = """
line1
line2
line3
line4
line5
line6
line7
line8
line9
line10
""" 
print getRandLine(text)
# 结果
>>>line9
参考: 编程珠玑

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42828.html

相关文章

  • 用Python写算法 | 蓄水池算法实现随机抽样

    摘要:输出的结果如下上面输出了每个数字被取样到的次数,通过图表可以清晰的看到分布情况可以看出蓄水池算法对于随机抽样还是非常适合的,每个元素的抽样概率都相同。 showImg(https://segmentfault.com/img/remote/1460000015901186); 现在有一组数,不知道这组数的总量有多少,请描述一种算法能够在这组数据中随机抽取k个数,使得每个数被取出来的概率...

    陈伟 评论0 收藏0
  • Appboy 基于 MongoDB 的数据密集型实践

    摘要:相反,这些数来源于统计抽样,统计抽样通过抽样小部分群体来获得更大群体的特征。但调查机构的报告与统计也经常带有所谓的置信区间,也称为偏差。在进行一个多变量测试时,消息推送的目标是测试全体,但是同一细分中的其他用户不会收到该条消息。 摘要:Appboy 正在过手机等新兴渠道尝试一种新的方法,让机构可以与顾客建立更好的关系,可以说是市场自动化产业的一个前沿探索者。在移动端探索上,该公司已经取...

    jindong 评论0 收藏0
  • 关于深度学习(deep learning)

    摘要:在每一层学习到的结果表示作为下一层的输入用监督训练来调整所有层加上一个或者更多的用于产生预测的附加层当前,国外在这方面的研究就是三分天下的局面,的与微软合作,的和合作,以及的计算机科学家和。深度学习的入门材料。 转载自:http://doctorimage.cn/2013/01/04/%e5%85%b3%e4%ba%8e%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0...

    ZweiZhao 评论0 收藏0

发表评论

0条评论

awesome23

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<