敏感词过滤

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 布隆过滤器用来判断一个集合中的是否包含某一个元素,由于采用hash运算,有hash碰撞的原因,所以会存在误判。布隆过滤器判定一个元素存在的情况,这个元素可能不存在,但是判定一个元素不存在的时候,是一定不存在的。

布隆过滤器


布隆过滤器用来判断一个集合中的是否包含某一个元素,由于采用hash运算,有hash碰撞的原因,所以会存在误判。布隆过滤器判定一个元素存在的情况,这个元素可能不存在,但是判定一个元素不存在的时候,是一定不存在的。


利用redisson的布隆过滤器实现敏感词过滤


public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.56.102:6379");
//        config.useSingleServer().setPassword("");
        // 构造Redisson
        RedissonClient redissonClient = Redisson.create(config);

        // 初始化布隆过滤器:预计元素为100000000L个,误差率为3%
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("phoneList");
        bloomFilter.tryInit(100000000L, 0.03);

        // 将号码插入到布隆过滤器中
        bloomFilter.add("张雪");
        bloomFilter.add("张学友");
        bloomFilter.add("张雪1");
        bloomFilter.add("张三");

        // 判断下面的号码是否在布隆过滤器中
        System.out.println(bloomFilter.contains("张雪1"));
        System.out.println(bloomFilter.contains("李四"));
        System.out.println(bloomFilter.contains("张学友"));
}

布隆过滤器特性,

  • 无法返回具体的敏感词是什么
  • 会存在敏感词的误判

DFA

  1. 敏感词拆分储存
  2. 设置标记位标记是否结束
    如敏感词有张学友,张学良,叶良,叶良辰,如图示:



java实现

public class SensitiveWordUtil {

    public static Map<String, Object> dictionaryMap = new HashMap<>();


    /**
     * 生成关键词字典库
     * @param words
     * @return
     */
    public static void initMap(Collection<String> words) {
        if (words == null) {
            System.out.println("敏感词列表不能为空");
            return ;
        }

        // map初始长度words.size(),整个字典库的入口字数(小于words.size(),因为不同的词可能会有相同的首字)
        Map<String, Object> map = new HashMap<>(words.size());
        // 遍历过程中当前层次的数据
        Map<String, Object> curMap;
        Iterator<String> iterator = words.iterator();

        while (iterator.hasNext()) {
            String word = iterator.next();
            curMap = map;
            int len = word.length();
            //DFA算法,Deterministic Finite Automaton,即确定有穷自动机。
            for (int i =0; i < len; i++) {
                // 遍历每个词的字
                String key = String.valueOf(word.charAt(i));
                // 当前字在当前层是否存在, 不存在则新建, 当前层数据指向下一个节点, 继续判断是否存在数据
                Map<String, Object> wordMap = (Map<String, Object>) curMap.get(key);
                if (wordMap == null) {
                    // 每个节点存在两个数据: 下一个节点和isEnd(是否结束标志)
                    wordMap = new HashMap<>(2);
                    wordMap.put("isEnd", "0");
                    curMap.put(key, wordMap);
                }
                curMap = wordMap;
                // 如果当前字是词的最后一个字,则将isEnd标志置1
                if (i == len -1) {
                    curMap.put("isEnd", "1");
                }
            }
        }

        dictionaryMap = map;
    }

    /**
     * 搜索文本中某个文字是否匹配关键词
     * @param text
     * @param beginIndex
     * @return
     */
    private static int checkWord(String text, int beginIndex) {
        if (dictionaryMap == null) {
            throw new RuntimeException("字典不能为空");
        }
        boolean isEnd = false;
        int wordLength = 0;
        Map<String, Object> curMap = dictionaryMap;
        int len = text.length();
        // 从文本的第beginIndex开始匹配
        for (int i = beginIndex; i < len; i++) {
            String key = String.valueOf(text.charAt(i));
            // 获取当前key的下一个节点
            curMap = (Map<String, Object>) curMap.get(key);
            if (curMap == null) {
                break;
            } else {
                wordLength ++;
                if ("1".equals(curMap.get("isEnd"))) {
                    isEnd = true;
                }
            }
        }
        if (!isEnd) {
            wordLength = 0;
        }
        return wordLength;
    }

