當我們要使用機器學習演算法來解決自然語言的問題,我們首先必須將文字進行量化( quantification )。而透過數字來表示語言的演算法,就稱之為語言模型( language model )。
A statistical language model is a probability distribution over sequences of words.
詞袋模型是一個基於單詞出現頻率來表示文字的方法,它並不考慮單詞的排列順序、或甚至是文法結構。
It is called a “bag” of words, because any information about the order or structure of words in the document is discarded. The model is only concerned with whether known words occur in the document, not where in the document.
詞袋模型(bag-of-words language model, BoW)在今日的語言模型當中當屬最簡單、最容易理解的了。雖說如此,其應用卻十分廣泛,它可被用來找尋新聞標題、過濾詐騙郵件、找出推文的正負向情緒、甚至到建立文字雲( word cloud )等等。
圖片來源:Text Encoding: A Review
我們將句子「 Natural language processing is fun. 」當中的每個詞條進行小寫轉換、斷詞與詞形還原的前處理,並排列如下:
這時候我們分別計算以下兩個句子中的單詞出現在上述參考單詞的次數:
Sentence 1: The story was fun.
Sentence 2: I watched a fun movie in a threatre called "FUN TIME".
我們可以藉由特徵出現的頻率,將上述句子轉換成向量:
Sentence 1: The story was fun. ⟶ (0, 0, 0, 1, 1)
Sentence 2: I watched a fun movie in a threatre called "FUN TIME". ⟶ (0, 0, 0, 0, 2)
我們不難發現,參照的文字資料的選擇,會影響向量的表達。因此我們必須找出具有代表文字特徵的字串作為基準,建立特徵詞典( features dictionary )。而當我們考慮更多的文字資料,我們就會得到更長的特徵詞典,從而將文字表達成更高維度的向量。
首先我們定義訓練文本:
training_docs = ["Five fantastic fish flew off to find faraway functions.",
"Maybe find another five fantastic fish?",
"Find my fish with a function please!"]
接著建立 features dictionary :
# merge a list of string to a single string
merged = ' '.join(training_docs)
# Stop word removal, tokenisation and lemmatisation
tokens = preprocess_text(merged)
features_dict = dict()
index = 0
for token in tokens:
print("token: {}".format(token))
# if not a new word
if token in features_dict:
continue
else:
features_dict[token] = index
index += 1
我們不妨將 features dictionary 打印出來,檢視編碼結果,其長度決定了文字向量化後的維度:
我們寫個字串轉換為向量的函式:
def text_to_bow_vector(sample_text, features_dict):
"""
sample_text: string
"""
bow_vector = [0] * len(features_dict)
tokens = preprocess_text(sample_text)
for token in tokens:
feature_index = features_dictionary[token]
bow_vector[feature_index] += 1
return bow_vector
接著,我們欲將以下文句依照 features dictionary 向量化:
text = "My fish found five fish!"
bow_vector = text_to_bow_vector(text, features_dict)
字串「 My fish found five fish! 」透過詞袋模型向量化的結果 bow_vector 等於 [1, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0] (維度 = 15)。
今天我們介紹了透過計算特徵單詞出現頻率而得出向量的詞袋模型,為一個簡單的統計語言模型。然而隨著訓練文本份量的增加,轉化後的向量維度往往十分可觀,因此容易引發維數災難( curse of dimenionality )。再者,由於其僅考慮單一詞條,以詞袋模型建立的機器學習模型(例如用來分類文件的單純貝氏分類器和文本主題預測的馬可夫鍊等)將很可能對資料有過擬合( overfitting )的現象。下一回我們將介紹詞袋模型的衍伸語言模型: n-gram models ,比較其與詞袋模型的優缺點。今天的介紹就到此畫下句點,我們明天見!