6棍鳖、分詞(lucene筆記)

一、概述

1.1 分詞的基本過(guò)程

首先是TokenStream通過(guò)接收一個(gè)StringReader流將需要進(jìn)行分詞的內(nèi)容讀入進(jìn)來(lái)相味,TokenStream有兩個(gè)子抽象類TokenizerTokenFilter粹胯。讀入的過(guò)程為:StringReader流經(jīng)過(guò)Tokenizer接收輸入流并根據(jù)輸入流進(jìn)行詞切分,然后會(huì)經(jīng)過(guò)多個(gè)TokenFilter對(duì)TokenStream進(jìn)行過(guò)濾咨演,例如去掉一些索引詞闸昨、替代同義索引詞等操作,最后生成TokenStream薄风。

1.2 Tokenizer

1

Tokenizer主要負(fù)責(zé)接收Reader字節(jié)流饵较,將Reader進(jìn)行分詞操作,即將一組數(shù)據(jù)劃分不同的語(yǔ)匯單元遭赂。KeyWordTokenizer是關(guān)鍵詞分詞循诉,StandardTokenizer是標(biāo)準(zhǔn)分詞,CharTokenizer是字符分詞撇他,WhitespaceTokenizer是空白分詞茄猫,LetterTokenizer是標(biāo)點(diǎn)分詞,LowerCaseTokenizer是小寫(xiě)分詞(將各個(gè)語(yǔ)匯單元轉(zhuǎn)換成小寫(xiě))困肩。
這里我們說(shuō)明一下WhitespaceTokenizerLetterTokenizer划纽,比如有這樣一句內(nèi)容:how are you I’m a teacher。那么前者會(huì)分成這樣:how锌畸、 are勇劣、 you、 I’m、 a比默、 teacher幻捏,而后者會(huì)分成:how、 are命咐、 you篡九、 I 、m醋奠、 a榛臼、 teacher

1.3 TokenFilter

2

TokenFilter類繼承于TokenStream钝域,其輸入是另一個(gè)TokenStream讽坏,主要職責(zé)是對(duì)TokenStream進(jìn)行過(guò)濾,例如去掉一些索引詞例证、替代同義索引詞等操作路呜。上面給出各類過(guò)濾器,這里只是作為了解织咧,后面再細(xì)說(shuō)胀葱。

