Python實現(xiàn)敏感詞檢測的多種方案
一、引言
在互聯(lián)網(wǎng)內容審核、社交平臺監(jiān)管、評論系統(tǒng)過濾等場景中,敏感詞檢測是一項必不可少的功能。Python憑借其豐富的生態(tài)和簡潔的語法,提供了多種實現(xiàn)敏感詞檢測的方案。本文將詳細介紹幾種主流的實現(xiàn)方式,并分析各自的優(yōu)缺點及適用場景。
二、基礎方案:關鍵詞匹配
2.1 直接遍歷匹配
最簡單的實現(xiàn)方式是使用列表存儲敏感詞,然后遍歷檢測:
class SimpleSensitiveWordFilter:
def __init__(self):
self.sensitive_words = []
def add_words(self, words):
self.sensitive_words.extend(words)
def contains_sensitive_word(self, text):
for word in self.sensitive_words:
if word in text:
return True
return False
def replace_sensitive_words(self, text, replace_char='*'):
result = text
for word in self.sensitive_words:
result = result.replace(word, replace_char * len(word))
return result優(yōu)點:實現(xiàn)簡單,易于理解
缺點:效率低,時間復雜度O(n*m),無法處理重疊匹配
2.2 正則表達式匹配
使用正則表達式可以更靈活地匹配敏感詞:
import re
class RegexSensitiveWordFilter:
def __init__(self):
self.pattern = None
def add_words(self, words):
# 使用正則的 | 連接所有敏感詞
pattern_str = '|'.join(re.escape(word) for word in words)
self.pattern = re.compile(pattern_str, re.IGNORECASE)
def contains_sensitive_word(self, text):
return bool(self.pattern.search(text))
def find_all_sensitive_words(self, text):
return self.pattern.findall(text)
def replace_sensitive_words(self, text, replace_char='*'):
def replace_func(match):
return replace_char * len(match.group())
return self.pattern.sub(replace_func, text)優(yōu)點:支持復雜匹配規(guī)則,代碼簡潔
缺點:敏感詞數(shù)量大時性能下降,正則表達式編譯開銷較大
三、進階方案:前綴樹(Trie樹)
3.1 原理介紹
Trie樹(前綴樹)是一種專門用于字符串快速匹配的樹形數(shù)據(jù)結構。它的核心思想是利用字符串的公共前綴來減少不必要的比較,實現(xiàn)O(n)的時間復雜度。
3.2 實現(xiàn)代碼
class TrieNode:
__slots__ = ('children', 'is_end')
def __init__(self):
self.children = {}
self.is_end = False
class TrieSensitiveWordFilter:
def __init__(self):
self.root = TrieNode()
def add_word(self, word):
"""添加單個敏感詞"""
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end = True
def add_words(self, words):
"""批量添加敏感詞"""
for word in words:
self.add_word(word)
def contains_sensitive_word(self, text):
"""檢測是否包含敏感詞"""
for i in range(len(text)):
node = self.root
j = i
while j < len(text) and text[j] in node.children:
node = node.children[text[j]]
if node.is_end:
return True
j += 1
return False
def find_all_sensitive_words(self, text):
"""找出所有敏感詞及位置"""
results = []
for i in range(len(text)):
node = self.root
j = i
while j < len(text) and text[j] in node.children:
node = node.children[text[j]]
if node.is_end:
results.append({
'word': text[i:j+1],
'start': i,
'end': j
})
j += 1
return results
def replace_sensitive_words(self, text, replace_char='*'):
"""替換敏感詞"""
sensitive_positions = self.find_all_sensitive_words(text)
if not sensitive_positions:
return text
result = list(text)
for pos in sensitive_positions:
for k in range(pos['start'], pos['end'] + 1):
result[k] = replace_char
return ''.join(result)3.3 優(yōu)化版:AC自動機
AC自動機(Aho-Corasick automaton)在Trie樹的基礎上增加了失敗指針,實現(xiàn)多模式串的高效匹配:
from collections import deque
class AhoCorasickNode:
__slots__ = ('children', 'fail', 'output')
def __init__(self):
self.children = {}
self.fail = None
self.output = [] # 存儲以此節(jié)點結尾的敏感詞
class AhoCorasickFilter:
def __init__(self):
self.root = AhoCorasickNode()
self._built = False
def add_word(self, word):
"""添加敏感詞"""
node = self.root
for char in word:
if char not in node.children:
node.children[char] = AhoCorasickNode()
node = node.children[char]
node.output.append(word)
self._built = False
def add_words(self, words):
for word in words:
self.add_word(word)
def _build_fail_pointers(self):
"""構建失敗指針(BFS)"""
queue = deque()
# 初始化第一層節(jié)點的失敗指針
for char, child in self.root.children.items():
child.fail = self.root
queue.append(child)
while queue:
current = queue.popleft()
for char, child in current.children.items():
queue.append(child)
# 尋找失敗指針
fail_node = current.fail
while fail_node is not None and char not in fail_node.children:
fail_node = fail_node.fail
if fail_node is None:
child.fail = self.root
else:
child.fail = fail_node.children[char]
# 合并輸出
child.output.extend(child.fail.output)
def search(self, text):
"""搜索文本中的所有敏感詞"""
if not self._built:
self._build_fail_pointers()
self._built = True
result = []
node = self.root
for i, char in enumerate(text):
# 沿著失敗指針查找匹配
while node is not self.root and char not in node.children:
node = node.fail
if char in node.children:
node = node.children[char]
else:
node = self.root
# 收集匹配結果
for word in node.output:
result.append({
'word': word,
'position': i - len(word) + 1
})
return result
def contains_sensitive_word(self, text):
return len(self.search(text)) > 0
def replace_sensitive_words(self, text, replace_char='*'):
matches = self.search(text)
if not matches:
return text
result = list(text)
for match in matches:
start = match['position']
end = start + len(match['word'])
for i in range(start, end):
result[i] = replace_char
return ''.join(result)四、第三方庫方案
4.1 使用better_profanity
from better_profanity import profanity
# 初始化
profanity.load_censor_words()
# 檢測
text = "You are a fool"
if profanity.contains_profanity(text):
print("包含敏感詞")
# 替換
censored_text = profanity.censor(text)
print(censored_text) # You are a ****
# 自定義敏感詞庫
custom_badwords = ['badword1', 'badword2']
profanity.load_censor_words(custom_badwords)4.2 使用ahocorasick庫
import ahocorasick
class PyAhocorasickFilter:
def __init__(self):
self.automaton = ahocorasick.Automaton()
self._built = False
def add_words(self, words):
for idx, word in enumerate(words):
self.automaton.add_word(word, (idx, word))
self._built = False
def build(self):
self.automaton.make_automaton()
self._built = True
def search(self, text):
if not self._built:
self.build()
result = []
for end_index, (idx, word) in self.automaton.iter(text):
start_index = end_index - len(word) + 1
result.append({
'word': word,
'start': start_index,
'end': end_index
})
return result4.3 其他相關庫
| 庫名 | 特點 | 適用場景 |
|---|---|---|
profanity-check | 基于機器學習 | 需要語義理解 |
alt-profanity-check | 輕量級 | 簡單場景 |
ngram-profanity | 支持模糊匹配 | 變形詞檢測 |
五、高級特性實現(xiàn)
5.1 支持跳過干擾字符
class AdvancedFilter:
def __init__(self, skip_chars=None):
self.skip_chars = skip_chars or {' ', '-', '_', '.'}
self.trie_filter = TrieSensitiveWordFilter()
def _normalize(self, text):
"""標準化文本,去除干擾字符"""
return ''.join(c for c in text if c not in self.skip_chars)
def contains_sensitive_word(self, text):
normalized = self._normalize(text)
return self.trie_filter.contains_sensitive_word(normalized)5.2 支持拼音/諧音檢測
# 使用 pypinyin 庫處理拼音
from pypinyin import lazy_pinyin
class PinyinSensitiveFilter:
def __init__(self):
self.pinyin_map = {}
def add_word(self, word):
# 同時添加中文和拼音形式的敏感詞
self.trie_filter.add_word(word)
pinyin = ''.join(lazy_pinyin(word))
self.trie_filter.add_word(pinyin)5.3 支持英文大小寫/變體處理
class CaseInsensitiveFilter:
def __init__(self):
self.trie_filter = TrieSensitiveWordFilter()
def add_word(self, word):
# 添加小寫版本
self.trie_filter.add_word(word.lower())
def contains_sensitive_word(self, text):
return self.trie_filter.contains_sensitive_word(text.lower())六、性能對比
| 方案 | 時間復雜度 | 空間復雜度 | 1000詞響應時間 | 適用場景 |
|---|---|---|---|---|
| 直接遍歷 | O(n*m) | O(m) | ~50ms | 小詞庫 |
| 正則表達式 | O(n*m) | O(m) | ~30ms | 中等詞庫 |
| Trie樹 | O(n) | O(m*k) | ~5ms | 大詞庫 |
| AC自動機 | O(n) | O(m*k) | ~3ms | 超大詞庫 |
| better_profanity | O(n) | O(m) | ~2ms | 通用場景 |
注:n為文本長度,m為敏感詞數(shù)量,k為平均詞長
七、完整實戰(zhàn)示例
class SensitiveWordDetectionSystem:
"""完整的敏感詞檢測系統(tǒng)"""
def __init__(self, word_file=None, skip_chars=None):
self.filter = AhoCorasickFilter()
self.skip_chars = skip_chars or {' ', '.', '-', '_', '*', '#'}
if word_file:
self.load_words_from_file(word_file)
def load_words_from_file(self, file_path):
"""從文件加載敏感詞庫"""
with open(file_path, 'r', encoding='utf-8') as f:
words = [line.strip() for line in f if line.strip()]
self.filter.add_words(words)
def preprocess_text(self, text):
"""預處理文本(移除干擾字符)"""
# 可選:移除干擾字符
# text = ''.join(c for c in text if c not in self.skip_chars)
# 可選:轉小寫
text = text.lower()
return text
def detect(self, text):
"""檢測文本"""
processed = self.preprocess_text(text)
return self.filter.search(processed)
def audit(self, text, strict=True):
"""內容審核"""
matches = self.detect(text)
result = {
'is_safe': len(matches) == 0,
'sensitive_words': [m['word'] for m in matches],
'count': len(matches),
'suggested_action': 'block' if strict and len(matches) > 0 else 'review'
}
return result
def censor(self, text, replace_char='*'):
"""敏感詞脫敏"""
processed = self.preprocess_text(text)
matches = self.filter.search(processed)
if not matches:
return text
# 需要映射回原始文本的位置
result = list(text)
# 簡化版:直接替換(實際應用需要處理位置映射)
for match in matches:
# 這里簡化處理
pass
return self.filter.replace_sensitive_words(processed, replace_char)
# 使用示例
if __name__ == "__main__":
# 初始化系統(tǒng)
system = SensitiveWordDetectionSystem()
system.filter.add_words(['敏感詞', '不良信息', '違規(guī)內容'])
# 測試文本
test_texts = [
"這是一條正常的消息",
"這里包含敏感詞,需要處理",
"用戶發(fā)送了不良信息內容"
]
for text in test_texts:
result = system.audit(text)
print(f"文本: {text}")
print(f"審核結果: {result}")
print("-" * 50)八、敏感詞庫管理建議
8.1 詞庫分類
sensitive_words/ ├── political.txt # 政治敏感 ├── porn.txt # 色情低俗 ├── violence.txt # 暴力恐怖 ├── abuse.txt # 人身攻擊 └── spam.txt # 垃圾廣告
8.2 詞庫維護策略
- 定期更新:建立詞庫更新機制
- 分級管理:按敏感程度分級處理
- 白名單機制:支持誤殺詞的快速恢復
- 版本控制:記錄詞庫變更歷史
九、總結與建議
9.1 方案選擇指南
- 小型項目(<100詞):使用正則或直接遍歷即可
- 中型項目(100-10000詞):推薦Trie樹方案
- 大型項目(>10000詞):必須使用AC自動機
- 快速開發(fā):使用better_profanity等成熟庫
9.2 注意事項
- 性能優(yōu)化:使用緩存、異步處理、批量檢測
- 誤殺控制:建立白名單和人工審核機制
- 編碼問題:統(tǒng)一使用UTF-8編碼
- 變形詞:需要考慮拼音、諧音、數(shù)字替代等
- 多語言:中英文混合檢測需要特殊處理
9.3 擴展方向
- 結合NLP語義理解,減少誤殺
- 支持圖片中的文字檢測(OCR)
- 實時監(jiān)控和告警系統(tǒng)
- 用戶行為分析和分級
通過合理選擇和優(yōu)化敏感詞檢測方案,可以有效保障平臺內容安全,同時保持良好的用戶體驗。
以上就是Python實現(xiàn)敏感詞檢測的多種方案的詳細內容,更多關于Python敏感詞檢測方案的資料請關注腳本之家其它相關文章!
相關文章
示例詳解Python3 or Python2 兩者之間的差異
這篇文章主要介紹了Python3 or Python2?示例詳解兩者之間的差異,在本文中給大家介紹的非常詳細,需要的朋友可以參考下2018-08-08

