整理的敏感词解决思路
敏感詞的檢測與替換,是一個很常見的需求,因此搜了下網(wǎng)上的大致實現(xiàn)方案,這里簡單整理下。
- 簡單替換
- 正則替換
- DFA
- 基于樸素貝葉斯分類算法
簡單替換
string = "hello world" string.replace("o wo", "***")類似于上面的代碼,我們會使用一個敏感詞列表,來對目標(biāo)字符串進行檢測與替換,比較適合于敏感詞列表和待檢測目標(biāo)字符串都比較小的場景。
正則替換
re.sub("|".join(keywords), "***", text)非要扒開來說,和上面的正則替換是類似的,只不過用了專門的 re 庫來做,效率會高一點。本質(zhì)上沒什么大的變化。
DFA
典型范例:Trie樹。我去年有幸用python寫了一個比較low的版本。不適用于中文場景,然后今日看了hutaishi的代碼,覺得不賴,拿過來改了改,以后或許會用得到。
import java.util.HashMap; import java.util.Map;/*** 前綴樹實現(xiàn)* 特點:* 1. 根節(jié)點不包含字符,除根節(jié)點外每一個子節(jié)點都包含一個字符* 2. 從根節(jié)點到某一個節(jié)點,路徑即為對應(yīng)的單詞* 3. 每個節(jié)點的所有子節(jié)點包含的字符各不相同* 4. 從第一字符開始有連續(xù)重復(fù)的字符只占用一個節(jié)點,如to,ten,第一個節(jié)點都是t* * 應(yīng)用:* 1. 前綴匹配* 2. 字符串檢索* 3. 詞頻統(tǒng)計* 4. 字符串排序?第一次知道還有這么個功能。*/ public class TrieTree {// 根節(jié)點private TrieNode rootNode = new TrieNode();// 判斷是否為一個符號private boolean isSymbol(char c) {int ic = (int)c;// 0x2e80 - 0x9fff 東亞文字范圍 忽略用Apache的CharUtils的工具判斷return !(ic>0x2e80 && ic<0x9fff);}private void addWord(String lineText) {TrieNode temNode = rootNode;for(int i=0; i<lineText.length(); i++) {Character c = lineText.charAt(i);if(isSymbol(c)) {continue;}TrieNode node = temNode.getSubNode(c);if (node == null) {node = new TrieNode();temNode.addSubNode(c, node);}temNode = node;if(i == lineText.length()-1) {temNode.setKeywordEnd(true);}}}public String filter(String text) {if("".equals(text)) {return text;}String replacement = "***";StringBuilder result = new StringBuilder();TrieNode temNode = rootNode;int begin = 0; // 開始指針int position = 0; // 位移指針while(position < text.length()) {char c = text.charAt(position);// 空格或者非東亞文字并且不是字母字符直接跳過if(isSymbol(c)) {if (temNode == rootNode) {result.append(c);begin++;}position++;continue;}temNode = temNode.getSubNode(c);if(temNode == null) {// 以begin開始的字符串不會存在敏感字符result.append(text.charAt(begin));// 跳到下一個字符進行測試position = begin + 1;begin = position;// 回到前綴樹的根節(jié)點temNode = rootNode;} else if(temNode.isKeywordEnd()) {// 發(fā)現(xiàn)敏感詞,從begin到position的位置進行替換result.append(replacement);position ++;begin = position;temNode = rootNode;} else {++position;}}result.append(text.substring(begin));return result.toString();}public static void main(String[] args) {TrieTree tree = new TrieTree();tree.addWord("賭博");tree.addWord("春天來了");System.out.println(tree.filter("春"));System.out.println(tree.filter("春夏秋冬"));System.out.println(tree.filter("黃賭博"));System.out.println(tree.filter("春天"));System.out.println(tree.filter("冬天來了,春天來了,夏天還會遠嗎"));}class TrieNode{private boolean end = false;private Map<Character, TrieNode> subNodes = new HashMap<Character, TrieNode>();void addSubNode(Character key, TrieNode node) {subNodes.put(key, node);}TrieNode getSubNode(Character key) {return subNodes.get(key);}boolean isKeywordEnd() {return end;}void setKeywordEnd(boolean end) {this.end = end;}public int getSubNodeCount() {return this.subNodes.size();}}}運行結(jié)果如下:
春 春夏秋冬 黃*** 春天 冬天來了,***,夏天還會遠嗎這個應(yīng)該算是一個比較不錯的范例了,實操性比較強。
樸素貝葉斯分類算法
寫過一個使用樸素貝葉斯分類算法實現(xiàn)的一個敏感詞檢測的程序,沒有應(yīng)用到線上環(huán)境,所以不敢保證準(zhǔn)確度。更為關(guān)鍵的是:
先驗概率很重要,也就是初識敏感詞列表要有很高的準(zhǔn)確度才可以。
鏈接如下:Golang+PHP樸素貝葉斯分類 敏感詞檢測
小結(jié)
忘了是聽誰說的了,人不可能學(xué)會所有知識,但整理、總結(jié)會讓智慧得到升華。這里整理了網(wǎng)上常見的敏感詞檢測相關(guān)的內(nèi)容,肯定還有沒寫進來的好的方案,到時候遇到了再來補充。
參考鏈接:
1 https://www.jianshu.com/p/c124b0d6ebb0
2 https://my.oschina.net/hutaishi/blog/885356
總結(jié)
以上是生活随笔為你收集整理的整理的敏感词解决思路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows10下安装QT5.14.2
- 下一篇: 将小数点后的0去掉