基于布隆过滤器实现敏感词识别和过滤

简介: 在当前的网络环境下,敏感词过滤已经是各大网站的“标准配置”,如果不想被大量的垃圾信息充斥,除了使用机器人识别、验证码等验证工具,还需要阻止含有敏感词内容的发布,否则可能面临关站等风险,可谓是国内互联网的红线。

在当前的网络环境下,敏感词过滤已经是各大网站的“标准配置”,如果不想被大量的垃圾信息充斥,除了使用机器人识别、验证码等验证工具,还需要阻止含有敏感词内容的发布,否则可能面临关站等风险,可谓是国内互联网的红线。

布隆过滤器

布隆过滤器(英语:Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

敏感词的过滤,在编程中最常见的方法是敏感词库数组遍历匹配,如果敏感词在文本中出现,则视为违规。本文将介绍基于分词技术和布隆过滤器实现的敏感词检测。相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数(O(k))。另外,散列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。除了敏感词过滤,布隆过滤器还有以下应用场景:

  1. 字处理软件中,需要检查一个英语单词是否拼写正确
  2. 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上
  3. 在网络爬虫里,一个网址是否被访问过
  4. yahoo, gmail等邮箱垃圾邮件过滤功能

布隆过滤器的原理

布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k
20190326214904
以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置位0。对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。

基于Java的编程实现

Google提供的guava核心库中,提供了布隆过滤器的实现。其中的敏感词库文件,可以参考:https://github.com/tenstone/textfilter

@Service
public class BloomFilterService {

    private BloomFilter<String> configuredFilter;

    private final BloomFilter<String> filter = BloomFilter.create(new Funnel<String>() {
        private static final long serialVersionUID = 1L;
        @Override
        public void funnel(String arg0, PrimitiveSink arg1) {

            arg1.putString(arg0, Charsets.UTF_8);
        }
    }, 1024*1024*32);

    /**
     * 读取带敏感词的布隆过滤器
     *
     * @return
     * @throws IOException
     */
    public BloomFilter<String> getSensitiveWordsFilter() throws IOException {
        InputStreamReader read = null;
        BufferedReader bufferedReader = null;
        read = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("SensitiveWords.txt"), StandardCharsets.UTF_8);
        bufferedReader = new BufferedReader(read);
        for (String txt = null; (txt = bufferedReader.readLine()) != null; ) {
            filter.put(txt);
        }
        this.configuredFilter = filter;
        return filter;
    }

    /**
     * 判断一段文字中,是否包含敏感词
     *
     * @param segments
     * @return
     */
    public Boolean segmentSensitiveFilterPassed(String[] segments) {
        if(configuredFilter == null){
            try {
                getSensitiveWordsFilter();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        Segment shortestSegment = new DijkstraSegment().enableCustomDictionary(false).enablePlaceRecognize(true).enableOrganizationRecognize(true);
        for(String segment :segments){
            List<Term> termList =  shortestSegment.seg(segment);
            for (Term term :termList){
                // 如果布隆过滤器中找到了对应的词,则认为敏感检测不通过
                if(configuredFilter.mightContain(term.word)){
                    log.info("检测到敏感词:"+term.word);
                    throw new RuntimeException("检测到敏感词");
                }
            }
        }
        return true;
    }
目录
相关文章
|
2月前
|
人工智能 Python
条件过滤检索
向量检索服务DashVector支持条件过滤和向量相似性检索相结合,在精确满足过滤条件的前提下进行高效的向量检索。
|
9月前
|
数据采集 数据可视化 数据挖掘
如何筛选和过滤ARWU网站上的大学排名数据
ARWU网站(ShanghaiRanking's Academic Ranking of World Universities)是一个公认的全球大学排名的先驱和最值得信赖的大学排名之一。它每年发布世界前1000所研究型大学的排名,基于透明的方法论和客观的第三方数据。ARWU网站上的大学排名数据可以为高考考生、专业选择、就业指导、行业发展等提供有价值的参考信息。
如何筛选和过滤ARWU网站上的大学排名数据
|
10月前
|
数据挖掘
基于R筛选过滤低丰度物种的几种方式
基于R筛选过滤低丰度物种的几种方式
260 0
|
自然语言处理 搜索推荐 算法
推荐系统:基于内容的过滤
此图像包含用户喜欢的电影的描述。根据用户喜欢的电影向用户推荐电影,需要使用这些描述得到一个数学形式,即文本应该是可测量的,然后通过与其他电影进行比较来找到相似的描述。 我们有各种电影和关于这些电影的数据。为了能够比较这些电影数据,需要对数据进行矢量化。在向量化这些描述时,必须创建所有电影描述(假设 n)和所有电影(假设 m)中的唯一词矩阵。列中有所有唯一的单词,行中有所有电影,每个单词在交叉点的电影中使用了多少。这样,文本就可以被矢量化。
216 0
LeetCode 1773. 统计匹配检索规则的物品数量
给你一个数组 items ,其中 items[i] = [typei, colori, namei] ,描述第 i 件物品的类型、颜色以及名称。
72 0
|
人工智能 开发者
垃圾邮件过滤实例 | 学习笔记
快速学习垃圾邮件过滤实例
85 0
|
Python
一日一技:如何对数据进行过滤
一日一技:如何对数据进行过滤
338 0
一日一技:如何对数据进行过滤
|
编解码 C语言 C++
1066 图像过滤 (15 分)
图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来。现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色替换。
84 0
|
存储 算法 JavaScript
如何优雅地过滤敏感词
敏感词过滤功能在很多地方都会用到,理论上在Web应用中,只要涉及用户输入的地方,都需要进行文本校验,如:XSS校验、SQL注入检验、敏感词过滤等。今天着重讲讲如何优雅高效地实现敏感词过滤。
13836 0