一、文本表示
文本表示的意思是把字詞處理成向量或矩陣,以便計算機能進行處理。文本表示是自然語言處理的開始環節。
文本表示按照細粒度划分,一般可分為字級別、詞語級別和句子級別的文本表示。字級別(char level)的如把“鄧紫棋實在太可愛了,我想養一只”這句話拆成一個個的字:{鄧,紫,棋,實,在,太,可,愛,了,我,想,養,一,只},然后把每個字用一個向量表示,那么這句話就轉化為了由14個向量組成的矩陣。
文本表示分為離散表示和分布式表示。離散表示的代表就是詞袋模型,one-hot(也叫獨熱編碼)、TF-IDF、n-gram都可以看作是詞袋模型。分布式表示也叫做詞嵌入(word embedding),經典模型是word2vec,還包括后來的Glove、ELMO、GPT和最近很火的BERT。
這篇文章介紹一下文本的離散表示。
二、詞袋模型
假如現在有1000篇新聞文檔,把這些文檔拆成一個個的字,去重后得到3000個字,然后把這3000個字作為字典,進行文本表示的模型,叫做詞袋模型。這種模型的特點是字典中的字沒有特定的順序,句子的總體結構也被舍棄了。下面分別介紹詞袋模型中的one-hot、TF-IDF和n-gram文本表示方法。
(一)one-hot
看一個簡單的例子。有兩句話“鄧紫棋太可愛了,我愛鄧紫棋”,“我要看鄧紫棋的演唱會”,把這兩句話拆成一個個的字,整理得到14個不重復的字,這14個字決定了在文本表示時向量的長度為14。
下面這個表格的第一行是這兩句話構成的一個詞袋(或者說字典),有14個字。要對兩句話進行數值表示,那么先構造一個2×14的零矩陣,然后找到第一句話中每個字在字典中出現的位置,把該位置的0替換為1,第二句話也這樣處理。只管字出現了沒有(出現了就填入1,不然就是0),而不管這個字在句子中出現了幾次。
下面表格中的二、三行就是這兩句話的one-hot表示。
鄧 |
紫 |
棋 |
太 |
可 |
愛 |
了 |
我 |
要 |
看 |
的 |
演 |
唱 |
會 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
第一個問題是數據稀疏和維度災難。數據稀疏也就是向量的大部分元素為0,如果詞袋中的字詞達數百萬個,那么由每篇文檔轉換成的向量的維度是數百萬維,由於每篇文檔去重后字數較少,因此向量中大部分的元素是0。而且對數百萬維的向量進行計算是一件比較蛋疼的事。
但是這樣進行文本表示有幾個問題。可見,盡管兩個句子的長度不一樣,但是one-hot編碼后長度都一樣了,方便進行矩陣運算。
第二個問題是沒有考慮句中字的順序性,假定字之間相互獨立。這意味着意思不同的句子可能得到一樣的向量。比如“我太可愛了,鄧紫棋愛我”,“鄧紫棋要看我的演唱會”,得到的one-hot編碼和上面兩句話的是一樣的。
第三個問題是沒有考慮字的相對重要性。這種表示只管字出現沒有,而不管出現的頻率,但顯然一個字出現的次數越多,一般而言越重要(除了一些沒有實際意義的停用詞)。
接下來用TF-IDF來解決字的相對重要性問題。
(二)TF-IDF
TF-IDF用來評估字詞對於文檔集合中某一篇文檔的重要程度。字詞的重要性與它在某篇文檔中出現的次數成正比,與它在所有文檔中出現的次數成反比。TF-IDF的計算公式為:
下面一步步來理解。
1 TF——詞頻
TF(term frequency),即詞頻,用來衡量字在一篇文檔中的重要性,計算公式為:
首先統計字典中每個字在句子中出現的頻率:
鄧 |
紫 |
棋 |
太 |
可 |
愛 |
了 |
我 |
要 |
看 |
的 |
演 |
唱 |
會 |
2 |
2 |
2 |
1 |
1 |
2 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
為了防止數值過大,將其歸一化,其中下表的二、三行構成的就是TF值矩陣。可以看到,第一句話中“鄧、紫、棋、愛”這4個字對應的值更大,在第一句中更重要。
鄧 |
紫 |
棋 |
太 |
可 |
愛 |
了 |
我 |
要 |
看 |
的 |
演 |
唱 |
會 |
0.14 |
0.14 |
0.14 |
0.07 |
0.07 |
0.14 |
0.07 |
0.07 |
0 |
0 |
0 |
0 |
0 |
0 |
0.07 |
0.07 |
0.07 |
0 |
0 |
0 |
0 |
0.07 |
0.07 |
0.07 |
0.07 |
0.07 |
0.07 |
0.07 |
2 IDF——逆文檔頻率
IDF((inverse document frequency),叫做逆文檔頻率,衡量某個字在所有文檔集合中的常見程度。當包含某個字的文檔的篇數越多時,這個字也就爛大街了,重要性越低。計算公式為:
計算出來的IDF矩陣如下表。值為負或0,因為這個例子比較極端,只有兩句話,所以得到了這個極端的結果。“鄧、紫、棋、我”這四個字由於在兩句話中都出現了,所以得到的IDF值較小。
鄧 |
紫 |
棋 |
太 |
可 |
愛 |
了 |
我 |
要 |
看 |
的 |
演 |
唱 |
會 |
-0.41 |
-0.41 |
-0.41 |
0 |
0 |
0 |
0 |
-0.41 |
0 |
0 |
0 |
0 |
0 |
0 |
最后得到TF-IDF = TF × IDF,這里就不再計算了。
TF-IDF的思想比較簡單,但是卻非常實用。然而這種方法還是存在着數據稀疏的問題,也沒有考慮字的前后信息。
(三)n-gram
上面詞袋模型的兩種表示方法假設字與字之間是相互獨立的,沒有考慮它們之間的順序。於是引入n-gram(n元語法)的概念。n-gram是從一個句子中提取n個連續的字的集合,可以獲取到字的前后信息。一般2-gram或者3-gram比較常見。
比如“鄧紫棋太可愛了,我愛鄧紫棋”,“我要看鄧紫棋的演唱會”這兩個句子,分解為2-gram詞匯表:
{鄧,鄧紫,紫,紫棋,棋,棋太,太,太可,可,可愛,愛,愛了,了,了我,我,我愛,愛鄧,我要,要,要看,看鄧,棋的,的,的演,演,演唱,唱會,會}
於是原來只有14個字的1-gram字典(就是一個字一個字進行划分的方法)就成了28個元素的2-gram詞匯表,詞表的維度增加了一倍。
結合one-hot,對兩個句子進行編碼得到:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1]
也可以結合TF-IDF來得到文本表示,這里不再計算。
這種表示方法的好處是可以獲取更豐富的特征,提取字的前后信息,考慮了字之間的順序性。
但是問題也是顯而易見的,這種方法沒有解決數據稀疏和詞表維度過高的問題,而且隨着n的增大,詞表維度會變得更高。
三、總結
文本的離散表示存在着數據稀疏、向量維度過高、字詞之間的關系無法度量的問題,適用於淺層的機器學習模型,不適用於深度學習模型。
參考資料:
1、《Python深度學習》
2、https://www.cnblogs.com/lianyingteng/p/7755545.html