基于字典樹可視化 COCA20000 詞匯

COCA20000 是美國當代語料庫中最常見的 20000 個詞匯,不過實際上有一些重復,去重之后大概是 17600+ 個,這些單詞是很有用,如果能掌握這些單詞,相信會對英語的能力有一個較大的提升。我很早就下載了這些單詞,并且自己編寫了一個背單詞的簡易工具,如果有需要的同學,可以去看我的博客中搜索。今天這篇博客是利用字典樹來堆單詞的一個可視化。

字典樹可視化詞匯

下面就是一顆簡單的 4 個單詞的字典樹,這個東西用來檢索是很快的,這里我把最后的單詞作為樹的葉子節點。隨著單詞的不斷增加,整個樹也會不斷的膨脹,不過這樣就難以閱讀了,所以我最終選擇是把樹的排列方向變成從又到右的形式。我之后要實現的字典樹和下面這個沒有什么本質的區別,只是更大一些而已,利用的數據就是 COCA 20000 的單詞。

在這里插入圖片描述

上面這個圖形是使用 mermaid 繪制的,不過最終我采用的是 dot 語言(繪圖指令就在下面),因為 mermaid 可能會遇到性能問題。實際上,dot 語言也是遇到了性能問題,因為單詞實在是太多了,導致最后的圖形太大了。我想了一些可能的優化措施,比如根據首字母來區分單詞,這樣的化加上大小寫總共 52 個字母,可以把大的樹分成 52 個小一點的樹。不過,我也不是真的要去看這個樹,所以就沒有這樣做。

在這里插入圖片描述

代碼處理

下面是全部的處理代碼。

"""
字典樹
目的是生成 COCA 單詞的字典樹,但是也可以用于其他單詞或者詞語(包括英語)。
"""
import jsonclass Node:"""字典樹的一個節點,包含這個節點的值,以及它下面的節點,以及是否是一個單詞的結尾。"""def __init__(self, val, is_end) -> None:self.val = valself.is_end = is_endself.children = {}def set_is_end(self) -> None:"""有些短的單詞要重新設置,否則無法和長的區分開來,例如:are, area"""self.is_end = Trueclass DictTree:"""字典樹"""def __init__(self):self.root = Node('/', False)self.stack = [] # 用來保存單詞def append(self, word: str):"""向字典樹中添加一個單詞: 獲取當前樹的根節點:node = self.root遍歷這個詞的每一個字符 c,1. 如果該字符在當前樹的子樹中,則把當前樹的子樹指向當前樹: node = node.children[c]如果當前字符 c 是最后一個字符,那么: node.is_end = True2. 如果該字符不在當前樹的子樹中,那么新建立一個節點,如果當前字符 c 是最后一個字符:is_end = True把它添加到當前樹的子樹中, node.children[c] = Node(c, is_end)"""node = self.rootfor i, c in enumerate(word):is_end = not i != len(word)-1if node.children.get(c):node = node.children[c]if is_end:node.set_is_end()else:node.children[c] = Node(c, is_end)node = node.children[c]def dumps(self) -> dict:"""序列化成字典對象"""return {"/": self.__dump(self.root)}def __dump(self, node: Node) -> dict:"""序列化成字典對象的內部方法,一個簡單但是并不優雅的遞歸"""ret = {}self.stack.append(node.val)if not node.children:ret["word"] = "".join(self.stack[1:])for k, c in node.children.items():ret[k] = self.__dump(c)self.stack.pop()return ret# 生成dot描述
# 層序遍歷 tips: 使用隊列
def BFS_to_dot(tree) -> str:"""將樹結構以層序遍歷的方式轉換為Dot語言表示的圖形。Dot語言用于描述圖形結構,本函數特別適用于將樹結構可視化。:param tree: 輸入的樹結構,通常是一個字典或類似字典的對象,其中鍵值對表示節點及其子節點。:return: 返回一個表示樹結構的Dot語言字符串。"""if not tree:returnqueue = [tree["/"]]          # 把樹的根本身作為第一個節點加入隊列count = 0                    # 子節點計數parent_count = 0             # 父節點計數parent_map = {0: "/"}        # 記錄父節點序號和它的值nodes = ['n_0 [label="/"]']  # 點集edges = []                   # 邊集while queue:node = queue.pop(0)if isinstance(node, dict):for val, child in node.items():queue.append(child)count += 1v = val if val != "word" else childparent_map[count] = vdot_node = f'n_{count} [label="{v}"]'dot_edge = f"n_{parent_count} -> n_{count};"nodes.append(dot_node)edges.append(dot_edge)parent_count += 1node_str = "\n".join(nodes)edge_str = "\n".join(edges)return f"digraph G {{\nrankdir=LR;\n{node_str};\n{edge_str}\n}}"if __name__ == "__main__":in_file = r"C:\Users\25735\Desktop\DragonEnglish\data\raw_txt\coca_no_order.txt"out_json_file = r"C:\Users\25735\Desktop\DragonEnglish\data\raw_txt\coca_dt_tree.json"out_dot_file = r"C:\Users\25735\Desktop\DragonEnglish\data\raw_txt\coca_dt_tree.dot"dt = DictTree()with open(in_file, "r", encoding="utf-8") as file:for word in [line.strip() for line in file.readlines()]:dt.append(word)dt_dumps = dt.dumps()# 序列化json寫入with open(out_json_file, "w", encoding="utf-8") as file:json.dump(dt_dumps, file)# dot寫入with open(out_dot_file, "w", encoding="utf-8") as file:file.write(BFS_to_dot(dt_dumps))print("EOF")

