該系列文章是《an introduce to information retrieval》chapter 1 的讀書筆記。
ir的概念很廣泛,即使從錢包中拿出一張信用卡並輸入卡號也是一種形式的資訊檢索。在學術領域,我們這樣定義ir:
資訊檢索(ir)就是一種從大量資料集合中(通常指儲存在計算機中文件)尋找滿足資訊需求的非結構化(通常指文字)得資料(通常指文件)。
布林檢索模型(boolean retrieval)
要點: (1) 倒排/反向索引模型 inverted indexes
(2) 簡單的布林表示式如何處理這些索引
1.1 詞—文件的關聯矩陣索引 a term-document matrix
(1) unix/linux grep- 命令
這個命令或許大家都用過,它是unix/linux中用於在指定檔案中查詢特定的搜尋字串的命令。它的原理是利用正規表示式 在文件集合中進行線性順序掃瞄(sort of linear scan)。
這種方式對於現代計算機的執行速度而言,在有限的資料規模下做簡單的查詢足夠應付了。
(2) web data 的搜尋面臨的現實問題
▲ web搜尋面臨的是廣大使用者群,其查詢表示式的方式靈活多樣(並不一定是布林表示式)。甚至有的時候並沒有準確的查詢含義。比如查詢query: romans near courtyman。 這裡的near到底是指romans,courtyman這兩詞需要在文章中同乙個句子裡出現,還是相隔若干詞。如何更好的響應使用者的靈活多變的查詢方法,提供更加人性化得服務呢?
▲ 檢索結果的排序問題也是乙個現實問題。使用者需要看到的是最滿意的答案,那麼查詢返回的若干文件,到底哪些與使用者查詢最相關呢?
(3)布林模型的詞—文件關聯矩陣索引模型
線性順序掃面對於web data來說是不可能的。目前,解決高效檢索大量非結構化的資訊的公認最好手段就是建立索引(indexes)。下面就是乙個簡單的索引模型——關聯矩陣。
1. 詞—文件關聯矩陣 如下圖,列表示文件,行表示文件中的詞。
其中如果term1出現在doc1中,則矩陣(1,1)標示為1,否則為0。
2. 建立布林查詢表示式(boolean query)。 antony and brutus not caesar 也就是我們需要找到包含antony ,brutus同時不包含caesar 詞語的文件。
3. 使用位運算: antony and brutus not caesar = 110001 & 110100 & (~110111) =000000. 很可惜,一篇都沒有。
(4) 關聯矩陣模型的缺陷
上面這個簡單索引模型並不適合web data的檢索。對於大資料量而言,這個矩陣實在是太大了,不可能全部放進記憶體。而且更嚴重的是矩陣太稀疏了。況且對於檢索結果的排序問題也是解決不了的。
1.2 倒排索引 inverted index
倒排索引絕對是乙個偉大的發現。當前很多搜尋引擎或者開發包都使用了這個模型,比如lucene。
(1) 倒排索引結構:1. 詞語組成的字典結構 ——dictionary 如下圖左側
2. 文件組成的位置鏈 —— postiong 如下圖右側
(2) 建立過程
1. 將每乙個文件中的詞語與文件id(唯一標示文件)組成乙個pair,存入index。如左圖a
2. 將index中的詞語按字典序排序。如中圖b
3. 如果相同詞語來自同乙個文件,則只記錄一次。相同詞語來自不同文件,則合併成進posting。如右圖c
(3) 索引儲存方法
很顯然,對於倒排索引,我們必須把dictionary和posting都儲存起來。一般dictionary可以全部載入進記憶體中,而posting存放在磁碟中,當需要查詢posting的時候,再會將某乙個詞語所指向的posting載入進記憶體。
dictionary in menory
很多時候使用hash表的形式,也用連續儲存的陣列結構。
posting in menory:
1. 單鏈表( singly linked lists) ,在將新文件插入posting中的時候付出的代價較少。這一點很適合高頻率從網上抓取內容並更新文件。
2. 可變長陣列(variable length arrays),節約了指標所需要的額外空間。並且對於擁有記憶體快取區的現代計算機而言,連續記憶體的結構無疑會增加查詢的速度。
3. 跳躍表(skip lists),一種很先進的儲存結構。除了需要額外耗費一些指標空間之外,查詢效率極高。lucene就是用了這種結構。
1.3 布林查詢表示式的處理
(1) posting的合併演算法(merge algorithm)
假如我們需要在倒排索引上查詢這樣乙個表示式: brutus and calpurnia。很明顯我們需要下面幾個步驟:
1. 在dictionary中定位brutus.
2. 檢索brutus所指向的posting: 1、2、4、11、31....
3. 在dictionary中定位calpurnia.
4. 檢索calpurnia所指向的posting: 2、31、54....
5. 合併兩個posting.
對於兩個有序表的合併演算法,可以採用下面的演算法: 時間複雜度為o(m+n)
//指標p1,p2分別指向兩個posting鏈(2) 布林表示式的優化posting intersect(p1,p2)
if(p1>p2) p2=p2->next;
if(p1next;}}
brutus and caesar and calpurnia
表示式的and順序按照每乙個詞的文件頻率遞增進行優化。 比如
brutus『s
ducument frequence(brutus所在文件的數量,符號表示df(brutus))。df(brutus)=1000,df(caesar)=10000,df(calpurnia)=100。那麼查詢表示式可以優化成: (calpurnia and brutus) and caesar。
理由很簡單,calpurnia and brutus的時間複雜度(利用上面的合併演算法)為o(1100),其合併後的中間結果r=df(calpurnia and brutus)如果使用原表示式,brutus and caesa的時間複雜度為o(11000),且中間結果為r=df(
brutus and caesa
)< df(brutus)=1000。然後r and calpurnia的時間複雜度可能達到o(1000+100)。兩次and操作的總時間複雜度為o(11000+1100)=o(12100)
明顯優化之後的時間複雜度會少。如果查詢表示式更長,查詢詞語的df差距更大,那麼優化的效率會更明顯 。
根據上面的優化原理,對於更加複雜的查詢表示式(madding or crowd) and (ignoble or strife) and (killed or slain)。我們一般都會估算or操作兩個詞的df之和的數量,然後進行and遞增排序。
事實上,對於任意的布林表示式,每一次操作的中間結果(intermediate)越小越好。 這是我們進行優化的原則所在。
(3) 自然語言查詢
and
布林查詢表示式
為什麼我們對布林表示式的操作只將and,很少說or或not呢?
在搜尋引擎實際應用的環境下,使用者的查詢都是自然語言敘述的,很少直接用布林表示式(你不能要求所有的使用者必須邏輯思維縝密吧)。那麼對於使用者提交的這些查詢,都是純粹的合併操作。
正是這個原因,現實中很多搜尋引擎的應用已經退化成了只有and的布林模型了。
python布林系列 python 布林運算
python學習手冊 讀書筆記 真值測試 在python中 任何非零數字或非空物件都為真 數字零 空物件以及特殊物件none都被認作是假 比較和相等測試會遞迴地應用在資料結構中 比較和相等測試會返回true或false 1和0的特殊版本 布林and和or運算子會返回真或假的操作物件 python中有...
python布林類入門 Python的布林型別
前面我們了解到,布林型別是python的基礎資料型別,布林型別只有true和false兩種值,本節課我們學習布林型別的集中運算。與運算只有兩個布林值都為 true 時,計算結果才為 true。true and true true true and false false false and true...
c 布林型別
布林型別 bool 是c 新增的一種基本資料型別。在標準的c語言中並未定義bool型別,如果需要使用bool型別,程式設計師可以通過巨集定義來自定義乙個bool型別,定義語句如下 define bool int define false 0 define true 1 也就是將int型定義為bool...