[轉(zhuǎn)]全文檢索

原文鏈接# Lucene學(xué)習(xí)總結(jié)之一:全文檢索的基本原理,這是我遇見最好的入門锰茉,近10年前的文章如今讀來依然讓人耳目一新。這里做一些摘要并收藏

Lucene是一個高效的扬霜,基于Java的全文檢索庫著瓶。

一材原、什么是全文檢索?

我們生活中的數(shù)據(jù)總體分為兩種:

  • 結(jié)構(gòu)化數(shù)據(jù):指具有固定格式或有限長度的數(shù)據(jù)威酒,如數(shù)據(jù)庫担钮,元數(shù)據(jù)等
  • 非結(jié)構(gòu)化數(shù)據(jù):指不定長或無固定格式的數(shù)據(jù)箫津,如郵件苏遥,word文檔等
  • 還有人提到第三種,半結(jié)構(gòu)化數(shù)據(jù):如XML诫肠,HTML等栋豫,根據(jù)需要可按結(jié)構(gòu)化數(shù)據(jù)來處理,也可抽取出純文本按非結(jié)構(gòu)化數(shù)據(jù)來處理

非結(jié)構(gòu)化數(shù)據(jù)又叫全文數(shù)據(jù)

類似的丛肢,按照數(shù)據(jù)的分類蜂怎,搜索也分為兩種:

  • 對結(jié)構(gòu)化數(shù)據(jù)的搜索:如對數(shù)據(jù)庫的搜索,用SQL語句幽歼。再如對元數(shù)據(jù)的搜索甸私,如利用windows搜索對文件名诬烹,類型绞吁,修改時間進(jìn)行搜索等雪隧。
  • 對非結(jié)構(gòu)化數(shù)據(jù)的搜索:如利用windows的搜索也可以搜索文件內(nèi)容脑沿,Linux下的grep命令注服,再如用Google和百度可以搜索大量內(nèi)容數(shù)據(jù)溶弟。

對非結(jié)構(gòu)化數(shù)據(jù)即全文數(shù)據(jù)的搜索主要有兩種方法:

一種是順序掃描法(Serial Scanning):所謂順序掃描,比如要找內(nèi)容包含某一個字符串的文件擒权,就是一個文檔一個文檔的看,對于每個文檔剖效,從頭看到尾贱鄙,如果此文檔包含此字符串,則此文檔是我們要找的文件瞎颗,接著看下一個文件直至看完所有文件引有。如利用windows的搜索來搜索文件內(nèi)容或者Linux的grep命令譬正,都是使用這種方式。顯而易見抒巢,這種方式相當(dāng)?shù)穆4蠹铱赡苡X得這種方式比較原始型诚,但對于小數(shù)據(jù)量的文件,這種方法還是最簡單最直接的暮现。但對于大量文件,這種方法就很慢了塘幅。

可能有人會說,對非結(jié)構(gòu)化數(shù)據(jù)順序掃描很慢匾乓,對結(jié)構(gòu)化數(shù)據(jù)的搜索卻相對較快(由于結(jié)構(gòu)化數(shù)據(jù)有一定的結(jié)構(gòu)娱局,可以采用一定的搜索算法加快速度)衰齐,那么把我們的非結(jié)構(gòu)化數(shù)據(jù)想辦法弄得有一定結(jié)構(gòu)不就行了嗎?(在我的第一家公司抹缕,我就做了這樣的事)

這種想法很天然丰介,卻構(gòu)成了全文檢索的基本思路带膀,即將非結(jié)構(gòu)化數(shù)據(jù)中的一部分信息提取出來,重新組織嗽元,使其變得有一定結(jié)構(gòu),然后對此有一定結(jié)構(gòu)的數(shù)據(jù)進(jìn)行搜索佩谷,從而達(dá)到搜索相對較快的目的。

這部分從非結(jié)構(gòu)化數(shù)據(jù)中提取出的而后重新組織的信息桐猬,我們稱之為索引厦坛。

