iT邦幫忙

2021 iThome 鐵人賽

DAY 8
1
AI & Data

當自然語言處理遇上深度學習系列 第 8

[常見的自然語言處理技術] Bag-of-Words Model:簡單直觀的統計語言模型

  • 分享至 

  • xImage
  •  

前言

當我們要使用機器學習演算法來解決自然語言的問題,我們首先必須將文字進行量化( quantification )。而透過數字來表示語言的演算法,就稱之為語言模型( language model )。

A statistical language model is a probability distribution over sequences of words.

文字出處:Language Model| Wikipedia

詞袋模型(Bag-of-Words Model, BoW)

淺談詞「袋」

詞袋模型是一個基於單詞出現頻率來表示文字的方法,它並不考慮單詞的排列順序、或甚至是文法結構。

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.

文字出處:A Gentle Introduction to the Bag-of-Words Model

圖片來源:A Bag of Words: Levels of Language

詞袋模型(bag-of-words language model, BoW)在今日的語言模型當中當屬最簡單、最容易理解的了。雖說如此,其應用卻十分廣泛,它可被用來找尋新聞標題、過濾詐騙郵件、找出推文的正負向情緒、甚至到建立文字雲( word cloud )等等。

臉書文字雲
圖片來源:https://devilmen.blogspot.com/2012/02/fb.html

文字的向量化

圖片來源: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 )。而當我們考慮更多的文字資料,我們就會得到更長的特徵詞典,從而將文字表達成更高維度的向量。

如何用Python寫一個詞袋模型

首先我們定義訓練文本:

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 ,比較其與詞袋模型的優缺點。今天的介紹就到此畫下句點,我們明天見!

閱讀更多

  1. Language Model
  2. Curse of Dimensionality

上一篇
[自然語言處理基礎] 語法分析與資訊檢索 (II)
下一篇
[常見的自然語言處理技術] N-Gram Model 與關鍵字預測 (I)
系列文
當自然語言處理遇上深度學習33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言