天天看點

開源搜尋架構Lucene學習之分詞器(2)——TokenFilter類及其子類 - 左眼微笑右眼淚

開源搜尋架構Lucene學習之分詞器(2)——TokenFilter類及其子類

2011-12-30 13:17 

左眼微笑右眼淚 

閱讀(846) 

評論(3) 

編輯 

收藏 

舉報

      前面我們分析了一下Tokenizer類及它的子類,Tokenizer類繼承于TokenStream類,它的作用主要是把一個字元串分隔成一個個的詞,不同的子類實作不同的切分方式。有按空格的,有按非英文字元的。把切分出來的詞Token組合成TokenStream。今天我們要讨論的是TokenFilter及其子類。TokenFilter類也是繼承于TokenSteam類,它的作用是對分出來的詞進行一些處理,比如去掉停詞,轉換大小寫。我們來看TokenFilter類的代碼:

abstract public class TokenFilter : TokenStream      
{      
///<summary>      
///需要傳過來的處理的TokenStream      
///The source of tokens for this filter.       
///</summary>      
protected TokenStream input;      
///<summary> Close the input TokenStream. </summary>      
public override void Close()      
{      
input.Close();      
}      
}      

     也是一個抽象類,它裡面定義了一個受保護的成員TokenStream類型的input,我們知道在Tokenizer類裡面定義了一個受保護的TextReader類型的input,Tokenizer類裡面接收的是一個文本流,而TokenFilter類則需要接收一個TokenStream,也就是一個語彙單元流。具體的流程就是把一個字元串傳遞給Tokenizer,Tokenizer把這個字元串分拆成一個個的Token,然後把這些Token組合成一個TokenStream,也就是一個語彙單元流,然後把這個語彙單元流傳給TokenFilter,TokenFilter會對TokenStream裡面的每一個Token進行一下處理。根據處理方式的不同,由不同的子類來實作這些處理方式。先來看看第一個子類LowerCaseFilter,也就是把每個Token都轉換成小寫的。

public class LowerCaseFilter : TokenFilter      
{      
/// <summary>      
/// Initializes a new instance of the LowerCaseFilter class.      
/// </summary>      
/// <param name="ts">Token stream to read from.</param>      
public LowerCaseFilter(TokenStream ts)      
{      
input = ts;      
}      
/// <summary>      
/// Returns the next token from the stream.      
/// </summary>      
/// <returns>The next token or null if EOS.</returns>      
public override Token Next()      
{      
Token t = input.Next();      
if (t == null)      
return null;      
t.TermText = t.TermText.ToLower();      
return t;      
}      
}      

     主要就是Next方法,裡面就是把每一個Token轉換成小寫。方法比較簡單,就不用解釋了。再看第二個子類,去掉停詞的類StopFilter,我們就隻看Next方法,代碼如下:

public override Token Next()      
{      
// return the first non-stop word found      
for (Token token = input.Next(); token != null; token = input.Next())      
if (table[token.TermText] == null)      
return token;      
// reached EOS -- return null      
return null;      
}      

     這個方法裡面有一個table變量,它是一個HashTable的對象,裡面裝的就是停詞,也就是那些沒有實際意義,需要剔除的詞,這個停詞集合,在這個類裡面有一個初始化,也就是英文中常用的停詞集合,你也可以自己傳入一個停詞的集合。Next方法主要就是周遊每一個Token,看其是否是停詞,如果是的,就去掉。

     接下來要看的一個子類就比較有意思,它的作用就是把詞元進行一些Stem處理,Stem就是把每一個詞元還原成原型,比如cars轉換成car。這裡會用到一個著名的的stemming算法,全稱是The Porter Stemming Algorithm,其首頁為http://tartarus.org/~martin/PorterStemmer/,也可檢視其論文http://tartarus.org/~martin/PorterStemmer/def.txt。通過以下網頁可以進行簡單的測試:Porter\'s Stemming Algorithm Online[http://facweb.cs.depaul.edu/mobasher/classes/csc575/porter.html]。比如cars –> car,driving –> drive,tokenization –> token。下面我們來看看這個類的Next方法:

public override Token Next()      
{      
Token token = input.Next();      
if (token == null)      
return null;      
else      
{      
String s = stemmer.stem(token.TermText);      
if (s != token.TermText) // Yes, I mean object reference comparison here      
token.TermText = s;      
return token;      
}      
}      

    當然首先是定義了一個封裝了stemming算法的類PorterStemmer的對象stemmer,然後調用這個裡面的stem方法,把每一個Token都處理一下,傳回即可。有時間的話把stemming算法單獨拿出來解讀一下。

    分詞的一些基本類都已經介紹完成了,前面所介紹的都是一些簡單的分詞,Lucene裡面内置了四個分詞器,分别是WhitespaceAnalyzer,SimpleAnalyzer,StopAnalyzer還有一個StandardAnalyzer分詞器,前三個分詞器用前面介紹的一些類就可以完成其功能,StandardAnalyzer分詞器比較複雜,下次将來解讀,構成StandardAnalyzer分詞器的StandardFilter類和StandardTokenizer類。

  • 分類 Lucene
開源搜尋架構Lucene學習之分詞器(2)——TokenFilter類及其子類 - 左眼微笑右眼淚