這種說法比較抽象。舉個例子撬碟,字典。字典的拼音表和不部首表就相當(dāng)于字典的索引其障,對每一個字的解釋是非結(jié)構(gòu)化的,如果字典沒有音節(jié)表和不受檢字表,在茫茫辭海中查找一個字就只能順序掃描造烁。然而字的某些信息可以提取出來做進(jìn)行結(jié)構(gòu)化處理,比如讀音告组,就比較結(jié)構(gòu)化,分聲母和韻母,分別只有幾種可以一一列舉怎囚,于是將讀音拿出來按照一定的順序排列考婴,每一項(xiàng)讀音都指向此字的詳細(xì)解釋頁數(shù)。我們搜索時按照結(jié)構(gòu)化的拼音搜到讀音考杉,然后按其指向的頁數(shù),便可找到我們的非結(jié)構(gòu)化數(shù)據(jù)——即對字的解釋。

這種先建立索引萎坷,再對索引進(jìn)行搜索的過程就叫全文檢索(Full-text Search)食铐。

下面這幅圖來自《Lucene in action》匕垫,其不僅描述了Lucene的檢索過程僧鲁,而是描述了全文檢索的一般過程。


全文檢索大體分兩個過程象泵,索引創(chuàng)建(Indexing)搜索索引(Search)

  • 索引創(chuàng)建:將現(xiàn)實(shí)世界中所有的結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)提取信息寞秃,創(chuàng)建索引的過程偶惠。
  • 搜索索引:就是得到用戶查詢請求春寿,搜索創(chuàng)建的索引,然后返回結(jié)果的過程忽孽。

于是全文檢索就存在三個重要問題:

1. 索引里面究竟存些什么绑改?(Index)
2. 如何創(chuàng)建索引?(Indexing)
3. 如何對索引進(jìn)行搜索兄一?(Search)

下面我們順序?qū)γ總€問題進(jìn)行研究厘线。

二、索引里面究竟存寫什么

首先我們來看為什么順序掃描的速度慢:

其實(shí)是由于我們想要搜索的信息和非結(jié)構(gòu)化數(shù)據(jù)中所存儲的信息不一致造成的出革。

非結(jié)構(gòu)化數(shù)據(jù)中所存儲的信息是每個文件包含哪些字符串造壮,是從文件到字符串的映射;已知文件骂束,欲求字符串相對容易耳璧。而我們想搜索的信息是哪些文件包含此字符串成箫,是從字符串到文件的映射;已知字符串旨枯,欲求文件蹬昌,兩者恰恰相反。如果索引總能夠保存從字符串到文件的映射攀隔,則會大大提高搜索速度凳厢。

由于從字符串到文件的映射是從文件到字符串映射的反向過程,于是保存這種信息的索引成為反向索引竞慢、又叫做倒排索引(Inverted index)先紫。

反向索引所保存的信息一般如下:
假設(shè)我的文檔集合里面有100篇文檔,為了方便表示筹煮,我們將文檔編號從1到100遮精,得到下面的結(jié)構(gòu)

inverted index

左邊保存的是一系列字符串,稱為詞典败潦。
每個字符串都指向包含此字符串的的文檔(Document)鏈表本冲,此文檔鏈表成為倒排表(Posting List)

有了索引劫扒,便使保存的信息和要搜索的信息一致檬洞,可以大大加快搜索的速度。

比如說沟饥,我們要尋找既包含字符串"lucene"又包含字符串"solr"的文檔添怔,我們只需要以下幾步:

  1. 取出包含字符串"lucene"的文檔鏈表
  2. 取出包含字符串"solr"的文檔鏈表
  3. 通過合并鏈表,找出既包含"lucene"又包含"solr"的文件贤旷。
inverted index merge

看到這個地方广料,可能有人會說,全文索引的確加快了搜索的速度幼驶,但是多了索引的過程艾杏,兩者加起來不一定比順序掃描快多少。的確盅藻,加上索引的過程购桑,全文檢索不一定比順序掃描快,尤其是在數(shù)據(jù)量小的時候更是如此氏淑。而對于一個很大量的數(shù)據(jù)創(chuàng)建索引也是一個很慢的過程勃蜘。

