欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Lucene于搜索引擎技術(shù)(Analysis包詳解)

Lucene與搜索引擎技術(shù)

TjuAILab  windshow  2005.11.11

Analysis包分析

算法和數據結構分析:

由于Analysis包比較簡(jiǎn)單,不詳述了!

算法:基于機械分詞 1-gram,2-gram,HMM(如果使用ICTCLAS接口的話(huà))

數據結構:部分源碼用到了Set ,HashTable,HashMap

認真理解Token

Lucene中的Analysis包專(zhuān)門(mén)用于完成對于索引文件的分詞.Lucene中的Token是一個(gè)非常重要的概念.

看一下其源碼實(shí)現:

public final class Token {

  String termText;                        // the text of the term

  int startOffset;                           // start in source text

  int endOffset;                            // end in source text

  String type = "word";                        // lexical type

  private int positionIncrement = 1;

  public Token(String text, int start, int end)

  public Token(String text, int start, int end, String typ)

  public void setPositionIncrement(int positionIncrement)

  public int getPositionIncrement() { return positionIncrement; }

  public final String termText() { return termText; }

  public final int startOffset() { return startOffset; }

public void setStartOffset(int givenStartOffset)

  public final int endOffset() { return endOffset; }

public void setEndOffset(int givenEndOffset)

  public final String type() { return type; }

  public String toString()

 }

下面編一段代碼來(lái)看一下

TestToken.java

package org.apache.lucene.analysis.test;

import org.apache.lucene.analysis.*;

import org.apache.lucene.analysis.standard.StandardAnalyzer;

import java.io.*;

public class TestToken

{

  public static void main(String[] args)

  {

    String string = new String("我愛(ài)天大,但我更愛(ài)中國");

//Analyzer analyzer = new StandardAnalyzer();

Analyzer analyzer = new TjuChineseAnalyzer();

//Analyzer analyzer= new StopAnalyzer();

    TokenStream ts = analyzer.tokenStream("dummy",new StringReader(string));

    Token token;

    try

    {

      int n=0;

      while ( (token = ts.next()) != null)

      {

        System.out.println((n++)+"->"+token.toString());

      }

    }

    catch(IOException ioe)

    {

      ioe.printStackTrace();

    }

 

  }

}注意看其結果如下所示

0->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,0,1,<CJK>,1)

1->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(愛(ài),1,2,<CJK>,1)

2->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,2,3,<CJK>,1)

3->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,3,4,<CJK>,1)

4->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,5,6,<CJK>,1)

5->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,6,7,<CJK>,1)

6->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,7,8,<CJK>,1)

7->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(愛(ài),8,9,<CJK>,1)

8->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,9,10,<CJK>,1)

9->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,10,11,<CJK>,1)

注意:其中”,”StandardAnalyzer給過(guò)濾掉了,所以大家注意第4個(gè)Token直接startOffset5開(kāi)始.

如果改用StopAnalyzer()

0->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(我愛(ài)天大,0,4,word,1)

1->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(但我更愛(ài)中國,5,11,word,1)

改用TjuChineseAnalyzer(我寫(xiě)的,下文會(huì )講到如何去寫(xiě))

0->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(愛(ài),3,4,word,1)

1->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(天大,6,8,word,1)

2->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,19,20,word,1)

3->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(愛(ài),22,23,word,1)

4->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(中國,25,27,word,1)

講明白了Token,咱們來(lái)看以下其他的東西

一個(gè)TokenStream是用來(lái)走訪(fǎng)Tokeniterator(迭代器)

看一下其源代碼:

public abstract class TokenStream {

  public abstract Token next() throws IOException;

  public void close() throws IOException {}

}

一個(gè)Tokenizer,is-a TokenStream(派生自TokenStream),其輸入為Reader

看一下其源碼如下:

public abstract class Tokenizer extends TokenStream {

  protected Reader input;

  protected Tokenizer() {}

  protected Tokenizer(Reader input) {

    this.input = input;

  }

  public void close() throws IOException {

    input.close();

  }

}

一個(gè)TokenFilter is–a TokenStream(派生自TokenStream),其義如名就是用來(lái)完成對TokenStream的過(guò)濾操作,譬如

