介紹一款全文搜索引擎--lucene
時(shí)間:2023-03-16 19:42:01 | 來源:電子商務(wù)
時(shí)間:2023-03-16 19:42:01 來源:電子商務(wù)
今天我想給大家介紹的,是一款叫做lucene的開源搜索引擎。它是基于java環(huán)境下的,一款全文搜索引擎。如果你需要對(duì)非常多的文檔進(jìn)行搜索,可以考慮使用它。
lucene進(jìn)行搜索1. 通過對(duì)目標(biāo)文檔的處理,得到一個(gè)新的處理好的index。這些index是長成這個(gè)樣子的:在這里,lucene 所做的事情其實(shí)是把這些文檔中的話先進(jìn)行預(yù)處理。比如lucene會(huì)把"BitTiger" 轉(zhuǎn)換成"bitgtiger" 也就是全部小寫化。之后呢,lucene 會(huì)為你的文檔建立一個(gè)matrix。這里我直接開始舉例說明。
doc1 : "I love programming";doc2: "programming is necessary skills and you should love it "lucene 會(huì)建立如下的索引結(jié)構(gòu):
term docs locationI 1 1.0 love 1,2 1.2->2.47programming 1,2 1.7->2.00skills 2 2.26and 2 ---you 2 ---it 2 ---is 2 ---term 代表出現(xiàn)在文檔中的一個(gè)一個(gè)詞語,docs代表的是這個(gè)文檔的編號(hào),lcoation代表的是詞語出現(xiàn)在文檔中的某個(gè)位置。在lucene當(dāng)中,詞語的位置是用一個(gè)linkedlist 串聯(lián)起來的。
如果你要對(duì)一段文檔進(jìn)行索引,在API,你要做的事情很簡(jiǎn)單,我在這里直接貼代碼
String path = "XXXXX"; -----------
你文檔的路徑final Path docDirs = Paths.get(Path);
// 你建立索引的路徑Directory dic_siwei = FSDirectory.open(Paths.get("你建立一個(gè)大索引的路徑"));
Analyzer analyzer = new StandardAnalyzer(); ------
構(gòu)建分析器,它的作用是對(duì)文檔語言進(jìn)行處理//配置索引writer和建立一個(gè)索引IndexWriterConfig conf = new IndexWriterConfig(analyzer);
IndexWriter writer = new IndexWriter(dic_siwei,conf);
Document docs = new Document();
這里docDir是單獨(dú)一個(gè)文件的路徑,我省略了之前的一個(gè)方法,大家知道就行
InputStream stream = Files.newInputStream(docDir);
doc.add(new TextField("contents", new BufferedReader(newInputStreamReader(stream, StandardCharsets.UTF_8))));
writer.close();
這之后,你們就可以創(chuàng)建好一份索引。在這里你會(huì)問,如果我的添加了一個(gè)新的索引,那么我需不需要重新跑一次我的程序,去建立一個(gè)新的索引。在這里,lucene處理的很好。當(dāng)你有新的文件需要進(jìn)行處理,lucene提供了一個(gè)"updata" 接口可以將你的新內(nèi)容加入到原來的索引文件中。
2.建立好索引之后如何進(jìn)行搜索?我覺得在這里,我想談?wù)刲ucene的打分機(jī)制。比如我搜索“dota ti5”,我希望第一個(gè)搜索的結(jié)果文檔叫做"dota2"而不是“英雄聯(lián)盟(LOL)”.那么lucene是如何做的呢?
lucene 默認(rèn)的搜索算法叫做TF/IDF 算法。
2.1(TF/IDF 算法)TF-IDF算法全稱為term frequency–inverse document frequency。TF就是term frequency的縮寫,意為詞頻。IDF則是inverse document frequency的縮寫,意為逆文檔頻率。
該算法在信息處理中通常用來抽取關(guān)鍵詞。比如,對(duì)一個(gè)文章提取關(guān)鍵詞作為搜索詞,就可以采用TF-IDF算法。
要找出一篇文章中的關(guān)鍵詞,通常的思路就是,就是找到出現(xiàn)次數(shù)最多的詞。如果某個(gè)詞很重要,它應(yīng)該在這篇文章中多次出現(xiàn)。于是,我們進(jìn)行"詞頻"(Term Frequency,縮寫為TF)統(tǒng)計(jì)。
但是通常,一篇中文的文章中,都會(huì)有很多沒有實(shí)際意義的詞,比如“的”,“是”,“了”,這類詞是最常用的詞,稱為停用詞,稱它們?yōu)橥S迷~是因?yàn)樵谖谋咎幚磉^程中如果遇到它們,則立即停止處理,將其扔掉。將這些詞扔掉減少了索引量,增加了檢索效率,并且通常都會(huì)提高檢索的效果。停用詞主要包括英文字符、數(shù)字、數(shù)學(xué)字符、標(biāo)點(diǎn)符號(hào)及使用頻率特高的單漢字等。
當(dāng)過濾掉所有的停用詞后,剩下的都是實(shí)際意義的詞,但也不能簡(jiǎn)單的認(rèn)為那個(gè)詞出現(xiàn)的次數(shù)多就是關(guān)鍵詞。比如在一篇如何組裝電腦的文章中,出現(xiàn)“CPU”,“主板”等關(guān)鍵詞和出現(xiàn)“說明書”的次數(shù)一樣多,但很顯然,CPU,主板等關(guān)鍵詞,更能確定這個(gè)文章的特性。也就是說,“CPU”,“主板”等關(guān)鍵詞比“說明書”這個(gè)關(guān)鍵詞更重要,需要排在前面。所以我們就需要一個(gè)權(quán)重系數(shù),用來調(diào)整各個(gè)關(guān)鍵詞的重要性。如果一個(gè)詞很少見,但是它在某個(gè)文章中反復(fù)出現(xiàn)多次,那么可以認(rèn)為這個(gè)詞反應(yīng)了這個(gè)文章的特性,可以把它作為關(guān)鍵詞。在信息檢索中,這個(gè)權(quán)重非常重要,它決定了關(guān)鍵詞的重要度,這個(gè)權(quán)重叫做"逆文檔頻率"(Inverse Document Frequency,縮寫為IDF),它的大小與一個(gè)詞的常見程度成反比。
在知道了詞頻和權(quán)重之后,兩者相乘,就得到一個(gè)詞的TF-IDF值,某個(gè)詞對(duì)文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的幾個(gè)詞,就是這篇文章的關(guān)鍵詞。
因此TF-IDF算法的主要工作就是計(jì)算出TF*IDF值最大的那幾個(gè)詞,作為文章的關(guān)鍵詞。
可是,TF-IDF算法的優(yōu)點(diǎn)是簡(jiǎn)單快速,結(jié)果比較符合實(shí)際情況。缺點(diǎn)是,單純以"詞頻"衡量一個(gè)詞的重要性,不夠全面,有時(shí)重要的詞可能出現(xiàn)次數(shù)并不多。而且,這種算法無法體現(xiàn)詞的位置信息,出現(xiàn)位置靠前的詞與出現(xiàn)位置靠后的詞,都被視為重要性相同,這是不正確的。(一種解決方法是,對(duì)全文的第一段和每一段的第一句話,給予較大的權(quán)重。)
當(dāng)通過TF-IDF算法找出文章的關(guān)鍵字后,可以運(yùn)用到一些具體的場(chǎng)景。比如:根據(jù)關(guān)鍵字找出相似的文章。
2.2 代碼怎么寫?//配置搜索器IndexReader reade=DirectoryReader.open(FSDirectory.open(Paths.get(“你剛才建立索引的文件夾”)));
IndexSearcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser(field, analyzer);
Query query = parser.parse("你要搜索的內(nèi)容");
// topDocs 就是就是你要得到的10個(gè)評(píng)分最高的文檔TopDocs results = searcher.search(query, 10);
2.3 其他算法擴(kuò)展如果你認(rèn)為lucene本身的算法不夠好,那么你可以考慮去實(shí)現(xiàn)其他的算法。比如BM25和BM25F算法。在lucene當(dāng)中,如果你想更改原本的算法,那么你需要extends原來的Similarity類,然后將它配置到你的索引writer的配置中。如果你需要更好的索引。那么你可能需要為lucene重寫很多代碼,包括權(quán)重包(Weight),Query包(查詢),Score包(打分)。
3.小小的展望這是博主第一次寫博客,真的第一次都獻(xiàn)給了BitTiger啊有木有!博主表示如果文章寫的不好,請(qǐng)見諒??!
小組簡(jiǎn)介:亞特蘭大地區(qū)小組Ranger,我們四個(gè)人都是CS相關(guān)專業(yè)的學(xué)生,三位GT一位Emory的。這里誠招一位兼職技術(shù)顧問,學(xué)生黨經(jīng)驗(yàn)不足??!
作者:污妖王, 編輯:王思維,
查看更多精彩博客文章:
https://www.bittiger.io/blog更多內(nèi)容,請(qǐng)?jiān)L問:BitTiger.io, 掃描下面二維碼,關(guān)注微信公眾賬號(hào)“論碼農(nóng)的自我修養(yǎng)”