然而兩者還是有區(qū)別的,順序掃描時每次都要掃描夸政,而創(chuàng)建索引的過程僅需一次元旬,一勞永逸。以后的每次搜索,創(chuàng)建索引的過程不必再經(jīng)過匀归,僅僅搜索創(chuàng)建好的索引就可以了坑资。

這也是全文搜索相對與順序掃描的優(yōu)勢之一:一次索引,多次使用穆端。

三袱贮、如何創(chuàng)建索引

全文檢索的檢索創(chuàng)建過程一般有一下幾步:

第一步:一些要索引的原文檔(Document)。

為了方便說明索引的創(chuàng)建過程体啰,這里特意用兩個文件為例:

文件一:Students should be allowed to go out with their friends, but not allowed to drink beer.

文件二:My friend Jerry went to school to see his students but found them drunk which is not allowed.

第二步:將原文檔傳給分詞組件(Tokenizer)攒巍。

分詞組件(Tokenizer)會做以下幾件事情(此過程稱為Tokenize):

1. 將文檔分成一個一個單獨(dú)的單詞。
2. 去除標(biāo)點(diǎn)符號荒勇。
3. 去除停詞(Stop word)柒莉。

所謂停詞(Stop word)就是一種語言中最普通的一些詞,由于沒有特別的意義沽翔,因而大多數(shù)情況下不能成為搜索的關(guān)鍵詞兢孝,創(chuàng)建索引時,這種詞會被去掉以減少索引的大小仅偎。

英語中停詞(Stop word)如:"the"跨蟹,"a","this"等橘沥。

對于每一種語言的分詞組件(tokenizer)窗轩,都有一個停詞(Stop word)集合。

經(jīng)過分詞(Tokenizer)后得到的結(jié)果稱為詞元(Token)座咆。

在我們的例子中痢艺,便得到以下詞元(Token):

"Students","allowed"箫措,"go"腹备,"their"衬潦,"friends"斤蔓,"allowed","drink"镀岛,"beer"弦牡,"My","friend"漂羊,"Jerry"驾锰,"went","school"走越,"see"椭豫,"his","students","found"赏酥,"them"喳整,"drunk","allowed"裸扶。

第三步:將得到的詞元(Token)傳給語言處理組件(Linguistic Processor)框都。

語言處理組件(Linguistic Processor)主要是對得到的詞元(Token)做一些語言相關(guān)的處理。

對于英語呵晨, 語言處理組件(Linguistic Processer)一般做到以下幾點(diǎn):

1. 變?yōu)樾?Lowercase)
2. 將單詞縮減為詞根形式魏保,如"cars"到"car"等。這種操作稱為:stemming摸屠。
3. 將單詞轉(zhuǎn)變?yōu)樵~根形式谓罗,如"drove"到"drive"等。這種操作成為:lemmatization季二。

Stemming和Lemmatization的異同:

  • 相同之處: Stemming和Lemmzation都要使詞匯成為詞根形式妥衣。

  • 兩者的方式不同:

    • Stemming采用的是"縮減"的方式:"cars"到"car","driving"到"drive"戒傻。
    • Lemmatization采用的時"轉(zhuǎn)變"的方式:"drove"到"drive"税手,"driving"到"drive"
  • 兩者的算法不同:

    • Stemming主要是采取某種固定的算法來做這種縮減,如去除“s”需纳,去除“ing”加“e”芦倒,將“ational”變?yōu)椤癮te”,將“tional”變?yōu)椤皌ion”不翩。
    • Lemmatization主要是采用保存某種字典的方式做這種轉(zhuǎn)變兵扬。比如字典中有“driving”到“drive”,“drove”到“drive”口蝠,“am, is, are”到“be”的映射器钟,做轉(zhuǎn)變時,只要查字典就可以了妙蔗。
  • Stemming和Lemmatization不是互斥關(guān)系与帆,是有交集的,有的詞利用這兩種方式都能達(dá)到相同的轉(zhuǎn)換