    /**
     * 获取匹配的关键词和命中次数
     * @param text
     * @return
     */
    public static Map<String, Integer> matchWords(String text) {
        Map<String, Integer> wordMap = new HashMap<>();
        int len = text.length();
        for (int i = 0; i < len; i++) {
            int wordLength = checkWord(text, i);
            if (wordLength > 0) {
                String word = text.substring(i, i + wordLength);
                // 添加关键词匹配次数
                if (wordMap.containsKey(word)) {
                    wordMap.put(word, wordMap.get(word) + 1);
                } else {
                    wordMap.put(word, 1);
                }

                i += wordLength - 1;
            }
        }
        return wordMap;
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张学友");
        list.add("张学良");
        list.add("叶良");
        list.add("叶良辰");
        initMap(list);
        String content="我是张学友,不是叶良, 更不是叶良辰";
        Map<String, Integer> map = matchWords(content);
        System.out.println(map);
        //{叶良=1, 张学友=1, 叶良辰=1}
    }
}

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
监控 算法 安全
Apriori算法:文档管理软件中的智能标签建议
Apriori算法是一种关联规则挖掘算法,它可以用于在大规模数据集中查找项集之间的频繁性关联。该算法的核心思想是通过迭代计算事物间的相对支持度,并根据预设的阈值来剪枝,以得到频繁的关联项。Apriori算法的优势在于可以快速地找到大量且未知的关联规则,广泛应用于数据挖掘领域。
166 1
|
3月前
|
移动开发 API
成语接龙[3万词库]免费API接口教程
该接口用于根据指定字首查询相关成语信息。通过POST或GET请求至`https://cn.apihz.cn/api/zici/cyjl.php`,需提供用户ID、KEY及字首参数。返回成语的详细信息,包括名称、拼音、解释等。示例请求中ID与KEY为公共测试用,建议使用个人ID与KEY以提高调用频率。
|
6月前
|
UED
【打造梦幻联动!】揭秘钉钉宜搭中的单选关联选项设置与图文展示的魔术 —— 让你的表单瞬间变身智能导游!
【8月更文挑战第7天】随着企业信息化的发展,办公自动化工具如钉钉宜搭成为提高效率的关键。宜搭是一款低代码平台,支持灵活的表单设计与流程管理。以旅行社报名表为例,介绍如何实现单选字段联动图文展示:用户选择目的地后自动显示相关信息。设计上,先创建单选和图文字段,再设置联动逻辑。通过简单的后台配置即可实现动态展示效果,提升用户体验与数据准确性。
174 0
如何让ChatGPT学习销售过往文字稿,并自动分析话术的优缺点,然后修改?
产品特点、服务优势、目标客户需求和痛点、行业与市场的趋势变化、竞争对手的优劣势、销售场景的特点和要求、销售环境、销售氛围、时间、地点、客户情感需求、心理转态、个性特点、解决方案
353 0
如何让ChatGPT学习销售过往文字稿,并自动分析话术的优缺点,然后修改?
|
消息中间件 人工智能 算法
很全的敏感词匹配系统的设计与实践(1)
很全的敏感词匹配系统的设计与实践(1)
|
文字识别 小程序 Java
基于发票增值税OCR API设计自动识别应用系统,从此解放财务双手
增值税发票识别OCR API是一种基于光学字符识别(OCR)技术的API,旨在帮助用户自动识别和提取增值税发票中的文字信息。通过使用这个API,用户可以将增值税发票扫描或拍照后上传至云端,API将自动识别和提取发票中的关键信息,例如发票号码、日期、销售方名称、购买方名称等等。
392 0
基于发票增值税OCR API设计自动识别应用系统,从此解放财务双手
|
数据安全/隐私保护
Mindopt上新数据脱敏功能,方便外发数据
V0.24.0版本的MindOpt优化求解器新增了数据脱敏功能,可以对输入模型文件进行数据脱敏。将优化问题中问题名、决策变量、约束条件名称这些和业务场景相关的数据进行脱敏变更,使得优化问题的数据仅保留看不出用途的数值信息,隐藏业务信息。方便外发数据去做技术可行性验证、方案咨询、测试等。
Mindopt上新数据脱敏功能,方便外发数据
|
存储 算法
很全的敏感词匹配系统的设计与实践(2)
很全的敏感词匹配系统的设计与实践(2)
|
自然语言处理
两份数据基于文本和住房信息的分词统计 tfidf 数分作业
两份数据基于文本和住房信息的分词统计 tfidf 数分作业
87 0
两份数据基于文本和住房信息的分词统计 tfidf 数分作业
|
人工智能 UED
ThinkPHP6.0 实现 图片审核+文本内容审核(敏感词过滤)
应用场景 用户评论过滤:对网站用户的评论信息进行检测,审核出涉及违规内容,保证良好的用户体验 注册信息筛查:对用户的注册信息进行筛查,避免黑产通过用户名实现违规信息的推广 文章内容审核:对UGC文章内容进行多个维度的审核,避免因内容违规导致的APP下架等损失