Lucene--相關(guān)度排序和中文分析器

一、相關(guān)度排序

1.什么是相關(guān)度排序

相關(guān)度排序是查詢結(jié)果按照與查詢關(guān)鍵字的相關(guān)性進(jìn)行排序,越相關(guān)的越靠前。比如搜索“Lucene”關(guān)鍵字,與該關(guān)鍵字最相關(guān)的文章應(yīng)該排在前邊。

2.相關(guān)度打分

Lucene對(duì)查詢關(guān)鍵字和索引文檔的相關(guān)度進(jìn)行打分,得分高的就排在前邊。如何打分呢?Lucene是在用戶進(jìn)行檢索時(shí)實(shí)時(shí)根據(jù)搜索的關(guān)鍵字計(jì)算出來(lái)的,分兩步:

  1. 計(jì)算出詞(Term)的權(quán)重
  2. 根據(jù)詞的權(quán)重值,計(jì)算文檔相關(guān)度得分。

什么是詞的權(quán)重?
明確索引的最小單位是一個(gè)Term(索引詞典中的一個(gè)詞),搜索也是要從Term中搜索,再根據(jù)Term找到文檔,Term對(duì)文檔的重要性稱為權(quán)重,影響Term權(quán)重有兩個(gè)因素:

  • Term Frequency (tf):
    指此Term在此文檔中出現(xiàn)了多少次。tf 越大說(shuō)明越重要。 詞(Term)在文檔中出現(xiàn)的次數(shù)越多,說(shuō)明此詞(Term)對(duì)該文檔越重要,如“Lucene”這個(gè)詞,在文檔中出現(xiàn)的次數(shù)很多,說(shuō)明該文檔主要就是講Lucene技術(shù)的。

  • Document Frequency (df):
    指有多少文檔包含次Term。df 越大說(shuō)明越不重要。
    比如,在一篇英語(yǔ)文檔中,this出現(xiàn)的次數(shù)更多,就說(shuō)明越重要嗎?不是的,有越多的文檔包含此詞(Term), 說(shuō)明此詞(Term)太普通,不足以區(qū)分這些文檔,因而重要性越低。

3.設(shè)置boost值影響相關(guān)度排序

boost是一個(gè)加權(quán)值(默認(rèn)加權(quán)值為1.0f),它可以影響權(quán)重的計(jì)算。

  • 在索引時(shí)對(duì)某個(gè)文檔中的field設(shè)置加權(quán)值高,在搜索時(shí)匹配到這個(gè)文檔就可能排在前邊。
  • 在搜索時(shí)對(duì)某個(gè)域進(jìn)行加權(quán),在進(jìn)行組合域查詢時(shí),匹配到加權(quán)值高的域最后計(jì)算的相關(guān)度得分就高。

設(shè)置boost是給域(field)或者Document設(shè)置的。

3.1 在創(chuàng)建索引時(shí)設(shè)置

如果希望某些文檔更重要,當(dāng)此文檔中包含所要查詢的詞則應(yīng)該得分較高,這樣相關(guān)度排序可以排在前邊,可以在創(chuàng)建索引時(shí)設(shè)定文檔中某些域(Field)的boost值來(lái)實(shí)現(xiàn),如果不進(jìn)行設(shè)定,則Field Boost默認(rèn)為1.0f。一旦設(shè)定,除非刪除此文檔,否則無(wú)法改變。

@Test
public void setBoost4createIndex() throws Exception {
    // 創(chuàng)建分詞器
    Analyzer analyzer = new StandardAnalyzer();

    IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,
            analyzer);
    Directory directory = FSDirectory.open(new File("E:\\11-index\\0728"));
    // 創(chuàng)建IndexWriter對(duì)象,通過(guò)它把分好的詞寫(xiě)到索引庫(kù)中
    IndexWriter writer = new IndexWriter(directory, cfg);

    Document doc = new Document();
    Field id = new StringField("id", "11", Store.YES);
    Field description = new TextField("description", "測(cè)試設(shè)置BOOST值 lucene",
            Store.YES);
    // 設(shè)置boost
    description.setBoost(10.0f);
    // 把域添加到文檔中
    doc.add(id);
    doc.add(description);
    writer.addDocument(doc);
    // 關(guān)閉IndexWriter
    writer.close();
}