語言處理組件(linguistic processor)的結(jié)果稱為詞(Term)汁展。

在我們的例子中猎提,經(jīng)過語言處理,得到的詞(Term)如下:

"student"寸五,"allow"梳凛,"go","their"梳杏,"friend"韧拒,"allow"淹接,"drink","beer"叛溢,"my"蹈集,"friend","jerry"雇初,"go"拢肆,"school","see"靖诗,"his"郭怪,"student","find"刊橘,"them"鄙才,"drink","allow"促绵。

也正是因?yàn)橛姓Z言處理的步驟攒庵,才能使搜索drove,而drive也能被搜索出來败晴。

第四步:將得到的詞(Term)傳給索引組件(Indexer)浓冒。

索引組件(Indexer)主要做以下幾件事情:

1. 利用得到的詞創(chuàng)建一個字典。

在我們的例子中尖坤,字典如下:

Term Document ID
student 1
allow 1
go 1
their 1
friend 1
allow 1
drink 1
beer 1
my 2
friend 2
jerry 2
go 2
school 2
see 2
his 2
student 2
find 2
them 2
drink 2
allow 2

2. 對字典按字母順序進(jìn)行排序

Term Document ID
allow 1
allow 1
allow 2
beer 1
drink 1
drink 2
find 2
friend 1
friend 2
go 1
go 2
his 2
jerry 2
my 2
school 2
see 2
student 1
student 2
their 1
them 2

3. 合并相同的詞(Term)成文文檔倒排鏈表(Posting List)

postinglist

在此表中稳懒,有幾個定義:

  • Document Frequency 即文檔頻次,表示總共有多少文件包含此詞(Term)慢味。
  • Frequency 即詞頻率场梆,表示此文件中包含了幾個此詞(Term)。

所以對詞(Term)"allow"來講纯路,總共有兩篇文檔包含此詞(Term)或油,從而詞(Term)后面的文檔鏈表總共有兩個節(jié)點(diǎn),第一個節(jié)點(diǎn)表示包含了"allow"的第一篇文檔驰唬,即1號文檔顶岸,此文檔中,"allow"出現(xiàn)了2次定嗓;第二項(xiàng)表示包含"allow"的第二篇文檔蜕琴,即2號文檔,此文檔中宵溅,"allow"出現(xiàn)了1次。

四上炎、如何對索引進(jìn)行搜索

到這里似乎我們可以宣布"我們找到想要的文檔了"恃逻。

然而事情并沒有結(jié)束雏搂,找到了僅僅是全文檢索的一個方面,不是嗎寇损?如果僅僅只有一個或十個文檔包含我們查詢的字符串凸郑,我們的確找到了∶校可是如果結(jié)果有一千萬個芙沥,甚至成千上萬個呢?哪個是您最想要的文件呢浊吏?

舉個例子而昨,打開Google,比如你想在微軟找份工作找田,于是輸入" Microsoft job"歌憨,你卻發(fā)現(xiàn)總共有12,600,000個結(jié)果返回。好大的數(shù)字啊墩衙,突然發(fā)現(xiàn)找不到是一個問題务嫡,找到的太多也是一個問題。在如此多的結(jié)果中漆改,如何將最相關(guān)的放在最前面呢心铃?

Search "Microsoft job" on Google

當(dāng)然Google做的很不錯,你一下就找到了"job at Microsoft"挫剑。想象一下于个,如果前幾個全部是"Microsoft does a good job at software industry..."將是多么可怕的事情。

如何像Google一樣暮顺,在成千上萬的搜索結(jié)果中厅篓,找到和查詢語句最相關(guān)的呢?

如何判斷搜索出的文檔和查詢語句的相關(guān)性呢捶码?

這要回到我們的第三個問題:如何對索引進(jìn)行搜索羽氮?

搜索主要分為以下幾步:

第一步:用戶輸入查詢語句。

