Hadoop简单随机采样

基于Hadoop的两种随机采样模式
博客介绍基于Hadoop的两种采样模式,即随机百分比采样和随机抽取固定容量样本。随机百分比采样是对每条数据用随机数生成器产生[0,1]随机数,与阈值比较决定取舍,再用恒等reducer合并;固定容量样本则用堆维护,最后通过单个reducer重新抽取。

(注:内容来自《Hadoop数据分析》)

基于Hadoop的两种采样模式:百分比采样和N样本采样。

1.随机百分比采样:

从样本中随机抽取一个比例的样本,一种方法是对每条数据简单地使用随机数生成器来产生[0,1]上均匀分布的随机数,并将其与期望的阈值大小进行比较,小于阈值的留下,大于阈值的跳过。

mapper.py

import random
# class Mapper可参考上一篇博客
class PercentSampleMapper(Mapper):

    def __init__(self,*args,**kwargs):
        self.percentage = kwargs.pop("percentage")
        super(PercentSampleMapper,self).__init__(*args,**kwargs)

    def map(self):
        for _, val in self:
            if random.random() < self.percentage:
                self.emit(None,val)
    
    if __name__=='__main__':
        mapper = PercentSampleMapper(sys.stdin,percentage=0.2)
        mapper.map 

接着,使用一个恒等reducer合并数据

2.随机抽取固定容量样本:

仍然对每条数据产生一个[0,1]上的均匀分布,然后通过堆维护一个容量为n的样本。

import random,heapd

class SampleMapper(Mapper):

    def __init__(self,n,*args,**kwargs):
        self.n = n
        super(SampleMapper,self).__init__(*args,**kwargs)
    
    def map(self):
        heap = [0]*self.n

        for value in self:
            #heappushpop 如存在random.random()>heap中的某值,则将heap中最小值弹出,并将random.random()随机插入到heap
            heapd.heappushpop(heap,(random.random(),value))
            for item in heap:
                self.emit(None,item)

class SampleReducer(Mapper):
    
    def __init__(self,n,*args,**kwargs):
        self.n = n
        supper(SampleReducer,self).__init__(*args,**kwargs)

    def reduce(self):
        heap = [0]*self.n

        for _,value in self:
            for value in values:
                heapd.heappushpop(heap,make_tuple(value))

        for item in heap:
            self.emit(None,item[1])

该方法获得的样本数是mapper的数量的n倍,通过单个reducer对数据重新抽取。

### Hadoop 中实现蒙特卡洛算法 在 Hadoop 的生态系统中,可以利用其分布式计算框架 MapReduce 来实现蒙特卡洛方法。通过将大规模随机采样任务分解到多个节点上执行,能够显著提升效率并缩短运行时间。 #### 蒙特卡洛算法的核心思想 蒙特卡洛算法是一种基于概率统计的方法,它通过对大量随机样本的模拟来逼近问题的真实解[^2]。例如,在估算圆周率 π 时,可以通过向单位正方形内均匀投掷点,并判断这些点是否落在内切圆内部的比例来进行近似计算。 #### Hadoop 实现蒙特卡洛算法的关键组件 Hadoop 是一个强大的大数据处理平台,主要由以下几个核心模块构成: - **HDFS (Hadoop Distributed File System)**: 提供分布式的存储能力,支持海量数据的高效读写操作[^3]。 - **MapReduce**: 借助于函数式编程的思想,提供了一种高层次的抽象模型用于解决复杂的大规模数据分析问题[^4]。 具体来说,可以在 Map 阶段生成大量的随机数作为输入样本;而在 Reduce 阶段则负责汇总各个子任务的结果以得出最终估计值。 以下是使用 Java 编写的简单示例程序展示如何借助 Hadoop 平台完成上述过程: ```java // Mapper 类定义 public static class PiMapper extends Mapper<LongWritable, Text, NullWritable, DoubleWritable> { private Random random = new Random(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { double x = random.nextDouble(); // 随机生成横坐标 double y = random.nextDouble(); // 随机生成纵坐标 if ((x * x + y * y) <= 1) { // 判断该点是否位于单位圆内 context.write(NullWritable.get(), new DoubleWritable(1.0)); } else { context.write(NullWritable.get(), new DoubleWritable(0.0)); } } } // Reducer 类定义 public static class PiReducer extends Reducer<NullWritable, DoubleWritable, NullWritable, DoubleWritable> { int totalPointsInsideCircle = 0; int totalCounts = 0; @Override protected void reduce(NullWritable key, Iterable<DoubleWritable> values, Context context) throws IOException, InterruptedException { for (DoubleWritable val : values) { totalCounts++; if (val.get() == 1.0) { totalPointsInsideCircle++; } } double estimatedPiValue = 4.0 * totalPointsInsideCircle / totalCounts; // 计算π值 context.write(NullWritable.get(), new DoubleWritable(estimatedPiValue)); } } ``` 此代码片段展示了如何构建一个基本的地图还原器结构来执行 Monte Carlo 方法的任务分配与结果收集工作流程。 #### 运行命令 要启动这个应用程序,请按照如下方式调用 `hadoop` 命令: ```bash hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar pi <numMappers> <numSamples> ``` 其中 `<numMappers>` 表示使用的映射器数量,而 `<numSamples>` 定义总的抽样次数[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值