生成的文件
這里生成的 json 文件是壓縮形式的,如果格式化的化,就超過 4m 了。
請添加圖片描述

渲染圖形

因為我安裝了 graphviz 的插件,所以我直接在 VSCode 查看生成的 dot 文件時,它就在渲染了,不過渲染失敗了。請添加圖片描述

因為這個文件太大了,有十幾萬行(定義的節點就有幾萬個了)。

請添加圖片描述

所以還是在本地來生成,我已經配置好了 graphviz 的環境了。一開始是生成的 png 格式,不過它提示分辨率有問題,因為節點太多了,導致生成的圖形其實沒法觀看了。所以最終還是選擇了 svg 和 pdf 格式,其中 pdf 格式生成的特別慢,至少是 20 分鐘以上了。

請添加圖片描述

生成的 svg 和 pdf

在這里插入圖片描述

這兩個文件的渲染都特別費勁,我的電腦打開有點吃力了。

請添加圖片描述

請添加圖片描述

對它的理解

如果是這 20000 個單詞,它們的字母數是 150011 個,這是一個十分龐大的數字了。但是觀察上面的字典樹可以發現,其實有些單詞是含有共同部分的,在計算的時候可以省去這部分,對于字典樹來說就是計算其中的節點數就行了。因為我把完整的單詞也算做節點了,所以要只計算單個字母的節點,這里我使用正則表達式來計算,最終的結果是: 54457 個。我覺得它對于我們記憶單詞有一個很好的啟示,那就是我們記憶單詞并不是孤立的記憶每一個單詞,每個單詞之間是有聯系的,隨著記憶的單詞越多,對于單詞的掌握應該也是越來越熟悉的,但是太少了還是看不出來。而且這里只有前綴的聯系,實際上還包括后綴的聯系等。我會把這篇博客中產生的文件上傳到 CSDN 中,如果有感興趣的同學也可以自己下載體驗。

請添加圖片描述
請添加圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/21310.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/21310.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/21310.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Django的博客系統之用HayStack連接elasticsearch增加搜索功能(五)

上一篇:搭建基于Django的博客系統數據庫遷移從Sqlite3到MySQL(四) 下一篇:基于Django的博客系統之增加類別導航欄(六) 功能概述 添加搜索框用于搜索博客。 需求詳細描述 1. 添加搜索框用于搜索博客 描…

【數據密集型系統設計】軟件系統的可靠性、可伸縮性、可維護性

文章目錄 一. 數據密集型程序的特點以及遇到的問題二. 可靠性 : 即使出現問題,也能繼續正確工作1 硬件故障2. 軟件錯誤3. 人為錯誤 二. 可伸縮性1. 描述負載與推特的例子2. 描述性能-延遲和響應時間3. 應對負載的方法 四. 可維護性1. 可操作性:人生苦短&…

如何解決Mac系統創建/home目錄提示Read-Only filesystem(補充)?

繼昨日發布的博文之后,有小伙伴私我說: sudo mount -uw /命令報錯:mount_apfs: volume could not be mounted: Permission denied mount: / failed with 66 今天補充一下昨天的文章,昨天的文章我沒有注明是Mac什么系統的&#x…

Chromebook Plus中添加了Gemini?

Chromebook Plus中添加了Gemini? 前言 就在5月29日,谷歌宣布了一項重大更新,將其Gemini人工智能技術集成到Chromebook Plus筆記本電腦中。這項技術此前已應用于谷歌的其他設備。華碩和惠普已經在市場上銷售的Chromebook Plus機型,…

mysql binlog查看指定數據庫

1.mysql binlog查看指定數據庫的方法 MySQL 的 binlog(二進制日志)主要記錄了數據庫上執行的所有更改數據的 SQL 語句,包括數據的插入、更新和刪除等操作。但直接查看 binlog 并不直觀,因為它是以二進制格式存儲的。為了查看 bin…

電腦缺少dll文件怎么解決,分享幾種靠譜的解決方法

在現代科技高度發達的時代,電腦已經成為我們生活和工作中不可或缺的工具。然而,在使用電腦的過程中,我們可能會遇到一些問題,其中之一就是電腦丟失dll文件。那么,當我們面臨這樣的問題時,應該如何解決呢&am…

云原生架構案例分析_1.某旅行公司云原生改造