查詢語句同我們普通的語言一樣惫恼,也是有一定語法的档押。

不同的查詢語句有不同的語法,如SQL語句就有一定的語法祈纯。

查詢語句的語法根據(jù)全文檢索系統(tǒng)的實(shí)現(xiàn)不同而不同令宿。最基本的比如: AND,OR腕窥,NOT等粒没。

舉個例子,用戶輸入語句:lucene AND learned NOT hadoop簇爆。

說明用戶想找一個包含lucene和learned然而不包括hadoop的文檔癞松。

第二步:對查詢語句進(jìn)行詞法分析爽撒,語法分析,及語言處理响蓉。

由于查詢語句有語法硕勿,因而也要進(jìn)行詞法分析,語法分析及語言處理枫甲。

1. 詞法分析主要用來識別單詞和關(guān)鍵字源武。

如上述例子中,經(jīng)過詞法分析想幻,得到的單詞有l(wèi)ucene粱栖,learned,hadoop举畸,關(guān)鍵字有AND查排,NOT。

如果在詞法分析中發(fā)現(xiàn)不合法的關(guān)鍵字抄沮,則會出現(xiàn)錯誤跋核。如lucene AMD learned,其中由于 AND拼錯叛买,導(dǎo)致AMD作為一個普通單詞參與查詢砂代。

2. 語法分析主要是根據(jù)查詢語句的語法規(guī)則來形成一棵語法樹。

如果發(fā)現(xiàn)查詢語句不滿足語法規(guī)則率挣,則會報錯刻伊。如lucene NOT AND learned,則會出錯椒功。

如上述例子捶箱,lucene AND learned NOT hadoop形成的語法樹如下:

語法樹

3. 語言處理同索引過程的語言處理幾乎相同。

如learned變成learn等动漾。

經(jīng)過第3步丁屎,我們得到一棵經(jīng)過語言處理的語法樹。

語法樹_經(jīng)過語言處理.jpg
第三步:搜索索引旱眯,得到符合語法樹的文檔晨川。

此步驟又分幾小步:

  1. 首先,在反向索引表中删豺,分別找出包含lucene共虑,learn,hadoop的文檔鏈表呀页。
  2. 其次妈拌,對包含lucene,learn的鏈表進(jìn)行合并操作赔桌,得到既包含lucene又包含learn的文檔鏈表供炎。
  3. 然后渴逻,將此鏈表與hadoop的文檔鏈表進(jìn)行差操作疾党,去除包含hadoop的文檔音诫,從而得到既包含lucene又包含learned而且不包含hadoop的文檔鏈表。
  4. 此文檔鏈表就是我們要找的文檔雪位。
第四步:根據(jù)得到的文檔和查詢語句的相關(guān)性竭钝,對結(jié)果進(jìn)行排序。

雖然在上一步雹洗,我們得到了想要的文檔香罐,接下來應(yīng)該將查詢結(jié)果按照與查詢語句的相關(guān)性進(jìn)行排序,越相關(guān)者越靠前时肿。

如何計(jì)算文檔和查詢語句的相關(guān)性呢庇茫?

不如我們把查詢語句看作一片短小的文檔,對文檔與文檔之間的相關(guān)性(relevance)進(jìn)行打分(scoring)螃成,分?jǐn)?shù)高的相關(guān)性好旦签,就應(yīng)該排在前面。

那么又怎么對文檔之間的關(guān)系進(jìn)行打分呢寸宏?

這可不是一件容易的事情宁炫,首先我們看一看判斷人之間的關(guān)系吧。

首先看一個人氮凝,往往有很多要素羔巢,如性格、信仰罩阵、愛好竿秆、衣著、高矮稿壁、胖瘦等等幽钢。

其次對于人與人之間的關(guān)系,不同的要素重要性不同常摧,性格搅吁,信仰,愛好可能更重要一些落午,衣著谎懦,高矮,胖瘦可能就不能么重要了溃斋,所以具有相同或相似性格界拦,信仰,愛好的人比較容易稱為好的朋友梗劫,然而衣著享甸,高矮截碴,胖瘦不同的人,也可以成為好的朋友蛉威。

