一.前言

近期项目有了一个过滤敏感词的功能需求,在网上找了一些方法及解说,发现DFA算法比较好用,容易实现,但很多文章解释得不太清楚,这里将其详细描述,并用python代码实现.

二.DFA算法详解

DFA,网上常译为确定有限自动机,俗话就是新数据在已有的数据基础上去有限次查找,比如:新数据为苹果公司年会,旧数据为苹果公司,这样就可以直接旧数据后面添加"年会"两个字.
DFA算法思想是将敏感词组通过建立嵌套字典的方式去构建敏感词链表(以一个特定字符’\x00’作为结束),然后遍历新词的每个字是否出现在敏感词链表中,如果出现,即为敏感词,提取出来,可以用"*"代替.
例如:敏感词词组有:新疆骚乱,爆炸,骚乱
则构建出来的敏感词链表分别为:
‘新’: {‘疆’: {‘骚’: {‘乱’: {’\x00’: 0}}}}
‘爆’: {‘炸’: {’\x00’: 0}}
‘骚’: {‘乱’: {’\x00’: 0}}
合为一个链表为:{‘新’: {‘疆’: {‘骚’: {‘乱’: {’\x00’: 0}}}}, ‘爆’: {‘炸’: {’\x00’: 0}}, ‘骚’: {‘乱’: {’\x00’: 0}}}
其中’\x00’是指以该字符作为链表结尾
这样,当新词作为输入遍历敏感词链表时,遇到特定字符\x00才算敏感词识别出来,否则都不算入敏感词

三.python实现

采用类管理,初始化一个空字典链表,特定结束符以及生成敏感词链表的函数

Proj_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
SensitiveWord_Path = os.path.join(Proj_path, "main/minganci.txt")
class DFAFilter(object):def __init__(self):self.keyword_chains = {}  # 关键词链表self.delimit = '\x00'  # 限定self.parse(SensitiveWord_Path)

接下来是parse()读取敏感词库表,通过add()将敏感词以嵌套字典的方式形成链表,即为level,访问level即可匹配敏感词

    def parse(self, path):with open(path, encoding='utf-8') as f:for keyword in f:self.add(str(keyword).strip())def add(self, keyword):keyword = keyword.lower()  # 关键词英文变为小写chars = keyword.strip()  # 关键字去除首尾空格和换行if not chars:  # 如果关键词为空直接返回returnlevel = self.keyword_chains# 遍历关键字的每个字for i in range(len(chars)):# 如果这个字已经存在字符链的key中就进入其子字典if chars[i] in level:level = level[chars[i]]else:if not isinstance(level, dict):breakfor j in range(i, len(chars)):level[chars[j]] = {}last_level, last_char = level, chars[j]level = level[chars[j]]last_level[last_char] = {self.delimit: 0}breakif i == len(chars) - 1:  # 最后一个字level[self.delimit] = 0print(level)

最后,将传入的词组进行敏感词过滤,遍历新词组,只有当前字在敏感词链表中才能加入敏感词

    def filter(self, message, repl="*"):message = message.lower()ret = []start = 0while start < len(message):level = self.keyword_chainsstep_ins = 0for char in message[start:]:# 新字在敏感词字典链表中if char in level:step_ins += 1# 特定字符不在当前字的value值里,嵌套遍历下一个if self.delimit not in level[char]:level = level[char]else:# 将敏感词以*代替,跳出for循环ret.append(repl * step_ins)start += step_ins - 1breakelse:# 新字不在敏感词字典链表中ret.append(message[start])breakelse:ret.append(message[start])start += 1return ''.join(ret)

四.全部代码

import os
Proj_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
SensitiveWord_Path = os.path.join(Proj_path, "main/minganci.txt")# DFA算法
class DFAFilter(object):def __init__(self):self.keyword_chains = {}  # 关键词链表self.delimit = '\x00'  # 限定self.parse(SensitiveWord_Path)def add(self, keyword):keyword = keyword.lower()  # 关键词英文变为小写chars = keyword.strip()  # 关键字去除首尾空格和换行if not chars:  # 如果关键词为空直接返回returnlevel = self.keyword_chains# 遍历关键字的每个字for i in range(len(chars)):# 如果这个字已经存在字符链的key中就进入其子字典if chars[i] in level:level = level[chars[i]]else:if not isinstance(level, dict):breakfor j in range(i, len(chars)):level[chars[j]] = {}last_level, last_char = level, chars[j]level = level[chars[j]]last_level[last_char] = {self.delimit: 0}breakif i == len(chars) - 1:  # 最后一个字level[self.delimit] = 0print(level)def parse(self, path):with open(path, encoding='utf-8') as f:for keyword in f:self.add(str(keyword).strip())def filter(self, message, repl="*"):message = message.lower()ret = []start = 0while start < len(message):level = self.keyword_chainsstep_ins = 0for char in message[start:]:# 新字在敏感词字典链表中if char in level:step_ins += 1# 特定字符不在当前字的value值里,嵌套遍历下一个if self.delimit not in level[char]:level = level[char]else:# 将敏感词以*代替,跳出for循环ret.append(repl * step_ins)start += step_ins - 1breakelse:# 新字不在敏感词字典链表中ret.append(message[start])breakelse:ret.append(message[start])start += 1return ''.join(ret)

