布隆过滤

来源:互联网 发布:排序算法详解 编辑:程序博客网 时间:2024/05/01 22:47

在《大数据:互联网大规模数据挖掘与分布式处理》中,作者将布隆过滤放在了“数据流挖掘”中,并以垃圾邮件过滤为例。

而在《Hadoop实战》中,作者在MR程序性能调优中进行介绍。目的是在作业执行前过滤掉无用、噪声、异常数据。

1.为什么要使用布隆过滤?

因为当数据量过大而无法放入内存时,将每个数据映射到二进制位中可以减少内存的使用。

2.在哈希函数足够“好"的情况下,布隆过滤将“不存在的数据”误判为“存在”的可能性为多少?

假设桶数为n,数据集中的数据量为m,哈希函数的数目为k。

则将数据集中的数据进行哈希后,值为1的桶的比例为:

桶集合中值为1的桶的比例=给定一个桶,它的值为1的可能性=1-[(n-1)/n]^(k*m)=非数据集中的数据被哈希到某个桶,这个桶为1的概率

误判的可能性=桶集合中值为1的桶的比例的k次方

(桶集合中值为1的桶的比例,就是一个桶值为1的概率,也就是桶集合在设置一个桶的值时设置值为1的可能性)

import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.util.BitSet;import java.util.Random;import java.util.Scanner;public class BloomFiltering {BitSet bitsArray;int [] randomArray;public BloomFiltering(int hashTimes){bitsArray=new BitSet();randomArray=new int[2*hashTimes];Random random = new Random();for(int t=0;t<2*hashTimes;t++)randomArray[t]=(Math.abs(random.nextInt())%100)+1;//随机数的范围是1-100}public void add(String value){if(value==null){ System.out.println("您输入了空值");}else{for(int i=0;i<randomArray.length;i+=2)bitsArray.set(hash(randomArray[i],randomArray[i+1],value),true);}}public int hash(int random1,int random2,String value){int result ;int sum=0;int divider=2000000000;//20亿个桶for(int i=0;i<value.length();i++){//sum的值不会太大sum+=((int)value.charAt(i))*i;}result =(sum*random1+random2)%divider;//显然(sum*random1+random2)的值应该小于divider,哈希函数构造的并不好return result;}            public boolean contain(String value){boolean returnValue=true;if(value==null){ System.out.println("您输入了空值"); return false;}else{for(int i=0;i<randomArray.length;i+=2)returnValue=returnValue&&bitsArray.get((int)hash(randomArray[i],randomArray[i+1],value));return returnValue;}}public static void main(String[] args){int hashTimes;BufferedReader inputStream;BloomFiltering filter;Scanner keyboard=new Scanner(System.in);System.out.println("请问您需要使用几个哈希函数?");hashTimes=keyboard.nextInt();filter=new BloomFiltering(hashTimes);try {inputStream =new BufferedReader(new FileReader("C:\\Users\\fujiaxiaoshao\\Desktop\\邮箱.txt"));String line=inputStream.readLine();while(line!=null){while(line.indexOf("@")!=-1){String tmp;int end=line.indexOf(" ");if(end!=-1)  {tmp=line.substring(0, end);line=line.substring(end+1,line.length());}else {end=line.length();tmp=line.substring(0, end);line="";}System.out.println(tmp);filter.add(tmp);}line=inputStream.readLine();}} catch (IOException e) {System.out.println("读取文档发生IO异常");}System.out.println("请输入邮箱,查询其是否存在");String input=keyboard.next();if(filter.contain(input)){System.out.println("该邮箱地址有可能存在");}else{System.out.println("该邮箱一定不存在");}keyboard.close();}}

上边是我写的一个过滤邮箱的代码。使用了BitSet类。

0 0