因而判斷人與人之間的關(guān)系日丹,首先找出哪些要素對人與人之間的關(guān)系最重要,比如性格蚯嫌,信仰哲虾,愛好。其次要判斷兩個人的這些要素之間的關(guān)系择示,比如一個人性格開朗束凑,另一個人性格外向;一個人信仰佛教栅盲,另一個人信仰上帝汪诉;一個人愛好打籃球,另一個愛好踢足球谈秫。我們發(fā)現(xiàn)扒寄,兩個人在性格方面都很積極,信仰方面都很善良孝常,愛好方面都愛運(yùn)動旗们,因此兩個人關(guān)系應(yīng)該會很好。

我們再來看看公司之間的關(guān)系吧构灸。

首先看一個公司上渴,有很多人組成,如總經(jīng)理喜颁,經(jīng)理稠氮,首席技術(shù)官,普通員工半开,保安隔披,門衛(wèi)等。

其次對于公司與公司之間的關(guān)系寂拆,不同的人重要性不同奢米,總經(jīng)理,經(jīng)理纠永,首席技術(shù)官可能更重要一些鬓长,普通員工,保安尝江,門衛(wèi)可能較不重要以點(diǎn)涉波。如果兩個公司總經(jīng)理,經(jīng)理,首席技術(shù)官之間關(guān)系比較好啤覆,兩個公司容易有比較好的關(guān)系苍日。然而一位普通員工就算與另一家公司的一位普通員工有血海深仇,怕也難影響兩個公司之間的關(guān)系窗声。

因而判斷公司與公司之間的關(guān)系相恃,首先要找出哪些人對公司與公司之間的關(guān)系最重要,比如總經(jīng)理嫌佑,經(jīng)理豆茫,首席技術(shù)官侨歉。其次要判斷這戲人之間的關(guān)系屋摇,比如兩家公司的總經(jīng)理曾經(jīng)是同學(xué),經(jīng)理是老鄉(xiāng)幽邓,首席技術(shù)官曾是創(chuàng)業(yè)伙伴炮温。我們發(fā)現(xiàn),兩家公司無論總經(jīng)理牵舵,經(jīng)理柒啤,首席技術(shù)官關(guān)系都很好,因而兩家公司關(guān)系應(yīng)該會很好畸颅。

分析了兩種關(guān)系担巩,下面看一看如何判斷文檔之間的關(guān)系了。

首先没炒,一個文檔有很多的詞(Term)組成涛癌,如search,lucene送火,full-text拳话,this,a种吸,what等弃衍。

其次對于文檔之間的關(guān)系,不同的Term重要性不同坚俗,比如對于本篇文檔镜盯,search,lucene猖败,full-text就相對重要一些速缆,this,a辙浑,what可能相對不重要一些激涤。所以如果兩篇文檔都包含search,lucene,full-text倦踢,兩篇文檔的相關(guān)性好一些送滞;然而就算一篇文檔包含this,a辱挥,what犁嗅,另一篇文檔不包含this,a晤碘,what褂微,也不能影響兩篇文檔的相關(guān)性。

因而判斷文檔之間的關(guān)系园爷,首先找出哪些詞(Term)對文檔之間的關(guān)系最重要宠蚂,如search,lucene童社,full-text求厕。然后判斷這些詞(Term)之間的關(guān)系。

找出詞(Term)對文檔重要性的過程稱為計(jì)算詞的權(quán)重(Term weight)的過程扰楼。

計(jì)算詞的權(quán)重(term weight)有兩個參數(shù)呀癣,第一個是詞(Term),第二個是文檔(Document)弦赖。

詞的權(quán)重(Term weight)表示此詞(Term)在此文檔中的重要程度项栏,越重要的詞(Term)有越大的權(quán)重(Term weight),因而在計(jì)算文檔之間的關(guān)系的相關(guān)性中將發(fā)揮更大的作用蹬竖。

