原文鏈接# 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)
左邊保存的是一系列字符串,稱為詞典败潦。
每個字符串都指向包含此字符串的的文檔(Document)鏈表本冲,此文檔鏈表成為倒排表(Posting List)。
有了索引劫扒,便使保存的信息和要搜索的信息一致檬洞,可以大大加快搜索的速度。
比如說沟饥,我們要尋找既包含字符串"lucene"又包含字符串"solr"的文檔添怔,我們只需要以下幾步:
- 取出包含字符串"lucene"的文檔鏈表
- 取出包含字符串"solr"的文檔鏈表
- 通過合并鏈表,找出既包含"lucene"又包含"solr"的文件贤旷。
看到這個地方广料,可能有人會說,全文索引的確加快了搜索的速度幼驶,但是多了索引的過程艾杏,兩者加起來不一定比順序掃描快多少。的確盅藻,加上索引的過程购桑,全文檢索不一定比順序掃描快,尤其是在數(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)
在此表中稳懒,有幾個定義:
- 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)的放在最前面呢心铃?
當(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)過語言處理的語法樹。
第三步:搜索索引旱眯,得到符合語法樹的文檔晨川。
此步驟又分幾小步:
- 首先,在反向索引表中删豺,分別找出包含lucene共虑,learn,hadoop的文檔鏈表呀页。
- 其次妈拌,對包含lucene,learn的鏈表進(jìn)行合并操作赔桌,得到既包含lucene又包含learn的文檔鏈表供炎。
- 然后渴逻,將此鏈表與hadoop的文檔鏈表進(jìn)行差操作疾党,去除包含hadoop的文檔音诫,從而得到既包含lucene又包含learned而且不包含hadoop的文檔鏈表。
- 此文檔鏈表就是我們要找的文檔雪位。
第四步:根據(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)是一維毅贮。如圖:
我們認(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的世界了豌鹤。