輸出:

輸出.png

3.2 在查詢索引時(shí)設(shè)置

在MultiFieldQueryParser創(chuàng)建時(shí)設(shè)置boost值。

@Test
public void multiFieldQueryParser() throws Exception {
    // 創(chuàng)建7.3.2 MultiFieldQueryParser
    // 默認(rèn)搜索的多個(gè)域的域名
    String[] fields = { "name", "description" };
    Analyzer analyzer = new StandardAnalyzer();
    Map<String, Float> boosts = new HashMap<String, Float>();
    boosts.put("name", 200f);
    MultiFieldQueryParser parser = new MultiFieldQueryParser(fields,
            analyzer, boosts);

    // Query query = parser.parse("name:lucene OR description:lucene");
    //等同于name:lucene OR description:lucene
    Query query = parser.parse("java");
    System.out.println(query);
    doSearch(query);
}

二、中文分詞器

1.什么是中文分詞器

英文是以單詞為單位的,單詞與單詞之間以空格或者逗號(hào)句號(hào)隔開(kāi)。而中文則以字為單位,字又組成詞,字和詞再組成句子。所以對(duì)于英文,我們可以簡(jiǎn)單以空格判斷某個(gè)字符串是否為一個(gè)單詞,比如I love China,love 和 China很容易被程序區(qū)分開(kāi)來(lái);但中文“我愛(ài)中國(guó)”就不一樣了,電腦不知道“中國(guó)”是一個(gè)詞語(yǔ)還是“愛(ài)中”是一個(gè)詞語(yǔ)。把中文的句子切分成有意義的詞,就是中文分詞,也稱切詞。我愛(ài)中國(guó),分詞的結(jié)果是:我 愛(ài) 中國(guó)。

2.Lucene自帶的中文分詞器

  • StandardAnalyzer:
    單字分詞:就是按照中文一個(gè)字一個(gè)字地進(jìn)行分詞。如:“我愛(ài)中國(guó)”,
    效果:“我”、“愛(ài)”、“中”、“國(guó)”。

  • CJKAnalyzer:
    二分法分詞:按兩個(gè)字進(jìn)行切分。如:“我是中國(guó)人”,效果:“我是”、“是中”、“中國(guó)”“國(guó)人”。

上邊兩個(gè)分詞器無(wú)法滿足需求。

3.第三方中文分詞器

  • paoding: 庖丁解牛最新版在 https://code.google.com/p/paoding/ 中最多支持Lucene 3.0,且最新提交的代碼在 2008-06-03,在svn中最新也是2010年提交,已經(jīng)過(guò)時(shí),不予考慮。

  • mmseg4j:最新版已從 https://code.google.com/p/mmseg4j/ 移至 https://github.com/chenlb/mmseg4j-solr,支持Lucene 4.10,且在github中最新提交代碼是2014年6月,從09年~14年一共有:18個(gè)版本,也就是一年幾乎有3個(gè)大小版本,有較大的活躍度,用了mmseg算法。

  • IK-analyzer: 最新版在https://code.google.com/p/ik-analyzer/上,支持Lucene 4.10從2006年12月推出1.0版開(kāi)始, IKAnalyzer已經(jīng)推出了4個(gè)大版本。最初,它是以開(kāi)源項(xiàng)目Luence為應(yīng)用主體的,結(jié)合詞典分詞和文法分析算法的中文分詞組件。從3.0版本開(kāi) 始,IK發(fā)展為面向Java的公用分詞組件,獨(dú)立于Lucene項(xiàng)目,同時(shí)提供了對(duì)Lucene的默認(rèn)優(yōu)化實(shí)現(xiàn)。在2012版本中,IK實(shí)現(xiàn)了簡(jiǎn)單的分詞 歧義排除算法,標(biāo)志著IK分詞器從單純的詞典分詞向模擬語(yǔ)義分詞衍化。 但是也就是2012年12月后沒(méi)有在更新。

  • ansj_seg:最新版本在 https://github.com/NLPchina/ansj_seg tags僅有1.1版本,從2012年到2014年更新了大小6次,但是作者本人在2014年10月10日說(shuō)明:“可能我以后沒(méi)有精力來(lái)維護(hù)ansj_seg了”,現(xiàn)在由”nlp_china”管理。2014年11月有更新。并未說(shuō)明是否支持Lucene,是一個(gè)由CRF(條件隨機(jī)場(chǎng))算法所做的分詞算法。

  • imdict-chinese-analyzer:最新版在 https://code.google.com/p/imdict-chinese-analyzer/ , 最新更新也在2009年5月,下載源碼,不支持Lucene 4.10 。是利用HMM(隱馬爾科夫鏈)算法。

  • Jcseg:最新版本在git.oschina.net/lionsoul/jcseg,支持Lucene 4.10,作者有較高的活躍度。利用mmseg算法。