判斷詞(Term)之間的關(guān)系從而得到文檔相關(guān)性的過程應(yīng)用一種叫做向量空間模型的算法(Vector Space Model)沼沈。

仔細(xì)分析以下這個兩個過程:

1.計(jì)算權(quán)重(Term weight)的過程。

影響一個詞(Term)在一篇文檔中的重要性主要有兩個因素:

  • Term Frequency(tf):即此Term在文檔中出現(xiàn)了多少次案腺。tf越大說明越重要庆冕。
  • Document Frequency(df):即有多少文檔中包含了此Term。df越大說明越不重要劈榨。

容易理解嗎访递?詞(Term)在文檔中出現(xiàn)的次數(shù)越多,說明此詞(Term)對該文檔越重要同辣,如"搜索"這個詞拷姿,在本文檔中出現(xiàn)的次數(shù)很多,說明本文檔就是講這方面的事的旱函。然而在一篇英文文檔中响巢,"this"出現(xiàn)的次數(shù)更多,就說明更重要嗎棒妨?不是的踪古,這是由第二個因素進(jìn)行調(diào)整的,第二個因素說明,有越多的文檔包含此詞(Term)伏穆,說明此詞(Term)太普通拘泞,不足以區(qū)分這些文檔,因此重要性越低枕扫。

這也如我們程序員所學(xué)的技術(shù)陪腌,對于程序員本身來說,這項(xiàng)技術(shù)掌握的越深越好(掌握的越深說明花時間看的越多烟瞧,tf越大)诗鸭,找工作時越有競爭力;然而對所有程序員來說参滴,這項(xiàng)技術(shù)懂的人越少越好(懂得的人少df小)强岸,找工作越有競爭力。人的價值在于不可替代性就是這個道理卵洗。

道理明白了请唱,我們來看看公式:

這僅僅只有term weight計(jì)算公式的典型實(shí)現(xiàn)。

實(shí)現(xiàn)全文檢索系統(tǒng)的人會有自己的實(shí)現(xiàn)过蹂,lucene就與此稍有不同。

以上方創(chuàng)建索引的例子來說聚至,

Term tf in d1 tf in d2 df
allow 2 1 2
beer 1 0 1
drink 1 1 2
find 0 1 1
... ... ... ...

2. 判斷Term之間的關(guān)系從而得到文檔相關(guān)性的過程酷勺,也即向量空間模型的算法(VSM)。

我們把文檔看作一系列詞(Term)扳躬,每一個詞(Term)都有一個權(quán)重(Term weight)脆诉,不同的詞(Term)根據(jù)自己在文檔中的權(quán)重來影響文檔的相關(guān)性的打分計(jì)算。

于是我們把所有此文檔中詞(Term)的權(quán)重(Term weight)看作一個向量贷币。

Document = {term 1击胜,term 2,...役纹,term N}
Document Vector = {weight 1偶摔,weight 2,...促脉,weight N}

同樣我們把查詢語句看作一個簡單的文檔辰斋,也用向量來表示。

Query = {term 1瘸味,term 2宫仗,...,term N}
Query Vector = {weight 1旁仿,weight 2藕夫,...,weight N}

我們把所有搜索出的文檔向量以及查詢向量放到一個N維空間中,每個詞(term)是一維毅贮。如圖:

vsm

我們認(rèn)為兩個向量之間的夾角越小梭姓,相關(guān)性越大。

所以我們計(jì)算夾角的余弦值作為相關(guān)性的打分嫩码,夾角越小誉尖,余弦值越大,打分越高铸题,相關(guān)性越大铡恕。

有人可能會問,查詢語句一般是很短的丢间,包含的詞(Term)是很少的探熔,因而查詢向量的維數(shù)很小,而文檔很長烘挫,包含的詞(Term)很多诀艰,文檔向量維數(shù)很大。你的圖中兩者維數(shù)怎么都是N呢饮六?

在這里其垄,既然要放到相同的向量空間,自然維數(shù)是相同的卤橄,不同時绿满,取兩者的并集,如果不含某個詞(Term)時窟扑,則權(quán)重(Term weight)為0喇颁。

