iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
AI & Data

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

[常見的自然語言處理技術] 重不重要?TF-IDF 會告訴你

  • 分享至 

  • xImage
  •  

前言

在自然語言處理的諸多課題如信息檢索( information retrieval )和文本探勘( text mining )當中,我們希望找出重要的單詞或文句。在過程中我們需要將文字進行量化(轉化為向量)以進行後續處理及篩選。常見的向量表示法有:

  • One-Hot Encoding: 假設詞彙表(vocabulary, 意為語料庫中獨特單詞所構成的集合)有N個單詞,將每個單詞依序對應到一個N維向量,並且符合只有在其順位的維度為1,其餘維度皆為0的編碼原則。

將詞彙表中的單詞進行 One-Hot 編碼

圖片來源:Shane Lynn

各個句子以BoW表示成向量

圖片來源:GDCoder

  • Bag of N-Grams: 簡稱為BoN,是為BoW的衍生表示法,統計n-gram(由n個連續單詞所構成的小單位)在語料庫中出現的個數(詳見本系列第十天的文章:N-Gram Model 與關鍵字預測 (II)

各個句子以1-grams (tokens) 與 2-grams 表示成向量

圖片來源:GDCoder

然而以上編碼原則皆有一個共通點:每個單詞都被視為一樣重要。然而文件當中通常夾雜許多停用詞如 athebe ,未能提供實際意義,卻往往非常大量地出現在文本當中,因此僅憑單詞出現的次數( occurrences )來說明該單詞在一份文件乃至於整個語料庫中的重要程度,是不具說服力的。今天我們要談的TF-IDF就是一種衡量單詞重要性的加權機制。

詞頻(Term Frequency, TF)

什麼是TF-IDF?

TF-IDF 全名為Term Frequency-Inverse Document Frequency,是一種決定單詞對於一份文件重要程度的衡量手法。它由兩個部分組成:詞頻(term frequecny, tf)與逆向文件頻率(inverse document frequency, idf),接下來我們分別來介紹這兩者。
在深入探tf與idf之前,為了避免讀者的困惑,我們先解釋語料庫((text) corpus)、文件(document)和單詞(term)之間的關係。
文件是由單詞構成,例如一篇文章、一首詩詞,在Python當中經常以字串的形式出現,其與單詞的從屬為「單詞屬於文件」;語料庫是多份文件的集合,例如詩集,在Python當中常以list的物件出現,其與文件的從處關係為「文件屬於文語料庫」。

詞頻

詞頻,顧名思義就是單詞出現在一份文件的頻率。若某一單詞在一份文件當中出現的次數越多,我們會直覺地認為它愈是重要。然而我們不能光以「次數」來衡量,必須考慮文件的篇幅。因此我們需要進行正規化,將次數再除以文件長度,於是有了以「頻率」來衡量單詞重要性的定義方式:

在以上定義中, 表示單詞 t 在文件 d 當中的次數。

由TF衍生的加權方式

衡量單詞相對於文件重要程度的定義方式並不惟一,以下列舉出幾項由傳統詞頻衍生出的加權計算方式:

圖片來源:Wikipedia

逆向文件頻率(Inverse Document Frequency, IDF)

逆向文件頻率

有許多單詞,其詞頻非常高,卻不具重要性,如 a/anthe 等停用詞(stop words)。因此由將單詞出現的次數正規化而得的詞頻還不足以衡量單詞在文本中的重要程度,我們仍需要考慮單詞對於語料庫的重要程度,其定義方式如下:

在上述定義當中, D 表示語料庫,其元素為文件 d 。而分母加上1則是為了避免由於單詞不在語料庫中而導致分母為零(division-by-zero)的狀況,是一種well-defined的表現。
藉由對數 ln() 嚴格遞增的特性,我們可以直言:若某個單詞愈是集中出現在某幾份文件中,則 idf 就愈大,其之於整個語料庫而言就愈重要。反之,當某個單詞在大量文件中都出現,idf就愈小,我們會認為這個單詞愈是一般。。

由IDF衍生的加權方式

衡量單詞相對於整個語料庫重要程度的定義方式也不是惟一的,以下列舉出幾項由傳統IDF衍生出的加權計算方式:

圖片來源:Wikipedia

整合起來:TF-IDF加權分數

當我們將 tfidf 相乘起來,就可以反映出一個單詞在語料庫中對於一份文件有多麼重要。於是我們可以來正式定義今日的主人公 tf-idf

tf-idf Score與文件矩陣(Term-Document Matrix)

接下來我們示範如何計算單詞對於文件的 tf-idf 權重。

首先我們定義好含有三份文件(單一句子所構成的字串)的小型語料庫,並且對語料庫進行前處理:

from preprocessing import preprocess_text

# sample documents
document_1 = "This is the first sentence!"
document_2 = "This is my second sentence."
document_3 = "Is this my third sentence?"

# corpus of documents
corpus = [document_1, document_2, document_3]

# preprocess documents
processed_corpus = [preprocess_text(doc) for doc in corpus]

scikit-learn 函示庫中收錄了計算 tf-idf 的物件 TfidfVectorizer ,直接引入即可。將剛才前處理後的語料庫當作訓練資料進行擬合,我們即可得到每個單詞相對於各個文件的權重:

from sklearn.feature_extraction.text import TfidfVectorizer

# initialise TfidfVectorizer
vectoriser = TfidfVectorizer(norm = None)

# obtain weights of each term to each document in corpus (ie, tf-idf scores)
tf_idf_scores = vectoriser.fit_transform(processed_corpus)

文件矩陣(term-document matrix)用來表示各個單詞在整個語料庫中之於文件的重要性,其由 tf-idf scores 所構成。
我們透過轉換為 pandas dataframe 將結果呈現出來:

# get vocabulary of terms
feature_names = vectoriser.get_feature_names()
corpus_index = [n for n in processed_corpus]

import pandas as pd

# create pandas DataFrame with tf-idf scores: Term-Document Matrix
df_tf_idf = pd.DataFrame(tf_idf_scores.T.todense(), index = feature_names, columns = corpus_index)
print(df_tf_idf)

時不我與,今天的介紹就到這邊,我們明天見!

閱讀更多

  1. Corpus Vocabulary
  2. One-Hot Encoding of Text Data in Natural Language Processing
  3. Document and Query Weighting Schemes

上一篇
[常見的自然語言處理技術] N-Gram Model 與關鍵字預測 (II)
下一篇
[常見的自然語言處理技術] 文本相似度(I): Word Embeddings
系列文
當自然語言處理遇上深度學習33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言