用户行为分析--UV排重处理(Bloom)

来源:互联网 发布:java restful 服务端 编辑:程序博客网 时间:2024/05/06 01:20

Maching Learning 

  QQ群: 2441032012

         请说明来自csdn

  微信:soledede

 

进行用户行为分析避免不掉要计算网站的UV,即Unique Visitor,那如何定义一个有效的Visitor呢?


  1. 客户端第一次访问该网站(cookie)
  2. 当天同一个客户端的多次访问,算一个有效的Visitor

第1点通过判断客户端是否存在指定Cookie即可区分。

关于第2点,由于客户端对网站一天内的一(多)次访问过程会触发N条行为数据,针对这N条行为数据,服务端只会将Visitor的数量加1,即收到第一条行为数据时Visitor+1,后续的N-1条数据被忽略。那如何识别这N条行为数据是属于同一个Visitor,排重的策略又有哪些?

每个客户端都有一个唯一的CID Cookie,只要CID+{YYYYMMDD}是相同的,就认为是属于同一个Visitor。

一些可行的排重策略如下:

  • 利用DataBase中的主键进行排重过滤,比如MySQL(PK)、HBase(RowKey)、Redis(Key)等,此策略的劣势是要定期对垃圾数据进行清理。
  • 利用Memcache/Redis的set with expire time,超过expire time(此处大于一天)则垃圾数据自动清理
  • 使用Bloom Filter做过滤,基于内存、简单高效,前提是必须能够容忍小概率的出错、误判。


下面简单介绍一下Bloom Filter。

Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法。通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合。

Bloom Filter算法如下:

    创建一个m位BitSet,先将所有位初始化为0,然后选择k个不同的哈希函数。第i个哈希函数对字符串str哈希的结果记为h(i,str),且h(i,str)的范围是0到m-1 。

加入一个字符串:

    对于字符串str,分别计算h(1,str),h(2,str)…… h(k,str)。然后将BitSet的第h(1,str)、h(2,str)…… h(k,str)位设为1。

    

    这样就将字符串str映射到BitSet中的k个二进制位了。

检查字符串是否已存在的过程:

    对于字符串str,分别计算h(1,str),h(2,str)…… h(k,str)。然后检查BitSet的第h(1,str)、h(2,str)…… h(k,str)位是否为1,若其中任何一位不为1则可以判定str一定没有被记录过。若全部位都是1,则“认为”字符串str存在。

    一个字符串对应的Bit全为1,实际上是不能100%的肯定该字符串被Bloom Filter记录过的。(因为有可能该字符串的所有位都刚好是被其他字符串所对应)这种将该字符串划分错的情况,称为false positive。

如何降低false positive概率:

    增大BitSet的大小,这样就可以降低Bit位碰撞的几率,但这样同时会增加其占用的空间(内存)。

    把false positive概率控制在1%以下时,所需要的内存使用率如下:

        

    可见占用的空间在key的数量在百万级别还是很划算的,但到了上亿的级别就不那么划算了。

总之,Bloom Filter的插入和查询都非常快,最大的问题就是其占用内存过大,当然一定的错误率也是无法避免的。

原创粉丝点击