參考:http://grunt1223.iteye.com/blog/969197
?
Analyzer,或者說(shuō)文本分析的過(guò)程, 實(shí)質(zhì)上是將輸入文本轉(zhuǎn)化為文本特征向量的過(guò)程 。這里所說(shuō)的文本特征,可以是詞或者是短語(yǔ)。它主要包括以下四個(gè)步驟:?
1、分詞,將文本解析為單詞或短語(yǔ)
2、歸一化,將文本轉(zhuǎn)化為小寫
3、停用詞處理,去除一些常用的、無(wú)意義的詞
4、提取詞干,解決單復(fù)數(shù)、時(shí)態(tài)語(yǔ)態(tài)等問(wèn)題
?
?
?
Lucene Analyzer包含兩個(gè)核心組件,Tokenizer以及TokenFilter。兩者的區(qū)別在于,前者在字符級(jí)別處理流,而后者則在詞語(yǔ)級(jí)別處理流。Tokenizer是Analyzer的第一步,其構(gòu)造函數(shù)接收一個(gè)Reader作為參數(shù),而TokenFilter則是一個(gè)類似攔截器的東東,其參數(shù)可以使TokenStream、Tokenizer,甚至是另一個(gè)TokenFilter。整個(gè)Lucene Analyzer的過(guò)程如下圖所示:
?
?
?
上圖中的一些名詞的解釋如下表所示:?
| 類 | 說(shuō)明 |
| Token | 表示文中出現(xiàn)的一個(gè)詞,它包含了詞在文本中的位置信息 |
| Analyzer | 將文本轉(zhuǎn)化為TokenStream的工具 |
| TokenStream | 文本符號(hào)的流 |
| Tokenizer | 在字符級(jí)別處理輸入符號(hào)流 |
| TokenFilter | 在字符級(jí)別處理輸入符號(hào)流,其輸入可以是TokenStream、Tokenizer或者TokenFilter |
?
lucene分詞自定義
? ? ? ?TokenStream繼承關(guān)系圖如下:
?
StopAnalyzer,StandardAnalyze,WhitespaceAnalyzer,SimpleAnalyzer,KeyWordAnalyzer都繼承自父類Analyzer。
?
因此只要實(shí)現(xiàn)父類的虛方法tokenStream 就可以實(shí)現(xiàn)分析。
分詞的切分算法由繼承自父類Tokenizer的方法
public final boolean incrementToken() throws IOException 來(lái)實(shí)現(xiàn)。
因此自定義繼承類Tokenizer并實(shí)現(xiàn)其incrementToken算法就可以實(shí)現(xiàn)自定義的分詞。
?
?
//自定義禁用分詞器
public class UserDefinedAnalyzer extends Analyzer{
//定義禁用詞集合
private Set stops;
//無(wú)參構(gòu)造器使用默認(rèn)的禁用詞分詞器
public UserDefinedAnalyzer (){
stops = StopAnalyzer.ENGLISH_STOP_WORDS_SET;
}
/**
* 傳一個(gè)禁用詞數(shù)組
* @param sws
*/
public UserDefinedAnalyzer (String[] sws){
//使用stopFilter創(chuàng)建禁用詞集合
stops=StopFilter.makeStopSet(Version.LUCENE_35,sws,true);
//將默認(rèn)的禁用詞添加進(jìn)集合
stops.addAll(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
}
/**
* 自定義分詞器
*/
@Override
public TokenStream tokenStream(String str, Reader reader) {
//讀取原始Reader數(shù)據(jù)的一定是Tokenizer類,這里使用的是LetterTokenizer
return new StopFilter(Version.LUCENE_35,
new LowerCaseFilter(Version.LUCENE_35,
new LetterTokenizer(Version.LUCENE_35, reader)),stops);
}
public static void displayToken(String str,Analyzer a) {
try {
TokenStream stream = a.tokenStream("content",new StringReader(str));
//創(chuàng)建一個(gè)屬性,這個(gè)屬性會(huì)添加流中,隨著這個(gè)TokenStream增加
CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
while(stream.incrementToken()) {
System.out.print("["+cta+"]");
}
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
}
?
?
測(cè)試類
?
public class Test {
public static void main(String[] args) {
Analyzer a1=new UserDefinedAnalyzer(new String[]{"my","name"});
//Analyzer a1=new UserDefinedAnalyzer();
String str="my name is paul";
UserDefinedAnalyzer.displayToken(str, a1);
}
}
??
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

