• Bloom Fileter学习总结


    因为工作上要对大量小票数据进行无监督分类,考虑到内存和运算速度的问题,采用巴隆滤波映射对小票的数据进行了处理,工作内容就不详细说了,等项目做完的。

    现在谈谈BF(bloom fileter的使用心得

    首先,BF是一种基于多哈希映射的转换,随机或者说选取K个质数作为初始种子,这就有了K个哈希映射。一段字符串,每个种子可以得到一个哈希映射,这样这个字符串就对应了多个哈希值,可以降低不同字符串重复覆盖的误识别问题。下面用部分代码举例:

    public int hash(String value) {

    int result = 0;

    int len = value.length();

    for (int i = 0; i < len; i++) {

    result = seed * result + value.charAt(i);

    }

    return (cap - 1) & result;

    }

    这是一个种子(seed)对应的字符串哈希值,然后做个for循环遍历种子数组(seeds),得到字符串对应所有种子的多个哈希值,种子数组举例:

    private static final int[] seeds = new int[] { 5, 7, 11, 13, 31, 37, 61 };

    一般选取质数,个数看识别要求的精度了,具体请参照数学之美中对巴隆滤波的详细讲解,记着里面有个表格列举了部分种子个数的误识别概率,并做了详细推导说明

    而之所以计算快,就是因为将大量字符串的比对有效的转换为了bit的比对计算,bit是大数据计算常用的一种数据类型(话说我是学图像的,有的话可能不准确,见谅,这是和一些做数据挖掘的同学闲聊时有些印象,而且我自己工作中如果用java处理图像经常转为bitset类型,一些计算的速度很快),好吧,谁用谁知道。。。

    此外,需要注意的是,传统BF不能进行字符串的删除操作,因为不同字符串可能有少量重复元素,如果删除一个字符串的元素,会影响有交叉元素的其他字符串。如果一定要使用字符串的删除功能,可以试试CBF(Count,计数巴隆滤波),顾名思义,就是把bit的0,1记录元素,改为记录这个位置元素出现1的次数,删除时把统计次数减一就行了。

    下面贴下整体实现代码,这个就是非原创了,但是具体出处记不清了,因为是一个月前的事了,今天有时间所以对做的项目做个阶段性总结,有知道的请联系我

    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.BitSet;
    import java.util.List;


    public class SimpleBloomFilter {
    private static final int DEFAULT_SIZE = 2 << 24;
    private static final int[] seeds = new int[] { 5, 7, 11, 13, 31, 37, 61 };
    private BitSet bits = new BitSet(DEFAULT_SIZE);
    private SimpleHash[] func = new SimpleHash[seeds.length];


    public SimpleBloomFilter() {
    for (int i = 0; i < seeds.length; i++) {
    func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
    }
    }


    public void add(String value) {
    for (SimpleHash f : func) {
    bits.set(f.hash(value), true);
    }
    }


    public boolean contains(String value) {
    if (value == null) {
    return false;
    }
    boolean ret = true;
    for (SimpleHash f : func) {
    ret = ret && bits.get(f.hash(value));
    }
    return ret;
    }


    // 内部类,simpleHash
    public static class SimpleHash {
    private int cap;
    private int seed;


    public SimpleHash(int cap, int seed) {
    this.cap = cap;
    this.seed = seed;
    }


    public int hash(String value) {
    int result = 0;
    int len = value.length();
    for (int i = 0; i < len; i++) {
    result = seed * result + value.charAt(i);
    }
    return (cap - 1) & result;
    }
    }

    这是几种开源的java代码,我感觉最适用的,没写test,额下面关于项目部分以后补上吧。

  • 相关阅读:
    那些年搞不懂的多线程、同步异步及阻塞和非阻塞(一)---多线程简介
    java中IO流详细解释
    Java IO流学习总结
    MySQL数据库中索引的数据结构是什么?(B树和B+树的区别)
    使用Redis存储Nginx+Tomcat负载均衡集群的Session
    Redis 3.2.4集群搭建
    JDK1.8源码分析之HashMap
    java HashMap和LinkedHashMap区别
    Java中原子类的实现
    多线程-传统定时任务
  • 原文地址:https://www.cnblogs.com/zhangdebin/p/5567951.html
Copyright © 2020-2023  润新知