敏感词或关键词过滤,DFA算法详解及python代码实现相关推荐

  1. kmeans算法详解和python代码实现

    kmeans算法详解和python代码实现 kmeans算法 无监督学习和监督学习 监督学习: 是通过已知类别的样本分类器的参数,来达到所要求性能的过程 简单来说,就是让计算机去学习我们已经创建好了的 ...

  2. 编辑距离算法详解和python代码

    编辑距离(Levenshtein Distance)算法详解和python代码 最近做NLP用到了编辑距离,网上学习了很多,看到很多博客写的有问题,这里做一个编辑距离的算法介绍,步骤和多种python ...

  3. K-means算法详解及python代码实现

    K-means算法 算法步骤 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python)(待更.......) 算法步骤 1.随机选取K个点作为初始聚类中心 2.计算各个数据到个聚类中心的 ...

  4. python机器学习算法.mobi_机器学习之ID3算法详解及python代码实现

    在生活中我们经常会用到决策树算法,最简单的就是二叉树了:相信大家也会又同样的困扰,手机经常收到各种短信,其中不乏很多垃圾短信.此时只要设置这类短信为垃圾短信手机就会自动进行屏蔽.减少被骚扰的次数,同时 ...

  5. python决策树 value_机器学习之ID3算法详解及python代码实现

    在生活中我们经常会用到决策树算法,最简单的就是二叉树了:相信大家也会又同样的困扰,手机经常收到各种短信,其中不乏很多垃圾短信.此时只要设置这类短信为垃圾短信手机就会自动进行屏蔽.减少被骚扰的次数,同时 ...

  6. k-means算法详解及python代码

    K-means算法原理 K-means聚类属于原型聚类(基于原型的聚类,prototype-based clustering).原型聚类算法假设聚类结构能够通过一组原型进行刻画,在现实聚类任务中极为常 ...

  7. 朴素贝叶斯算法详解及python代码实现

    朴素贝叶斯算法 算法原理 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python)(待更.......) 算法原理 P(Ck∣xi)=p(xi∣ck)∗p(ck)p(xi)=p(x1∣c ...

  8. Simhash算法详解及python实现

    Simhash算法详解及python实现 GoogleMoses Charikar发表的一篇论文"detecting near-duplicates for web crawling&quo ...

  9. AC自动机算法详解以及Java代码实现

    详细介绍了AC自动机算法详解以及Java代码实现. 文章目录 1 概念和原理 2 节点定义 3 构建Trie前缀树 3.1 案例演示 4 构建fail失配指针 4.1 案例演示 5 匹配文本 5.1 ...

最新文章

  1. windows 10 anaconda python 3.7 安装keras-gpu tensorflow-gpu
  2. 使用Angular CLI从蓝本生成代码
  3. SAP Fiori应用的三种部署方式
  4. 【NLP】基于预训练的中文NLP工具介绍:ltp 和 fastHan
  5. JDBC连接数据库(一)
  6. 吴恩达斯坦福大学机器学习 CS229 课程学习笔记(二)
  7. Android_(控件)使用自定义控件在屏幕中绘制一条虚线
  8. Linux学习总结(38)——Linux超实用的30个命令
  9. 医学遗传学词汇英语术语英文(Glossary) 5
  10. 计算机毕业论文技术可行性怎么写,毕业论文怎么写可行性分析?
  11. 2021深圳杯数学建模D题分析
  12. sqlserver连接问题圣经
  13. QQ 微信转链,如何实现淘宝京东苏宁唯品会拼多多,返利转链思路
  14. 小白聊智慧制造之二:智能制造的体系架构
  15. 拓嘉启远:拼多多购物运输中的商品能拒收吗
  16. 《罗辑思维不逻辑》之那些温柔的操纵
  17. 计算机系女学霸男生追,杨紫李现解锁恋爱新姿势:吃最甜的糖,追最燃的梦
  18. PPT扁平化风格设计手册
  19. 移动文件需要计算机管理员权限,win7系统提示“需要管理员权限才能移动文件夹”的解决方法...
  20. C++常用头文件——常用数学函数头文件

热门文章

  1. Invalid options object. Dev Server has been initialized using an options object
  2. 用 vue 写一个iPhone时钟
  3. 【图像处理】Niblack
  4. 图像处理与机器视觉_第一篇
  5. bryntum gantt
  6. 在雅加达EE服务中使用Thymeleaf
  7. 【微服务】服务之间的调用方式
  8. 如何把PPT转成PDF有用的方法
  9. MEGA-X 3D打印机教程:02_打印机上手
  10. sklearn一元线性回归