`

MapReduce设计模式:Filtering

 
阅读更多

MapReduce设计模式:Filtering

 

在上一节中,我们学习了MapReduce的设计模式之一:Local Aggregation;这个更像是对MapReduce的优化,确保数据能够准确、快速、高效的运行。本节学习的Filtering模式则是从另外一个角度来看数据。

 

Filtering模式下,我们不是想改动源数据,只是想得到源数据的子集;该集合有可能很小,如TOP-K;也有可能很大,如数据去重。使用Filtering时,你肯定是很清楚业务功能,想从更高的层面去看待数据:从语料库里抽取最常用词、StackOverflow用户的访问轨迹、数据的代表性子集合等,这些都是从数据中抽取部分内容,从而能够更近的观察数据,这些在机器学习和数据挖掘中都是很常见的内容。

 

我们看下常用的Filtering使用案例:

事件跟踪:更具用户的IPID等来分析用户感兴趣的商品、感兴趣的话题、想了解的内容,以便在用户下次登录时能够向用户做内容推荐。

内容查询:分布式查找(Distributed grep)就是一个典型的使用案例

数据清洗:数据格式、完整性、内容缺失等,导致数据不可用,需要将这些数据过滤掉,在数据挖掘中是数据的很重要的预处理过程。

抽样:这个和概率上的抽样含义一致,就是想得到子集合。有人会有疑问,数据越多越好,为什么要抽样呢?处理百万级别的数据和处理亿万级别的数据,结果差别不到的话,为什么不选择前者呢?千万别问我为什么会存在这种场景。

去重:根据用户的ID去重,得到网站的UV统计

 

使用的Filtering方法需要根据业务来判断:可以使用Regex Filtering、当然也可以直接使用Probability Sampling、或者使用特定功能过滤的Bloom Filtering

 

 

我们先看下Regex匹配的MapReduce程序,这个实际上就是Distributed Grep的实例:

class Mapper
  method setup
    regex = new Regex Array
  method map(value val)
    if(val matches regex)
      emit(null,val)

 

这个分布式的Grep操作看起来很是简单,实际上也确实是简单;至少Hadoop提供的教程里面也是这么写的,当然写的有点不一样,我这里只关心能体现Filtering逻辑的内容。注意这个Distributed Grep没有Combiner、没有Reducer、只有一个Mapper就足够了,设置Reducer数目为Zero就不会运行Reducer了。

 

在使用概率抽样时,SRSSimple Random Sampling)是个不错的方法。对于减小数据集大小的抽样,使用SRS方法先设定好取样的数据集合大小门限theta,然后对于每条数据,使用随机数产生数字alpha,如果alpha小于theta,该数据满足取样要求,否则丢弃。伪码如下:

class Mapper
  method setup
    theta = threshold from configuration
  method map(value val)
    alpha = new random
    if(alpha < theta)
      emit(null,val)

 

说到这些Filter,必须得提下Bloom Filter,是一种Space Efficient的概率型数据结构(probabilistic data structure),用于判定一个元素是否位于集合中。在垃圾邮件过滤的黑白名单方法、爬虫的网址判重模块中经常被用到。wiki可以参考这里(http://en.wikipedia.org/wiki/Bloom_filter)。简单说就是利用多个Hash函数来判定是否位于集合中,False Positive可能发生,就是误判;但是False Negative绝对不会发生。wiki页面上有比较详细的推导,实际上就是使用错误率来换取存储空间。如果你需要的场景是对误判的Zero-Tolerance,这个Bloom Filter不是你的选择。

使用多个Hash函数来处理碰撞,那么高效的Hash函数就是个关键,在HadoopHbase中使用了MurmurHash( http://en.wikipedia.org/wiki/MurmurHashGoogle构建于其上的CityHash (http://en.wikipedia.org/wiki/CityHash都具有不错的性能,原理大家自行细读。

 

明白了Bloom Filter的原理,对于使用Bloom Filter的场景也要有清晰的认识。

过滤非热词:从数据集合中过滤热词,根据Bloom Filter的特性,非热词也有可能出现,但是热词都已经存在,非热词作为噪声处理也没有关系,至少数据集合大小已经降下来了。

预处理集合:这个预处理需要仔细定义一下,假如说某个查找功能非常耗时耗力耗资源,使用这个功能时,如果能对被查找的集合做Bloom Filter处理,能够大大降低被查找的集合大小,这个预处理功能就显得很有必要了。

空间操作:对于及其耗时的硬盘操作,可以使用Bloom Filter来处理,如Google Bigtable disk lookupSquid Web proxy cache digests

 

一般来说,使用Bloom Filter都有个初始化的过程,会初始化Bloom FilterHash函数,Bit大小等,使用Bloom Filter的伪码如下:

class Mapper
  method setup
    filter = new bloom filter
  method map(value val)
    if(filter.test(val))
      emit(null,val)

 

使用Bloom Filter的内容很简单,但是使用Bloom Filter的场景判定很关键。

 

TOP-K算法在网络上有许多,也有很多的分析,其实TOP-K也算是过滤的一个种类。

在面试时,TOP-K算法也算是基础题目之一,分而治之的思想就能顺利解决。如果加上内存、网络IO、时间等限制的话,根据具体的情况,分治也是一个不错的方法。这里当然不是讨论这个算法的解决方法,而是讨论在MapReduce框架中怎么解决这个问题。

class Mapper
  method setup
    H = new Fixed Array(K)
  method map(Value val)
    H.add(val)
    if(len(H) > K)
      truncate H to K size
  method cleanup
    for all Value val in H do:
      emit(null, val)
    
class Reducer
  method setup
    H = new Fixed Array(K)
  method reduce(Value key, Value[val1,val2,...])
    sort [val1,val2,...]
    truncate val to top K to H
    for all Value val in H do
    emit(null,val)

 

需要注意的是,所有的Mapper最后都汇总到同一个Reducer上,也就是说必须限制Reducer数目为1。那么最后Reducer需要处理的数据位K*M,这个K*M的问题后面再说。

 

TOP-K算法很简单,在很多情况下都能运行的很好,这里不再赘述,下面我们讨论下这个算法的不足之处,不足之处很大程度上来自于单个Reducer

 

1:多个Mapper输出结果到同一个Reducer中,如果K*M太大的话,ShuffleSort过程会比较耗时,这个是在本地硬盘上做的工作,而不是在内存中。

2:单个Reducer运行的数据来自于各个Mapper,这样会导致单个Reducer成为热点,网络IO过大。

3:将所有的K*M个记录状态装载到内存中,如果数据量过大的话,这个装载时间可能会特别长

4:在内存里面Sort可能会导致虚拟机崩溃;不过这个不是问题,这个K*M的数据规模跟原始数据比算是小的了,可以使用打擂台或者最大(小)堆来维护K个记录

5:使用单个Reducer,没有使用Hadoop的并行写的能力,不过这个也不是个问题

 

单个Reducer的限制确实很大,有可能会导致该程序效率低下、不发正常工作甚至崩溃。对于单个Mapper程序,M的数量是可以限制的,如果K的数目过大的话,就需要额外的考虑了。不过总体来说,这个M值即使上万都没有关系。换句话说,Top-10000是干什么用的呢?甚至说有时候我们只关心TOP-K(K < 100)的内容。

 

最后还有个Distinct内容。

Distinct,顾名思义,数据去重;含义和SQL中的distinct含义一致。除去去重之外,Distinct还有一个非常重要的功能:防止Inner Join数据爆炸;distinct在数据做Join模式时能够发挥巨大的作用。

Distinct的代码比较简单,但是其功能绝对不简单,尤其是在做Join操作时。代码如下:

class Mapper
  method map(key,val)
    emit(key,null)
    
class Reducer
  method reduce(key, records)
    emit(key,null)

这个Distinct的典型应用就是UV的计算,这个算是比较熟悉的内容了,不再多做解释。

  

Filtering模式到这里就算是结束了,主要是通过减小集合的内容,来更近、更关注的观察数据。熟悉、熟练掌握这种模式,能够加深对于数据集合的理解和应用。

分享到:
评论

相关推荐

    [MapReduce.Design.Patterns(2012.11)].Donald.M

    ### MapReduce设计模式详解 #### 一、概述与背景 《MapReduce设计模式》是由Donald Miner和Adam Shook合著的一本书,首次出版于2012年11月,由O'Reilly Media, Inc.出版发行(ISBN: 978-1-449-32717-0)。这本书主要...

    mapreduce-patterns-examples

    这个"mapreduce-patterns-examples"存储库提供了MapReduce设计模式的实例源代码,源自O'Reilly在2012年出版的书籍。本文将深入探讨MapReduce的核心概念、设计模式以及相关的Java实现。 一、MapReduce基础 ...

    数据分析师面试的77个常见问题,你准备好了吗?知识.pdf

    4. **技术术语**:协同过滤(Collaborative Filtering)、n-grams、MapReduce和余弦相似性(Cosine Similarity)是数据挖掘和机器学习中的常用概念。面试者应能阐述它们的用途和计算方式。 5. **网络爬虫优化**:...

    大数据之数据挖掘课程:海量数据集挖掘 08-双边序列推荐 共59页.pdf

    - **原理**:通过设计特定的哈希函数族,使得相似的数据点被哈希到同一个桶的概率高于不相似的数据点。 - **应用**:图像检索、文档相似性检测等领域。 ##### 4. 聚类算法(Clustering) - **定义**:将数据集中的...

    大数据之数据挖掘课程:海量数据集挖掘 10-WebSpam 共61页.pdf

    - **协同过滤(Collaborative Filtering)**:通过分析用户的行为和偏好,找到相似用户群体或相似项目,进而做出推荐。 - **潜在因子模型(Latent Factor Models)**:通过降维技术来识别用户和项目之间的潜在联系,构建...

    mahout 0.5

    Mahout 0.5包含了一套完整的推荐引擎,如基于用户的协同过滤(User-Based Collaborative Filtering)和基于物品的协同过滤(Item-Based Collaborative Filtering)。这些算法可以用于电影推荐、商品推荐等场景,通过...

    Mahout In Action英文完整版

    1. **推荐系统**:Mahout提供了一系列推荐算法,如基于用户的协同过滤(User-Based Collaborative Filtering)、基于物品的协同过滤(Item-Based Collaborative Filtering)等。这些算法能够根据用户的历史行为数据预测...

    Mahout算法详解

    1. **数据预处理**:将原始数据转换为适合MapReduce处理的格式。 2. **Map阶段**:根据用户ID或物品ID进行数据划分,由多个Mapper并行处理。 3. **Reduce阶段**:汇总各个Mapper的结果,计算物品间的相似度。 4. **...

    基于.协同过滤算法的电影推荐系统.pdf

    Taste 是一个高度可扩展的推荐引擎,采用 Java 编写,支持 MapReduce 模式,可以充分利用 Hadoop 分布式计算的优势,提高推荐算法的效率。在 Mahout 0.5 版本中,Taste 提供了多种推荐算法的实现,包括基础的用户和...

    斯坦福机器学习网页转pdf版本11-15.zip

    异常检测通常用于识别数据集中的离群值或不寻常模式,这对于识别欺诈行为、设备故障预测等应用场景非常重要。异常检测方法可以分为监督学习、无监督学习和半监督学习,每种方法都有其适用的场景和挑战。例如,...

Global site tag (gtag.js) - Google Analytics