日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字典树实现_学习NLP的第3天——字典树

發(fā)布時間:2023/12/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字典树实现_学习NLP的第3天——字典树 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

通過《自然語言處理入門》(何晗)的第2章來學(xué)習(xí)一下分詞的常用算法,因此以下的實現(xiàn)方法都是通過HanLP實現(xiàn)的。這里主要記錄我在學(xué)習(xí)過程中整理的知識、調(diào)試的代碼和心得理解,以供其他學(xué)習(xí)的朋友參考。

字符串集合常用字典樹(Trie樹)存儲,這是一種字符串上的樹形數(shù)據(jù)結(jié)構(gòu)。

字典樹中每條邊都對應(yīng)一個字,從根節(jié)點往下的路徑構(gòu)成一個個字符串。字典樹并不直接在節(jié)點上存儲字符串,而是將詞典視作根節(jié)點到某節(jié)點之間的一條路徑,并在終點節(jié)點上做個“該節(jié)點對應(yīng)詞語的結(jié)尾”的標(biāo)記。

字符串是一條路徑,要查詢一個單詞,只需順著這條路徑從歸根節(jié)點往下走。如果能走到特殊標(biāo)記的節(jié)點,則說明該字符串在集合中,否則說明不存在。

圖片來自《自然語言處理入門》(何晗)

例如,上圖中的藍色標(biāo)記著該節(jié)點是一個詞的結(jié)尾,數(shù)字是認為的編號。如“入門”、“自然人”等結(jié)束節(jié)點為藍色的路徑都可以成為詞,而“自然語”等結(jié)束節(jié)點為白色的路徑則不能成為詞。

字典樹的節(jié)點實現(xiàn)

每個節(jié)點都應(yīng)該知道自己的子節(jié)點與對應(yīng)的邊,以及自己是否對應(yīng)一個詞。

我們用None來表示該節(jié)點不對應(yīng)詞語。

節(jié)點的Python實現(xiàn)如下:

class Node(object): def __init__(self, value): self._children = {} # 子節(jié)點存儲變量 self._value = value # 當(dāng)前節(jié)點的值 def _add_child(self, char, value, overwrite=False): child = self._children.get(char) if child is None: # 判斷當(dāng)前節(jié)點是否已經(jīng)存在字符char對應(yīng)的child child = Node(value) self._children[char] = child elif overwrite: # 根據(jù)overwrite判斷是否覆蓋child的值 child._value = value return child

字典樹的增刪改查實現(xiàn)

只要將以上節(jié)點連到根節(jié)點上,就得到了字典樹。根節(jié)點繼承自普通節(jié)點,并增加了一些面向用戶的公開方法。因此,只要拿到根節(jié)點,就能抓住整棵字典樹。

從確定有限狀態(tài)自動機(DFA)的角度來講,每個節(jié)點都是一個狀態(tài),狀態(tài)表示當(dāng)前已查詢到的前綴。

有限狀態(tài)自動機(DFA)

有限狀態(tài)自動機(deterministic finite automaton, DFA)是一個能實現(xiàn)狀態(tài)轉(zhuǎn)移的自動機。對于一個給定的屬于該自動機的狀態(tài)和一個屬于該自動機字母表Σ的字符,它都能根據(jù)事先給定的轉(zhuǎn)移函數(shù)轉(zhuǎn)移到下一個狀態(tài)(這個狀態(tài)可以是先前那個狀態(tài))。每次輸入都會引起狀態(tài)的改變或者不變。

字典樹的Python實現(xiàn)如下:

class Trie(Node): def __init__(self): super().__init__(None) def __contains__(self, key): return self[key] is not None def __getitem__(self, key): state = self for char in key: # 遍歷字符串中的每一個字符 state = state._children.get(char) # 一直依據(jù)路徑找到目標(biāo)詞 if state is None: return None return state._value def __setitem__(self, key, value): state = self for i, char in enumerate(key): # 枚舉字符串中的每一個字符及其位置坐標(biāo) if i < len(key) - 1: # 若當(dāng)前詞不是結(jié)尾詞 state = state._add_child(char, None, False) else: # 若當(dāng)前詞是結(jié)尾詞 state = state._add_child(char, value, True)

運行測試

我們參考書中方法對以上的字典樹做如下測試:

if __name__ == '__main__': trie = Trie() # 增 trie['自然'] = 'nature' trie['自然人'] = 'human' trie['自然語言'] = 'language' trie['自語'] = 'talkto oneself' trie['入門'] = 'introduction' print(trie['自然']) # 刪 trie['自然'] = None print(trie['自然']) # 改 print(trie['自然語言']) trie['自然語言'] = 'human language' print(trie['自然語言'])

運行結(jié)果

natureNonelanguagehuman language

字典樹的使用是為了提高字典的查詢速度,優(yōu)化分詞算法的效率。

本文使用教材:《自然語言處理入門》(何晗):2.4.1 - 2.4.3

本文中代碼大部分引自該書中的代碼

總結(jié)

以上是生活随笔為你收集整理的字典树实现_学习NLP的第3天——字典树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。