自然语言处理入门指北 之 one-hot
自然語言(Natural Language)通常是指一種自然地隨文化演化的語言,例如,漢語、英語、日語都是自然語言的例子。與編程語言等為計算機而設的“人造”語言相對,自然語言無法直接被計算機等“理解”,在這個前提下,如何讓計算機認識、學習乃至理解自然語言就成了一個重要的研究方向:自然語言處理( Natural Language Processing, NLP) 。
簡而言之,自然語言處理旨在人與機器的直接通信,這需要一個復雜的系統做支撐,尤其是該系統必須能夠正確的“表示”自然語言。以漢字為例,雖然計算機通過漢字內碼擴展規范(GBK字庫)可以正常地顯示漢字,但對于我們要設計的通信系統而言還遠遠不夠,因為漢字無法直接參與計算,繼而無法量化文本,導致計算機無法在“數值”上認識漢字,僅僅將其當作簡單的字符,失去了學習、理解漢字的基礎。為了更好地發揮計算機的計算功能,用數值表示漢字就成了亟待解決的問題,這也是計算機語言學(Computational Linguistics)的由來。
對于漢字的表示,舉個簡單的例子,可以直接對中文字庫進行id映射,例如將“我”映射為“0”,將“是”映射為“1”,這樣當文本中包含“我”和“是”的時候,直接用對應的id做替換,以此類推,“我是中國人”就可以映射為“12345”,這樣就繞過了對中文的處理,轉變為處理相應的數字id,并且相應的數字id可直接參與相關統計量的計算,例如需要計算“我是中國人”與“我是人”的相似度,可以先將文本映射為向量“[1,2,3,4,5]”與向量“[1,2,5]”,然后再計算。顯然,這種映射方式有個致命的問題:當文本長度不一致的時候,向量維度也不一致,即不同長度文本的表示向量不在一個特征空間內,無法直接參與計算。可能這時候有些人會考慮使用補位的方法來解決文本長度不一致的問題,例如將空字符id設置為0并使用空字符補位短文本:“我是人”->“我是人[空字符][空字符]”->向量“[1,2,5,0,0]”,如此就將“我是人”映射至“我是中國人”的特征空間內,以實現相關計算問題。
簡單的補位粗暴地解決了計算問題,但又帶來了其他隱患,還是前文的例子,計算“我是中國人”與“我是人”的相似度使用補位方法就轉換為計算向量“[1,2,3,4,5]”與向量“[1,2,5,0,0]”,使用cos可得到相似度結果:0.4924(計算公式如下)
上面的例子使用了詞袋模型(Bag of Words)的思想:將自然語言文本的每個詞作為一個特征,每個詞互不相關,文本對應的特征向量即每個詞的特征的組合。這種思路雖然簡單,但是可以有效表示全部文本信息。本文的主角one-hot就是根據詞袋模型設計而來,與前文的例子同樣十分簡單,但在文本表示思路上略有不同。
one-hot開始就考慮了文本特征空間一致的問題,在文本編碼時首先將待處理文本中全部字/詞整理為詞典,隨后根據某個字在詞典中的位置對其進行編碼,例如“我”在詞典中的位置為k(詞典編號從1開始),詞典大小為n,則設立一個n維向量,第k維設置為1,其余維全都置0。還是前文的例子,假如詞典為[我,是,中,國,人],則“我”的編碼為“[1,0,0,0,0]”,以此類推:是[0,1,0,0,0]、中[0,0,1,0,0]、國[0,0,0,1,0]、人[0,0,0,0,1],如此,“我是中國人”可將每個字的編碼簡單組合在一起編碼為“[1,1,1,1,1]”,同樣“我是人”可編碼為“[1,1,0,0,1]”,二者維度相同,實際維度由詞典大小決定。依照one-hot編碼計算相似度,其結果為0.7746(計算公式如下)
如果將兩個結果0.4924與0.7746看作“我是中國人”與“我是人”相似的概率,從出現的字本身而言one-hot的結果0.7746更為合理,因為二者字的組成十分接近,但是邏輯上不如初始例子的結果,因為二者在概念上的差距使得0.4924更為合理。綜上,我們可以根據不同的任務環境選擇更合適的文本編碼方法以取得更好的結果。
總而言之,因為詞袋模型的弊端,導致one-hot編碼忽略了詞與詞之間的關聯,以至于忽視了語法和語境信息,再加上本身編碼長度由詞典大小決定,若詞典很大,則每個詞的編碼極度稀疏,不利于計算,且編碼文本時僅考慮出現的字,從而不同字數的同義詞產生不同的編碼,相近字數的反義詞產生相近的編碼,影響最終的計算結果。
one-hot編碼作為文本表示的鼻祖,不能忽視其為文本表示帶來的啟發,包括目前的深度學習模型與預訓練模型,都參考了one-hot編碼的思想,只不過利用了一些小技巧,將one-hot編碼映射為更低維度、更高質量的word-embedding,這就是另外的故事了。
總結
以上是生活随笔為你收集整理的自然语言处理入门指北 之 one-hot的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 共享停车位
- 下一篇: 【Flask】快速入门后台写接口【API