python敏感词过滤代码简单_DFA敏感词过滤算法的python实现
DFA敏感詞過濾算法的python實現
在網上查了下敏感詞過濾方案,找到了一種名為DFA的算法,即Deterministic Finite
Automaton算法,翻譯成中文就是確定有窮自動機算法。它的基本思想是基于狀態轉移來檢索敏感詞,只需要掃描一次待檢測文本,就能對所有敏感詞進行檢測,所以效率比方案一高不少。
假設我們有以下5個敏感詞需要檢測:傻逼、傻子、傻大個、壞蛋、壞人。那么我們可以先把敏感詞中有相同前綴的詞組合成一個樹形結構,不同前綴的詞分屬不同樹形分支,以上述5個敏感詞為例,可以初始化成如下2棵樹:
把敏感詞組成成樹形結構有什么好處呢?最大的好處就是可以減少檢索次數,我們只需要遍歷一次待檢測文本,然后在敏感詞庫中檢索出有沒有該字符對應的子樹就行了,如果沒有相應的子樹,說明當前檢測的字符不在敏感詞庫中,則直接跳過繼續檢測下一個字符;如果有相應的子樹,則接著檢查下一個字符是不是前一個字符對應的子樹的子節點,這樣迭代下去,就能找出待檢測文本中是否包含敏感詞了。
我們以文本“你是不是傻逼”為例,我們依次檢測每個字符,因為前4個字符都不在敏感詞庫里,找不到相應的子樹,所以直接跳過。當檢測到“傻”字時,發現敏感詞庫中有相應的子樹,我們把他記為tree-1,接著再搜索下一個字符“逼”是不是子樹tree-1的子節點,發現恰好是,接下來再判斷“逼”這個字符是不是葉子節點,如果是,則說明匹配到了一個敏感詞了,在這里“逼”這個字符剛好是tree-1的葉子節點,所以成功檢索到了敏感詞:“傻逼”。大家發現了沒有,在我們的搜索過程中,我們只需要掃描一次被檢測文本就行了,而且對于被檢測文本中不存在的敏感詞,如這個例子中的“壞蛋”和“壞人”,我們完全不會掃描到,因此相比方案一效率大大提升了。
在python中,我們可以用dict來存儲上述的樹形結構,還是以上述敏感詞為例,我們把每個敏感詞字符串拆散成字符,再存儲到dict中,可以這樣存:
# -*- coding:utf-8 -*-
import time
time1 = time.time()
# DFA算法
class DFAFilter(object):
def __init__(self):
self.keyword_chains = {} # 關鍵詞鏈表
self.delimit = '\x00' # 限定
def add(self, keyword):
keyword = keyword.lower() # 關鍵詞英文變為小寫
chars = keyword.strip() # 關鍵字去除首尾空格和換行
if not chars: # 如果關鍵詞為空直接返回
return
level = 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):
break
for 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}
break
if i == len(chars) - 1:
level[self.delimit] = 0
def parse(self, path):
with open(path, encoding='utf-8') as f:
for keyword in f:
self.add(str(keyword).strip())
print(self.keyword_chains)
def filter(self, message, repl="*"):
message = message.lower()
ret = []
start = 0
while start < len(message):
level = self.keyword_chains
step_ins = 0
for char in message[start:]:
if char in level:
step_ins += 1
if self.delimit not in level[char]:
level = level[char]
else:
ret.append(repl * step_ins)
start += step_ins - 1
break
else:
ret.append(message[start])
break
else:
ret.append(message[start])
start += 1
return ''.join(ret)
if __name__ == "__main__":
gfw = DFAFilter()
path = "./1.txt"
gfw.parse(path)
text = "你真是個大傻逼,大傻子,傻大個,大壞蛋,壞人。"
result = gfw.filter(text)
print(text)
print(result)
time2 = time.time()
print('總共耗時:' + str(time2 - time1) + 's')
{'傻': {'大': {'個': {'\x00': 0}}, '逼': {'\x00': 0}}, '壞': {'人': {'\x00': 0}}}
你真是個大傻逼,大傻子,傻大個,大壞蛋,壞人。
你真是個大**,大傻子,***,大壞蛋,**。
總共耗時:0.0s
總結
以上是生活随笔為你收集整理的python敏感词过滤代码简单_DFA敏感词过滤算法的python实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 老赵看博客园首页
- 下一篇: Matplotlib笔记(莫烦Pytho