隨著云計算的普及與云原生的廣泛應用,越來越多的從業者、決策者清晰地認識到“云原生化將成為企業技術創新的關鍵要素,也是完成企業數字化轉型的最短路徑”。因此,具有前瞻思維的互聯網企業從應用誕生之初就扎根于云端,謹慎穩重的…

BMC壓力測試腳本

說明 對于研發階段而言,需要對BMC執行壓力測試,可以提前發現問題,修復問題,提高產品穩定性。 大體而言,需要做到幾個方面: 1.預先發現是否會造成BMC hang機。2.進程是否會發生重啟,運行異常3.進程是否會…

SpringMVC:轉發和重定向

1. 請求轉發和重定向簡介 參考該鏈接第9點 2. forward 返回下一個資源路徑,請求轉發固定格式:return "forward:資源路徑"如 return "forward:/b" 此時為一次請求返回邏輯視圖名稱 返回邏輯視圖不指定方式時都會默認使用請求轉發in…

【Qt秘籍】[008]-Qt中的connect函數

在Qt框架中,connect函數是一個非常核心的函數,用于實現信號(Signals)和槽(Slots)之間的連接,它是Qt信號槽機制的關鍵所在。信號槽機制是一種高級的通信方式,允許對象在狀態改變時通知…

ChatGPT-3

ChatGPT-3是OpenAI開發的先進人工智能聊天機器人程序,它是基于 GPT-3.5 架構的大型語言模型,并通過強化學習進行了訓練。這項技術代表了自然語言處理領域的一個重要里程碑,具有以下顯著特點和功能: 強大的語言理解和生成能力&…

代碼隨想三刷數組篇

代碼隨想三刷數組篇1 704. 二分查找題目代碼27. 移除元素題目代碼977.有序數組的平方題目代碼209.長度最小的子數組題目代碼59.螺旋矩陣II題目代碼704. 二分查找 題目

牛客網刷題 | BC114 圣誕樹 (不理解)

目前主要分為三個專欄,后續還會添加: 專欄如下: C語言刷題解析 C語言系列文章 我的成長經歷 感謝閱讀! 初來乍到,如有錯誤請指出,感謝! 這道題沒搞懂 也沒找到視…

Nginx源碼編譯安裝

Nginx NginxNginx的特點Nginx的使用場景Nginx 有哪些進程 使用源碼編譯安裝Nginx準備工作安裝依賴包編譯安裝Nginx檢查、啟動、重啟、停止 nginx服務配置 Nginx 系統服務方法一:方法二: 訪問Nginx頁面 升級Nginx準備工作編譯安裝新版本Nginx驗證 Nginx N…

【HarmonyOS】Stage 模型 - UIAbility 的啟動模式

Stage 模型這樣的應用,它在啟動的時候會先準備 Ability Stage 舞臺,接著呢,就可以基于它去創建 UIAbility 的實例,并去啟動它。 UIAbility 組件啟動模式 有四種: singletonstandardmultitonspecified 修改模塊的 mod…

SSMP整合案例第五步 在前端頁面上拿到service層調數據庫里的數據后列表

在前端頁面上列表 我們首先看看前端頁面 我們已經把數據傳入前端控制臺 再看看我們的代碼是怎么寫的 我們展示 數據來自圖dataList 在這里 我們要把數據填進去 就能展示在前端頁面上 用的是前端數據雙向綁定 axios發送異步請求 函數 //鉤子函數,VUE對象初始化…

【四大組件】-- 活動 Activity

目錄 活動活動是什么活動的相關操作手動創建活動活動中使用Toast活動中使用Menu銷毀一個活動 使用Intent實現活動間啟動顯示啟動隱式啟動 活動間數據傳遞活動的生命周期返回棧活動的狀態活動的生存期 活動的啟動流程活動的回收和重建如何在活動銷毀前保存狀態 活動的啟動模式st…

設計模式(十四)行為型模式---訪問者模式(visitor)

文章目錄 訪問者模式簡介分派的分類什么是雙分派?結構UML圖具體實現UML圖代碼實現 優缺點 訪問者模式簡介 訪問者模式(visitor pattern)是封裝一些作用于某種數據結構中的元素的操作,它可以在不改變這個數據結構(實現…

紅隊內網攻防滲透:內網滲透之windows內網權限提升技術:手工篇

紅隊內網攻防滲透 1. 內網權限提升技術1.1 windows內網權限提升技術--手工篇1.1.1 Web到Win-系統提權-人工操作1.1.1.1 信息收集1.1.1.2 補丁篩選1.1.1.3 EXP獲取執行1.1.2 Web到Win-系統提權-土豆家族1.1.2.1 Test in:Windows 10/11(1809/21H2)1.1.2.2 Test in:Windows Se…

全新市場階段,Partisia BlockChain 將向 RWA、DeFi 等領域布局

Partisia Blockchain 是一個全新范式的 Layer1,該鏈通過 MPC 方案來構建鏈上隱私方案,同時該鏈通過系列獨特且創新的設計,旨在進一步解決目前 Web3 中所面臨的不可能三角問題,包括安全性、互操作性和可擴展性,為更多的…