打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
nutch-0.7的一些小知识

replace the default Tokenizer of carrot2 lingo filter with ICTCLAS

ICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System,中国科学院计算技术研究所汉语词法分析系统)替换nutch (0.7 release) 中carrot2 lingo filter 的Tokenizer。

nutch (0.7 release) 中的clustering plugin 采用的是Dawid Weiss 主持开发的carrot2,主要用到了其中的local controller 和 lingo filter 两个 compenent。lingo filter 缺省的Tokenizer (com.stachoodev.carrot.filter.lingo.tokenizer.Tokenizer)缺乏对中文的分词处理,这使得用这个filter 处理中文结果时效果往往不很让人满意!于是开始为nutch 选择合适的中文分词模块,经过一周左右的挑选、分析和比较,最终决定采用中国科学院计算技术研究所汉语词法分析系统——ICTCLAS。

接下来用了一周多的学习和练习:

  • 如何用java 的jni 接口调用native method
  • 如何用iconv 实现字符的编码转换
  • 如何为ICTCLAS 编写Makefile
  • 如何在resin/tomcat 下调用ICTCLAS方法
应该说这一周的学习历程是相当痛苦的,因为在这个过程中遇到的大部分细节问题都没办法直接从google 中找到答案,只能从类似问题的解决方法中寻找线索。例如,由于每个应用服务器对子进程的stack size 限制的不同,导致native method 经常会抛出有关 memset() 的异常。

经过一周多的时间终于用ICTCLAS 调换掉了lingo filter 缺省的 Tokenizer (com.stachoodev.carrot.filter.lingo.tokenizer.Tokenizer) :*)

nutch (0.7 release) 中carrot2 的版本略低于carrot2 官方网站对外公布的版本。

Wednesday, September 28, 2005

swith on the clustering plugin of nutch

the following works for the 0.7 release

edit $NUTCH_HOME/WEB-INF/classes/nutch-default.xml

  • register ‘clustering-carrot2‘ plugin
        <property>      <name>plugin.includes</name>      <value>clustering-carrot2|protocol-httpclient|urlfilter-regex|parse-(text|html|js)|index-basic|query-(basic|site|url)</value>       ...    </property>        
  • set attribute ‘extension.clustering.extension-name‘
        <property>      <name>extension.clustering.extension-name</name>      <value>Carrot2-Lingo</value>      ...    </property>        

Carrot2-Lingo: see $NUTCH_HOME/plugins/clustering-carrot2/plugin.xml for detail.

Now, it‘s ok! add an parameter ‘clustering=yes‘ onto your search url and try it.

Tuesday, September 27, 2005

hack NutchAnalysis.jj further so as to perform third-part segmentation

nutch (0.7 release) 缺省的token 规则对于很多语言(如CJK、 Myanmar等等)来说都不是很适合,于是很多人尝试在 NutchAnalysis.jj 中嵌入自己实现的Tokenizer,比较成功的例子有 Chinese in Nutch:My solution