4.使用中文分詞器IKAnalyzer

Ikanalyzer.png

IKAnalyzer繼承Lucene的Analyzer抽象類,使用IKAnalyzer和Lucene自帶的分析器方法一樣,將Analyzer測(cè)試代碼改為IKAnalyzer測(cè)試中文分詞效果。

如果使用中文分詞器ik-analyzer,就在索引和搜索程序中使用一致的分詞器ik-analyzer。

4.1添加jar包

jar包.png

4.2 修改分詞器代碼

// 創(chuàng)建分詞器,標(biāo)準(zhǔn)分詞器
// Analyzer analyzer = new StandardAnalyzer();
// 使用ikanalyzer
Analyzer analyzer = new IKAnalyzer();

5.擴(kuò)展中文詞庫(kù)

將以下文件拷貝到config目錄下

所需的文件.png

從ikanalyzer包中拷貝配置文件到classpath下。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  

    <comment>IK Analyzer 擴(kuò)展配置</comment>
    <!-- 用戶可以在這里配置自己的擴(kuò)展字典 -->
     <entry key="ext_dict">dicdata/mydict.dic</entry> 
     <!-- 用戶可以在這里配置自己的擴(kuò)展停用詞字典    -->
    <entry key="ext_stopwords">dicdata/ext_stopword.dic</entry> 

</properties>

如果想配置擴(kuò)展詞和停用詞,就創(chuàng)建擴(kuò)展詞的文件和停用詞的文件,文件的編碼要是utf-8。

注意:不要用記事本保存擴(kuò)展詞文件和停用詞文件,那樣的話,格式中是含有bom的。

添加擴(kuò)展詞文件:ext.dic,內(nèi)容:我愛(ài)中國(guó)

6.使用luke測(cè)試中文分詞

第一步:將ikanalyzer的jar包,拷貝到luke工具的目錄

測(cè)試1.png

使用Luke測(cè)試第三方分詞器分詞效果,需通過(guò)java.ext.dirs加載jar包:
可簡(jiǎn)單的將第三方分詞器和lukeall放在一塊兒,cmd下運(yùn)行:

11.png

第二步:使用命令打開(kāi)luke工具:

java -Djava.ext.dirs=. -jar lukeall-4.10.3.jar
測(cè)試2.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.Search Engine 目前主流的開(kāi)源搜索引擎主要有兩個(gè),一個(gè)是基于Java的Apache Lucene,...
    秦漢郵俠閱讀 888評(píng)論 0 1
  • 常用概念: 自然語(yǔ)言處理(NLP) 數(shù)據(jù)挖掘 推薦算法 用戶畫(huà)像 知識(shí)圖譜 信息檢索 文本分類 常用技術(shù): 詞級(jí)別...
    御風(fēng)之星閱讀 9,963評(píng)論 1 25
  • 包括內(nèi)容: IK分詞組件的添加和配置 索引建立及高亮搜索示例 添加自定義分詞的測(cè)試 版本: ES - 2.4.5,...
    君劍閱讀 8,999評(píng)論 0 0
  • 這周過(guò)得比較平靜,沒(méi)有什么新鮮的事,上課還是像往常一樣。 值得說(shuō)的是,在同一天兩個(gè)老師給我們介紹了一本叫(國(guó)富論)...
    悠悠99閱讀 430評(píng)論 0 0
  • 克里斯托弗·諾蘭導(dǎo)演的電影《星際穿越》是一部燒腦之作,電影里涉及到許多深?yuàn)W的物理學(xué)、天文學(xué)知識(shí),要完整了解電影的全...
    5bd376ea631b閱讀 1,762評(píng)論 0 1

友情鏈接更多精彩內(nèi)容