相關(guān)性打分公式如下:

舉個例子,查詢語句有11個Term嚎货,共有三篇文檔搜索出來橘霎。其中各自的權(quán)重(Term weight),如下表格殖属。

t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11
D1 0 0 .477 0 .477 .176 0 0 0 .176 0
D2 0 .176 0 .477 0 0 0 0 .954 0 .176
D3 0 .176 0 0 0 .176 0 0 0 .176 .176
Q 0 0 0 0 0 .176 0 0 .477 0 .176

于是計(jì)算姐叁,三篇文章同查詢語句的相關(guān)性打分分別為:

于是文檔二相關(guān)性最高,先返回忱辅,其次是文檔一七蜘,最后是文檔三。

到此為止墙懂,我們可以找到我們想要的文檔了橡卤。

說了這么多,其實(shí)還沒有進(jìn)到Lucene损搬,而僅僅是纖細(xì)檢索技術(shù)(Information retrieval)中的基本理論碧库,然而當(dāng)我們看過Lucene后我們會發(fā)現(xiàn)柜与,Lucene是對這種基本理論的一種基本的實(shí)踐。所以在以后分析Lucene的文章中嵌灰,會常撑埃看到以上理論在Lucene中的應(yīng)用。

在進(jìn)入Lucene之前沽瞭,對上述索引創(chuàng)建和搜索過程做一個總結(jié)迁匠,如圖:

1. 索引過程:
a) 有一系列被索引的文件
b) 被索引的文件經(jīng)過語法分析和語言處理形成一系列詞(Term)
c) 經(jīng)過索引創(chuàng)建形成詞典和反向索引表
d) 通過索引過程將索引寫入磁盤

2. 搜索過程:
a) 用戶輸入查詢語句
b) 對查詢語句經(jīng)過詞法分析和語言分析得到一系列詞(Term)
c) 通過語法分析得到一個查詢樹
d) 通過索引存儲將索引讀到內(nèi)存
e) 利用查詢樹搜索索引,從而得到每個詞(Term)的文檔列表驹溃,對文檔列表進(jìn)行交城丧、差、并得到結(jié)果文檔
f) 將搜索到的結(jié)果文檔按照對查詢語句的相關(guān)性進(jìn)行排序
g) 返回查詢結(jié)果給用戶


下面可以進(jìn)入Lucene的世界了豌鹤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亡哄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子布疙,更是在濱河造成了極大的恐慌蚊惯,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灵临,死亡現(xiàn)場離奇詭異截型,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)俱诸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門菠劝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人睁搭,你說我怎么就攤上這事×剑” “怎么了园骆?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長寓调。 經(jīng)常有香客問我锌唾,道長,這世上最難降的妖魔是什么夺英? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任晌涕,我火速辦了婚禮,結(jié)果婚禮上痛悯,老公的妹妹穿的比我還像新娘余黎。我一直安慰自己,他們只是感情好载萌,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布惧财。 她就那樣靜靜地躺著巡扇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垮衷。 梳的紋絲不亂的頭發(fā)上厅翔,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機(jī)與錄音搀突,去河邊找鬼刀闷。 笑死,一個胖子當(dāng)著我的面吹牛仰迁,可吹牛的內(nèi)容都是我干的甸昏。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼轩勘,長吁一口氣:“原來是場噩夢啊……” “哼筒扒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起绊寻,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤花墩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后澄步,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冰蘑,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年村缸,在試婚紗的時候發(fā)現(xiàn)自己被綠了祠肥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡梯皿,死狀恐怖仇箱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情东羹,我是刑警寧澤剂桥,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站属提,受9級特大地震影響权逗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冤议,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一斟薇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恕酸,春花似錦堪滨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惶岭。三九已至,卻和暖如春犯眠,著一層夾襖步出監(jiān)牢的瞬間按灶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工筐咧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸯旁,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓量蕊,卻偏偏與公主長得像铺罢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子残炮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容