下面是我想到的一个蹩脚方法,之所以说这个方法蹩脚是因为它在执行切分过程中产生了 sizeof(tokens[])次input_stream.backup(1) 操作和副作用:-(。但这个方法也还是有些可取之处的——把不同语言的切分工作交给不同的Tokenizer 去处理,这样可以产生比较好的细粒度切分效果。

org.apache.nutch.analysis.NutchAnalysis.jj

@@ -33,6 +33,7 @@import org.apache.nutch.searcher.Query.Clause;import org.apache.lucene.analysis.StopFilter;+import org.apache.lucene.analysis.cjk.CJKTokenizer;import java.io.*;import java.util.*;@@ -81,6 +82,14 @@PARSER_END(NutchAnalysis)TOKEN_MGR_DECLS : {+ /** use CJKTokenizer to process cjk character */+ private CJKTokenizer cjkTokenizer = null;++ /** a global cjk token */+ private org.apache.lucene.analysis.Token cjkToken = null;++ /** start offset of cjk sequence */+ private int cjkStartOffset = 0;/** Constructs a token manager for the provided Reader. */public NutchAnalysisTokenManager(Reader reader) {@@ -106,7 +115,46 @@}// chinese, japanese and korean characters-| <SIGRAM: <CJK> >+| <SIGRAM: (<CJK>)+ >+ {+   /**+   * use an instance of CJKTokenizer, cjkTokenizer, hold the maximum+   * matched cjk chars, and cjkToken for the current token;+   * reset matchedToken.image use cjkToken.termText();+   * reset matchedToken.beginColumn use cjkToken.startOffset();+   * reset matchedToken.endColumn use cjkToken.endOffset();+   * backup the last char when the next cjkToken is valid.+   */+   if(cjkTokenizer == null) {+     cjkTokenizer = new CJKTokenizer(new StringReader(image.toString()));+     cjkStartOffset = matchedToken.beginColumn;+     try {+       cjkToken = cjkTokenizer.next();+     } catch(IOException ioe) {+       cjkToken = null;+     }+   }++   if(cjkToken != null && !cjkToken.termText().equals("")) {+     //sometime the cjkTokenizer returns an empty string, is it a bug?+     matchedToken.image = cjkToken.termText();+     matchedToken.beginColumn = cjkStartOffset + cjkToken.startOffset();+     matchedToken.endColumn = cjkStartOffset + cjkToken.endOffset();+     try {+       cjkToken = cjkTokenizer.next();+     } catch(IOException ioe) {+       cjkToken = null;+     }+     if(cjkToken != null && !cjkToken.termText().equals("")) {+       input_stream.backup(1);+     }+   }++   if(cjkToken == null || cjkToken.termText().equals("")) {+     cjkTokenizer = null;+     cjkStartOffset = 0;+   }+ }

例子中所用的CJKTokenizer 取自Weblucene

关键词:nutch, segmentation, chinese, cjk

参考:

Thursday, September 22, 2005

hack NutchAnalysis.jj so as to perform bi-gram segmentation

Doug Cutting 的启发,修改NutchAnalysis.jj 如下,简单实现了二元切分功能:*)
109,110c109,112< | <SIGRAM: <CJK> ><---> | <SIGRAM: <CJK><CJK> >>   {>     input_stream.backup(1);>   }

简单测试一下效果:
$ echo $LANG
en_US.UTF-8
$ LANG=zh_CN
$ ./bin/nutch org.apache.nutch.analysis.NutchDocumentTokenizer
Text: 克己服人,礼智谦让
Tokens: 克己 己服 服人 礼智 智谦 谦让
Text: 中华人民共和国
Tokens: 中华 华人 人民 民共 共和 和国
Text: 中文&English&英文
Tokens: 中文 &english& 英文
Text: 写这些内容的时候,作者运行的是nutch 的0.7 release;如果你运行的是nutch 的其他版本,那么下面的内容可能并不适合你:
Tokens: 写这 这些 些内 内容 容的 的时 时候 作者 者运 运行 行的 的是 nutch 0 7 release 如果 果你 你运 运行 行的 的是 nutch 的其 其他 他版 版本 那么 么下 下面 面的 的内 内容 容可 可能 能并 并不 不适 适合 合你

关键词: nutch, segmentation, chinese, cjk, bi-gram

参考:

Wednesday, September 21, 2005

understand the tokenizer of nutch

逐步理解nutch 的 tokenizer(org.apache.nutch.analysis.NutchDocumentTokenizer)

注:写这些内容的时候,作者运行的是nutch 的0.7 release;如果你运行的是nutch 的其他版本,那么下面的内容可能并不适合你:*)

$ echo $LANG
en_US.UTF-8
$ LANG=zh_CN
$ ./bin/nutch org.apache.nutch.analysis.NutchDocumentTokenizer
Text: I.B.M.
Tokens: ibm
Text: I.B.M
Tokens: ib m
Text: AT&T
Tokens: at&t
Text: AT_T
Tokens: at_t
Text: 中华人民共和国
Tokens: 中 华 人 民 共 和 国
Text: 中文&English&英文
Tokens: 中 文 &english& 英 文

为什么会有这种切分效果呢?看看下面的 org.apache.nutch.analysis.NutchAnalysis.jj 文件片断也许就能明白了:

TOKEN : {// token regular expressions// basic word -- lowercase it<WORD: ((<LETTER>|<DIGIT>|<WORD_PUNCT>)+ | <IRREGULAR_WORD>)>  {     matchedToken.image = matchedToken.image.toLowerCase();  }// special handling for acronyms: U.S.A., I.B.M., etc: dots are removed| <ACRONYM: <LETTER> "." (<LETTER> ".")+ >  {// remove dots    for (int i = 0; i < image.length(); i++) {      if (image.charAt(i) == ‘.‘)        image.deleteCharAt(i--);    }    matchedToken.image = image.toString().toLowerCase();  }// chinese, japanese and korean characters| <SIGRAM: <CJK> >// irregular words| <#IRREGULAR_WORD:(<C_PLUS_PLUS>|<C_SHARP>)>......

当前的tokenizer 把单个的CJK 字符当成了一个完整的Token—— 并未对连续的CJK 字符做切分词处理,于是就出现了上面的结果。

Tuesday, September 20, 2005

crawl-urlfilter.txt vs. regex-urlfilter.txt in nutch

crawl-urlfilter.txt 之于 regex-urlfilter.txt

注:写这些内容的时候,作者运行的是nutch 的0.7 release;如果你运行的是nutch 的其他版本,那么你可能需要自己去分析二者的区别:*)

首先有一种说法是:crawl-urlfilter.txt 是供intranet 抓取用的,而regex-urlfilter.txt 是供internet 抓取用的——因为两者抓取的重点不同,从而导致过滤规则不同。如果你只是想知道两者的简单区别的话,那么看到这里也就可以了,但是如果你想知道更多细节那么下面的内容还是值得一看的:)

crawl-urlfilter.txt 和 regex-urlfilter.txt 都是用来保存过滤url 的正则表达式的。类 RegexURLFilter(org.apache.nutch.net.RegexURLFilter) 通过 NutchConf.get().get("urlfilter.regex.file") 来从中(当然如果你装载了其他配置文件的话,也可能有其他的候选者)进行选择。

regex-urlfilter.txt 是 urlfilter.regex.file 属性的缺省值(1),定义在 $NUTCH_JAVA_HOME/conf/nutch-default.xml(如果你设置了环境变量NUTCH_CONF_DIR 的话,那就是 $NUTCH_CONF_DIR/nutch-default.xml)中。该值可以被后续加载的配置文件所覆盖,例如如果你装载了类 CrawlTool(org.apache.nutch.tool.CrawlTool),那么缺省值就会被 crawl-tool.xml 中的urlfilter.regex.file 属性覆盖(2)。也就是说,如果你在操作过程中调用了类CrawlTool,那么类RegexURLFilter 将会采用crawl-tool.xml 中指定的文件,否则就用缺省的文件。

当然如果nutch-site.xml 中也定义了urlfilter.regex.file 属性的话,那么 NutchConf.get().get("urlfilter.regex.file") 返回的值就以nutch-site.xml 所指定的值为准。(关于nutch 的resource chain)

注:(1)NutchConf 初始化时会装载nutch-default.xml 和nutch-site.xml

public class NutchConf {......  public NutchConf() {    resourceNames.add("nutch-default.xml");    resourceNames.add("nutch-site.xml");  }......}
(2)装载类CrawlTool 时,crawl-tool.xml 会被插入到resource chain 中
public class CrawlTool {......  static {    NutchConf.get().addConfResource("crawl-tool.xml");  }......}
参见:

Monday, September 19, 2005

hack URLFilters so as to test RegexURLFilter

只是简单给URLFilters(org.apache.nutch.net.URLFilters)加了一个 main(String[]) 方法 :*)
public static void main(String args[]) throws IOException, MalformedPatternException, Exception {  BufferedReader in=new BufferedReader(new InputStreamReader(System.in));  String line;  while((line=in.readLine())!=null) {    String out=URLFilters.filter(line);    if(out!=null) {      System.out.print("+");      System.out.println(out);    } else {      System.out.print("-");      System.out.println(line);    }  }}
这样测试url filter rule 就方便多了:)

$ ./bin/nutch org.apache.nutch.net.URLFilters......http://www.lhelper.org/blog/using fitler 0:org.apache.nutch.net.RegexURLFilter+http://www.lhelper.org/blog/http://www.lhelper.org/blog/?q=lhelperusing fitler 0:org.apache.nutch.net.RegexURLFilter-http://www.lhelper.org/blog/?q=lhelper
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Apache Shiro实现单点登录SSO | 沐风
Shiro系列之Shiro+Mysql实现用户认证(Authentication)
Lucene 全文检索实践(四)
shiro实现APP、web统一登录认证和权限管理
shiro加盐走源码
一些门户或平台网站的数据获取与分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服