二、入門(mén)示例(工程lucene_analyzer01

AnalyzerUtils.java

package cn.itcast.util;
import java.io.IOException;
import java.io.StringReader;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;

public class AnalyzerUtils {
    public static void displayToken(String str, Analyzer analyzer) {
        try {
            //首先我們使用分詞器analyzer將相關(guān)數(shù)據(jù)(這里比如是內(nèi)容gcontent)進(jìn)行分詞笙蒙,這樣得到一個(gè)詞匯流
            //然后我們給這個(gè)流做一個(gè)標(biāo)記抵屿,可以用來(lái)遍歷此流
            TokenStream stream = analyzer.tokenStream("content",new StringReader(str));//這就是一個(gè)詞匯流
            CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);//相當(dāng)于一個(gè)標(biāo)記,隨著流增加
            while (stream.incrementToken()) {
                System.out.print("[" + cta + "]");
            }
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

測(cè)試:TestAnalyzer.java

@Test
public void test01(){
    Analyzer analyzer1 = new StandardAnalyzer(Version.LUCENE_35);//標(biāo)準(zhǔn)分詞器
    Analyzer analyzer2 = new StopAnalyzer(Version.LUCENE_35);//停用分詞器
    Analyzer analyzer3 = new SimpleAnalyzer(Version.LUCENE_35);//簡(jiǎn)單分詞器
    Analyzer analyzer4 = new WhitespaceAnalyzer(Version.LUCENE_35);//空格分詞器
    
    String text = "this is my house,I am come form Xian,My email is "
            + "xxx@qq.com,and my qq is 154625554";
    AnalyzerUtils.displayToken(text, analyzer1);
    AnalyzerUtils.displayToken(text, analyzer2);
    AnalyzerUtils.displayToken(text, analyzer3);
    AnalyzerUtils.displayToken(text, analyzer4);
}

說(shuō)明:可以看到我們構(gòu)造一個(gè)TokenStream 流捅位,此流接收兩個(gè)參數(shù)轧葛,第一個(gè)參數(shù)表示要進(jìn)行分詞的域(這里隨便),而第二個(gè)參數(shù)就是一個(gè)StringReader流艇搀。而CharTermAttribute 相當(dāng)于流中的一個(gè)標(biāo)記尿扯,隨著流而增減,用戶我們遍歷流中各個(gè)語(yǔ)匯單元焰雕。而相關(guān)的分詞器我們通過(guò)參數(shù)傳入進(jìn)去衷笋。分詞結(jié)果為:

3

從結(jié)果我們可以看到各個(gè)分詞器的作用和區(qū)別。下面我們?cè)贉y(cè)試一下中文分詞:

@Test
public void test02(){
    //對(duì)中文分詞不適用
    Analyzer analyzer1 = new StandardAnalyzer(Version.LUCENE_35);//標(biāo)準(zhǔn)分詞器
    Analyzer analyzer2 = new StopAnalyzer(Version.LUCENE_35);//停用分詞器
    Analyzer analyzer3 = new SimpleAnalyzer(Version.LUCENE_35);//簡(jiǎn)單分詞器
    Analyzer analyzer4 = new WhitespaceAnalyzer(Version.LUCENE_35);//空格分詞器
    
    String text = "西安市雁塔區(qū)";
    AnalyzerUtils.displayToken(text, analyzer1);
    AnalyzerUtils.displayToken(text, analyzer2);
    AnalyzerUtils.displayToken(text, analyzer3);
    AnalyzerUtils.displayToken(text, analyzer4);
}

測(cè)試結(jié)果為:


4

可見(jiàn)一般的分詞器對(duì)中文分詞作用不大矩屁。

下面看語(yǔ)匯單元的一些屬性:
AnalyzerUtils.java

public static void displayAllTokenInfo(String str, Analyzer analyzer){
    try {
        TokenStream stream = analyzer.tokenStream("content", new StringReader(str));
        PositionIncrementAttribute pia = stream.addAttribute(PositionIncrementAttribute.class);
        OffsetAttribute oa = stream.addAttribute(OffsetAttribute.class);
        CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
        TypeAttribute ta = stream.addAttribute(TypeAttribute.class);

        while (stream.incrementToken()) {
            System.out.print("位置增量: " + pia.getPositionIncrement());//詞與詞之間的空格
            System.out.print("辟宗,單詞: " + cta + "[" + oa.startOffset() + "," + oa.endOffset() + "]");
            System.out.print(",類型: " + ta.type()) ;
            System.out.println();
        }
        System.out.println();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

測(cè)試

@Test
public void test03(){
    //對(duì)中文分詞不適用
    Analyzer analyzer1 = new StandardAnalyzer(Version.LUCENE_35);//標(biāo)準(zhǔn)分詞器
    Analyzer analyzer2 = new StopAnalyzer(Version.LUCENE_35);//停用分詞器
    Analyzer analyzer3 = new SimpleAnalyzer(Version.LUCENE_35);//簡(jiǎn)單分詞器
    Analyzer analyzer4 = new WhitespaceAnalyzer(Version.LUCENE_35);//空格分詞器
    
    String text = "how are you thank you";
    System.out.println("************標(biāo)準(zhǔn)分詞器***************");
    AnalyzerUtils.displayAllTokenInfo(text, analyzer1);
    System.out.println("************停用分詞器***************");
    AnalyzerUtils.displayAllTokenInfo(text, analyzer2);
    System.out.println("************簡(jiǎn)單分詞器***************");
    AnalyzerUtils.displayAllTokenInfo(text, analyzer3);
    System.out.println("*************空格分詞器**************");
    AnalyzerUtils.displayAllTokenInfo(text, analyzer4);
}

說(shuō)明:

  • 語(yǔ)匯單元類型TypeAttribute:語(yǔ)匯單元的類型吝秕,一般有wordALPHANUM兩種類型泊脐。
  • 語(yǔ)匯單元偏移量OffsetAttribute:就是起始字符和終止字符之間的偏移量。這里我們舉例說(shuō)明烁峭,比如對(duì)how are you thank you進(jìn)行分詞晨抡,那么各個(gè)語(yǔ)匯單元之間的偏移量為
    5
  • 語(yǔ)匯單元位置增量PositionIncrementAttribute:位置增量就是語(yǔ)匯單元之間的距離,比如上面的分詞如果不將某些語(yǔ)匯濾除,那么各個(gè)語(yǔ)匯單元之間的位置增量都是1耘柱,但是如果有些單元被濾掉,比如are關(guān)鍵詞棍现,那么howyou之間的位置增量則為2调煎。我們看測(cè)試結(jié)果為:
    6
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市己肮,隨后出現(xiàn)的幾起案子士袄,更是在濱河造成了極大的恐慌,老刑警劉巖谎僻,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娄柳,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡艘绍,警方通過(guò)查閱死者的電腦和手機(jī)赤拒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)诱鞠,“玉大人挎挖,你說(shuō)我怎么就攤上這事『蕉幔” “怎么了蕉朵?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)阳掐。 經(jīng)常有香客問(wèn)我始衅,道長(zhǎng),這世上最難降的妖魔是什么缭保? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任汛闸,我火速辦了婚禮,結(jié)果婚禮上涮俄,老公的妹妹穿的比我還像新娘蛉拙。我一直安慰自己,他們只是感情好彻亲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布孕锄。 她就那樣靜靜地躺著,像睡著了一般苞尝。 火紅的嫁衣襯著肌膚如雪畸肆。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天宙址,我揣著相機(jī)與錄音轴脐,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛大咱,可吹牛的內(nèi)容都是我干的恬涧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼碴巾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼溯捆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起厦瓢,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤提揍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后煮仇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體劳跃,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浙垫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年贸人,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佃声。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡艺智,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出圾亏,到底是詐尸還是另有隱情十拣,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布志鹃,位于F島的核電站夭问,受9級(jí)特大地震影響曹铃,放射性物質(zhì)發(fā)生泄漏缰趋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一陕见、第九天 我趴在偏房一處隱蔽的房頂上張望秘血。 院中可真熱鬧,春花似錦评甜、人聲如沸粘舟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柑肴。三九已至霞揉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嘉抒,已是汗流浹背零聚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留些侍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓政模,卻偏偏與公主長(zhǎng)得像岗宣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子淋样,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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

  • 一趁猴、自定義分詞器 這里我們自定義一個(gè)停用分詞器刊咳,也就是在進(jìn)行分詞的時(shí)候?qū)⒛承┰~過(guò)濾掉。MyStopAnalyzer...
    yjaal閱讀 4,674評(píng)論 0 4
  • 詞匯單元流 lucene的分詞過(guò)程儡司,是從Reader中獲取原始字符流娱挨,產(chǎn)生語(yǔ)匯單元流TokenStream的過(guò)程。...
    愚公300代閱讀 1,373評(píng)論 0 1
  • 昨天晚上去通宵上網(wǎng)了捕犬,很久沒(méi)去過(guò)了跷坝,總是告訴自己要健康生活,通宵對(duì)身體不好碉碉。但是去過(guò)之后柴钻,感覺(jué)好jb滿足。...
    奮力向上的魚(yú)閱讀 308評(píng)論 0 0
  • 五 紅星星用手推了推下巴垢粮,才把嘴巴合攏贴届。又拍了拍腦袋,回憶起了過(guò)去的一幕幕蜡吧。一些事情...
    佛在欽山閱讀 443評(píng)論 2 6