接下來幾天,就讓我們來聊聊有關於資訊檢索的基本概念吧!
在 NLP 領域中,資訊檢索 ( Information Retrieval, IR ) 是一項應用非常廣泛的任務,從圖書館的藏書搜尋到現今大家每天上網都會用到的搜尋引擎,資訊檢索已經成為我們日常生活中不可或缺的一部分。
IR 的目標是從大量的文本中找到和使用者要求最相關的資訊,舉個例子:
doc1 : “I like banana.”
doc2 : “I don’t like orange.”
doc3 : “I don’t like apple.”
我們的資料集中包含了這三篇文章,假設使用者想要找出和 “apple” 有關的文章,最直觀的作法應該就是把每一篇文章都檢查過一遍,然後把所有包含 “apple” 的文章都抓出來:
documents = ["I like banana.", "I don't like orange.", "I don't like apple."]
query = "apple"
result = []
for doc in documents:
if query in doc:
result.append(doc)
for r in result:
print(r)
I don't like apple.
這就是資訊檢索在做的事情,不過像這種線性搜索(Linear Search)的方法過於簡單粗暴了,需要對每一篇文檔中的每一個單詞都進行比對,看起來效率不高,特別是在面對大量文章的時候。
因此,我們來聊聊更有效率一點的作法:布林檢索 ( Boolean Retrieval )。
布林檢索是基於簡單的布林運算,比方說 AND、OR、NOT 這些運算子對文章進行檢索。
不過在了解它的運作方式之前,我們先介紹一個名詞叫做 Term-Document Incidence Matrix,以剛剛提到的那三篇文章為例,它們可以被表示為下面這個矩陣:
document 1 | document 2 | document 3 | |
---|---|---|---|
I | 1 | 1 | 1 |
like | 1 | 1 | 1 |
banana | 1 | 0 | 0 |
don’t | 0 | 1 | 1 |
orange | 0 | 1 | 0 |
apple | 0 | 0 | 1 |
所謂的 Term-Document Incidence Matrix 就是把所有的文章和單詞都條列出來一一對應,如果這個單詞有包含在這個文章裡面就標示為 1,否則為 0。
在建立這個矩陣之後,我們就可以用它來做布林檢索,舉個例子來說:
使用者想要查找含有 like
以及 banana
的文章,可以輸入查詢條件 like AND banana
。
而檢索的方式就是將 like
所在的列 111
和 banana
所在的列 100
做 AND 運算,獲得 111 AND 100 = 100
的結果。
100
所代表的含意就是只有 document 1,因為剩下兩個 document 的位元是 0。
再看一個例子:
使用者想要查找含有 don’t
但不含 apple
的文章,運算結果就會是 011 AND (NOT 001) = 010
,對應的就是 document 2。
相較於一開始所提的線性搜尋,布林檢索的優勢就在於它非常的簡單而且運算快速,我們只需要一開始建立好 Term-Document Incidence Matrix,就可以快速篩選出相關文檔。
然而它的缺陷也很明顯,仔細觀察 Term-Document Incidence Matrix,我們會發現當資料集包含海量文檔的時候,整個矩陣會變的非常龐大,需要的空間應該是天文數字了。
而且不光如此,絕大多數的數值都會標示為 0,這也代表它是一個稀疏矩陣,很多空間其實是被浪費的。
那有沒有辦法可以讓布林檢索在省下時間的情況下,使用更少的儲存空間?
這樣問就是有,這也是我們明天要聊的主題:反向索引 ( Inverted Index ),接下來會講解反向索引是怎麼構建的,以及如何使用它來完成布林檢索。
推薦文章
Basic Information Retrieval Problem — Boolean Retrieval Model
Boolean Retrieval - Mark Chang's Blog