StopWords,將Token變?yōu)樾?xiě)等。

源碼如下:

public abstract class TokenFilter extends TokenStream {

  protected TokenStream input;

  protected TokenFilter() {}

  protected TokenFilter(TokenStream input) {

    this.input = input;

  }

  public void close() throws IOException {

    input.close();

  }

}

一個(gè)Analyzer就是一個(gè)TokenStream工廠(chǎng)

看一下其源碼就:

public abstract class Analyzer { 

  public TokenStream tokenStream(String fieldName, Reader reader)

  {

         return tokenStream(reader);

  }

  public TokenStream tokenStream(Reader reader)

  {

         return tokenStream(null, reader);

  }

}

好,現在咱們來(lái)看一下LuceneAnalysis包下面的各個(gè)類(lèi)文件都是用來(lái)干什么的。按照字典排序。

Analysis包中的源碼詳解

Analyzer.java  上文已經(jīng)講過(guò)。

CharTokenizer.java  此類(lèi)為簡(jiǎn)單一個(gè)抽象類(lèi),用來(lái)對基于字符的進(jìn)行簡(jiǎn)單分詞(tokenizer

LetterTokenizer.java兩個(gè)非字符之間的字符串定義為token(舉例來(lái)說(shuō)英文單詞由空白隔開(kāi),那個(gè)兩個(gè)空白之間的字符串即被定義為一個(gè)token。備注:對于絕大多數歐洲語(yǔ)言來(lái)說(shuō),這個(gè)類(lèi)工作效能很好。當時(shí)對于不用空白符分割的亞洲語(yǔ)言,效能極差(譬如中日韓)。)

LowerCaseFilter.java is-a TokenFilter用于將字母小寫(xiě)化

LowerCaseTokenizer is-a Tokenizer功能上等價(jià)于LetterTokenizerLowerCaseFilter

PerFieldAnalyzerWrapper是一個(gè)Analyzer,因為繼承自Analyzer當不同的域(Field)需要不同的語(yǔ)言分析器(Analyzer)時(shí),這個(gè)Analyzer就派上了用場(chǎng)。使用成員函數addAnalyzer可以增加一個(gè)非缺省的基于某個(gè)Fieldanalyzer。很少使用。

PorterStemFilter.java使用詞干抽取算法對每一個(gè)token流進(jìn)行詞干抽取。

PorterStemmer.java  有名的P-stemming算法

SimpleAnalyzer.java

StopAnalyzer.java   具有過(guò)濾停用詞的功能

StopFilter.java     StopFilter為一個(gè)Filter,主要用于從token流中去除StopWords

Token.java       上面已講.

TokenFilter.java   上面已經(jīng)講了

Tokenizer.java     上面已經(jīng)講了

TokenStream.java   上面已經(jīng)講了

WhitespaceAnalyzer.java

WhitespaceTokenizer.java 只是按照space區分Token.

 

由于Luceneanalyisis包下的Standard包下的StandardAnalyzer()功能很強大,而且支持CJK分詞,我們簡(jiǎn)要說(shuō)一下.

此包下的文件是有StandardTokenizer.jj經(jīng)過(guò)javac命令生成的.由于是機器自動(dòng)生成的代碼,可能可讀性很差,想了解的話(huà)好好看看那個(gè)StandardTokenizer.jj文件就會(huì )比較明了了.

Lucene常用的Analyzer功能概述.

WhitespaceAnalyzer:僅僅是去除空格,對字符沒(méi)有lowcase,不支持中文

SimpleAnalyzer:功能強于WhitespaceAnalyzer,將除去letter之外的符號全部過(guò)濾掉,并且將所有的字符lowcase,不支持中文

StopAnalyzer:StopAnalyzer的功能超越了SimpleAnalyzer,在SimpleAnalyzer的基礎上
   
增加了去除StopWords的功能,不支持中文

StandardAnalyzer:英文的處理能力同于StopAnalyzer.支持中文采用的方法為單字切分.

ChineseAnalyzer:來(lái)自于Lucenesand box.性能類(lèi)似于StandardAnalyzer,缺點(diǎn)是不支持中英文混和分詞.

CJKAnalyzer:chedong寫(xiě)的CJKAnalyzer的功能在英文處理上的功能和StandardAnalyzer相同
   
但是在漢語(yǔ)的分詞上,不能過(guò)濾掉標點(diǎn)符號,即使用二元切分

TjuChineseAnalyzer:我寫(xiě)的,功能最為強大.TjuChineseAnlyzer的功能相當強大,在中文分詞方面由于其調用的為ICTCLASjava接口.所以其在中文方面性能上同與ICTCLAS.其在英文分詞上采用了LuceneStopAnalyzer,可以去除 stopWords,而且可以不區分大小寫(xiě),過(guò)濾掉各類(lèi)標點(diǎn)符號.

各個(gè)Analyzer的功能已經(jīng)比較介紹完畢了,現在咱們應該學(xué)寫(xiě)Analyzer,如何diy自己的analyzer??

如何DIY一個(gè)Analyzer

咱們寫(xiě)一個(gè)Analyzer,要求有一下功能

(1)    可以處理中文和英文,對于中文實(shí)現的是單字切分,對于英文實(shí)現的是以空格切分.

(2)    對于英文部分要進(jìn)行小寫(xiě)化.

(3)    具有過(guò)濾功能,可以人工設定StopWords列表.如果不是人工設定,系統會(huì )給出默認的StopWords列表.

(4)    使用P-stemming算法對于英文部分進(jìn)行詞綴處理.

代碼如下:

public final class DiyAnalyzer

    extends Analyzer

{

  private Set stopWords;

  public static final String[] CHINESE_ENGLISH_STOP_WORDS =

      {

      "a", "an", "and", "are", "as", "at", "be", "but", "by",

      "for", "if", "in", "into", "is", "it",

      "no", "not", "of", "on", "or", "s", "such",

      "t", "that", "the", "their", "then", "there", "these",

      "they", "this", "to", "was", "will", "with",

      "", "我們"

  };

  public DiyAnalyzer()

  {

    this.stopWords=StopFilter.makeStopSet(CHINESE_ENGLISH_STOP_WORDS);

  }

 

  public DiyAnalyzer(String[] stopWordList)

  {

    this.stopWords=StopFilter.makeStopSet(stopWordList);

  }

 

  public TokenStream tokenStream(String fieldName, Reader reader)

  {

    TokenStream result = new StandardTokenizer(reader);

    result = new LowerCaseFilter(result);

 

    result = new StopFilter(result, stopWords);

    result = new PorterStemFilter(result);

    return result;

  }

 

  public static void main(String[] args)

  {

    //好像英文的結束符號標點(diǎn).,StandardAnalyzer不能識別

    String string = new String("我愛(ài)中國,我愛(ài)天津大學(xué)!I love China!Tianjin  is a City");

    Analyzer analyzer = new DiyAnalyzer();

    TokenStream ts = analyzer.tokenStream("dummy", new StringReader(string));

    Token token;

    try

    {

      while ( (token = ts.next()) != null)

      {

        System.out.println(token.toString());

      }

    }

    catch (IOException ioe)

    {

      ioe.printStackTrace();

    }

  }

}

可以看見(jiàn)其后的結果如下:

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(愛(ài),1,2,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,2,3,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,3,4,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(愛(ài),6,7,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,7,8,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,8,9,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(,9,10,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(學(xué),10,11,<CJK>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(i,12,13,<ALPHANUM>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(love,14,18,<ALPHANUM>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(china,19,24,<ALPHANUM>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(tianjin,25,32,<ALPHANUM>,1)

Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(citi,39,43,<ALPHANUM>,1)

 

到此為止這個(gè)簡(jiǎn)單的但是功能強大的分詞器就寫(xiě)完了,下面咱們可以嘗試寫(xiě)一個(gè)功能更強大的分詞器.

如何DIY一個(gè)功能更加強大Analyzer

譬如你有詞典,然后你根據正向最大匹配法或者逆向最大匹配法寫(xiě)了一個(gè)分詞方法,卻想在Lucene中應用,很簡(jiǎn)單

你只要把他們包裝成LuceneTokenStream就好了.下邊我以調用中科院寫(xiě)的ICTCLAS接口為例,進(jìn)行演示.你去中科院

網(wǎng)站可以拿到此接口的free版本,誰(shuí)叫你沒(méi)錢(qián)呢,有錢(qián),你就可以購買(mǎi)了.哈哈

,由于ICTCLAS進(jìn)行分詞之后,Java,中間會(huì )以?xún)蓚€(gè)空格隔開(kāi)!too easy,我們直接使用繼承Lucene

WhiteSpaceTokenizer就好了.

所以TjuChineseTokenizer 看起來(lái)像是這樣.

public class TjuChineseTokenizer extends WhitespaceTokenizer

{

  public TjuChineseTokenizer(Reader readerInput)

  {

    super(readerInput);

  }

}

TjuChineseAnalyzer看起來(lái)象是這樣

public final class TjuChineseAnalyzer

    extends Analyzer

{

  private Set stopWords;

 

  /** An array containing some common English words that are not usually useful

    for searching. */

  /*

     public static final String[] CHINESE_ENGLISH_STOP_WORDS =

      {

      "a", "an", "and", "are", "as", "at", "be", "but", "by",

      "for", "if", "in", "into", "is", "it",

      "no", "not", "of", "on", "or", "s", "such",

      "t", "that", "the", "their", "then", "there", "these",

      "they", "this", "to", "was", "will", "with",

      "", "我們"

     };

   */

  /** Builds an analyzer which removes words in ENGLISH_STOP_WORDS. */

  public TjuChineseAnalyzer()

  {

    stopWords = StopFilter.makeStopSet(StopWords.SMART_CHINESE_ENGLISH_STOP_WORDS);

  }

 

  /** Builds an analyzer which removes words in the provided array. */

  //提供獨自的stopwords

  public TjuChineseAnalyzer(String[] stopWords)

  {

    this.stopWords = StopFilter.makeStopSet(stopWords);

  }

 

  /** Filters LowerCaseTokenizer with StopFilter. */

  public TokenStream tokenStream(String fieldName, Reader reader)

  {

    try

    {

      ICTCLAS splitWord = new ICTCLAS();

      String inputString = FileIO.readerToString(reader);

      //分詞中間加入了空格

      String resultString = splitWord.paragraphProcess(inputString);

      System.out.println(resultString);

      TokenStream result = new TjuChineseTokenizer(new StringReader(resultString));

 

      result = new LowerCaseFilter(result);

      //使用stopWords進(jìn)行過(guò)濾

     result = new StopFilter(result, stopWords);

      //使用p-stemming算法進(jìn)行過(guò)濾

     result = new PorterStemFilter(result);

      return result;

 

    }

    catch (IOException e)

    {

      System.out.println("轉換出錯");

      return null;

    }

  }

 

  public static void main(String[] args)

  {

    String string = "我愛(ài)中國人民";

    Analyzer analyzer = new TjuChineseAnalyzer();

    TokenStream ts = analyzer.tokenStream("dummy", new StringReader(string));

    Token token;

    System.out.println("Tokens:");

    try

    {

      int n=0;

      while ( (token = ts.next()) != null)

      {

        System.out.println((n++)+"->"+token.toString());

      }

    }

    catch (IOException ioe)

    {

     ioe.printStackTrace();

    }

  }

}對于此程序的輸出接口可以看一下

0->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(愛(ài),3,4,word,1)

1->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(中國,6,8,word,1)

2->Token‘s (termText,startOffset,endOffset,type,positionIncrement) is:(人民,10,12,word,1)

 

OK,經(jīng)過(guò)這樣一番講解,你已經(jīng)對LuceneAnalysis包認識的比較好了,當然如果你想更加了解,還是認真讀讀源碼才好,

呵呵,源碼說(shuō)明一切!

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Lucene常用的Analyzer功能概述以及自定義Analyzer
Lucene關(guān)于幾種中文分詞的總結 (Lucene與搜索引擎技術(shù)) - [Matrix - 與 Java 共舞]
讓中科院中文分詞系統ICTCLAS為lucene所用的簡(jiǎn)單程序(C#版)
Analysis分析器(三)
lucene.net 2.0 中文分詞后語(yǔ)法高亮問(wèn)題 - 智慧掩蓋真相 - 博客園
lucene3.0創(chuàng )建索引及多目錄搜索詳解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久