论坛首页 Java企业应用论坛

Lucene中文分词“庖丁解牛”

浏览 129966 次
该帖已经被评为精华帖
作者 正文
   发表时间:2007-01-24  
“庖丁解牛”隐喻:

庖丁是一个能够游刃有余分解牛骨与肉的人。给他一块牛肉(Beef),他能够知道怎样切(dissect)这个肉,把切好的肉放到篮子里(Collector)。

在外人看来,庖丁犹如一个刀神。

他是拥有一系列利刀(Knife)的神。他知道遇到什么肉(字符以及其上下文)就该使用什么样的刀:遇到字母肉,就用字母刀LetterKnife;遇到阿拉伯数字肉,就用NumberKnife刀;遇到中文肉,就用CJKKnife刀,...

这些刀都配备放在刀箱KnifeBox中,这个刀箱可配置不同的刀,应付时势的变化:将来可能会出现火星肉,到时可以放上火星刀...他打算以后采用Spring作为配置文件配置Knife到KnifeBox中.

有一天,庖丁被Lucene发现,引进了他,为其成立了一个新部门(配2成员XAnalyzer和XTokenizer),请他为Lucene服务,从此他如遇知人,拼命、有效地工作着...

  • 描述: 庖丁解牛 类草图
  • 大小: 34.8 KB
0 请登录后投票
   发表时间:2007-01-25  

Qieqie 写道:

Lucene中文分词 “庖丁解牛”

附件 为本人设计编写的组件,中文分词“庖丁解牛”,具有相当好的使用价值。。。

高效率:我的赛扬PC 1 秒解析 >>> 20000汉字的词语  (实际测试结果数据,可达1秒10万汉字)
高可维护性:使用“庖丁”隐喻,形象明晰
高灵活性,可扩展:OOD

对比:《终于突破中文分词的效率问题》http://www.lucene.org.cn/read.php?tid=54&fpage=2 他的效率为 6秒 解析2588汉字
 
示例程序为com.sohospace.lucene.analysis.xanalyzer.Main0

附带广告<偶寻觅工作中>:

我是
接近5年Java/J2EE开发经验。good at Java底层基础, 网站开发架构与技术, 设计模式, 面向对象。
崇尚有效的工作和管理。

我要
找一个Java/J2EE架构师、高级工程师职位(北京)。

我的联系方法:
email: leyan_cc.wang@yahoo.com.cn
skype:jimudugushi
tel: 133-xxxx-0083

 

 

我也正在就中文分词方向进行研究,也是使用首字hash+折半查找的方法构造词典的,是我尝试过分词效率最高的一种词典实现方式,但是最近我收集到一份论文《基于双数组Trie树的词典查询算法》,发现效率可能比基于双数组Trie树的词典查询算法还要高(利用有穷自动机的原理与Trie树的易扩展性),不知楼主有没有尝试过这种方法呢?
1 请登录后投票
   发表时间:2007-01-25  
/*
* 本代码所有权归作者所有 但在保持源代码不被破坏以及所有人署名的基础上 任何人可自由无限使用
*/
package com.sohospace.dictionary.support.merging;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.ListIterator;

/**
*
* @author zhiliang.wang@yahoo.com.cn
*
* @since 1.0
*
*/
public class Merger {

public static void merge(LinkedList<String> a, LinkedList<String> b) {
ListIterator<String> aIter = (ListIterator<String>) a.iterator();
ListIterator<String> bIter = (ListIterator<String>) b.iterator();
while (aIter.hasNext() && bIter.hasNext()) {     //判断有没有元素
String aWord = aIter.next();
System.out.println("aWord="+aWord);
boolean bGoOn = true;
while (bGoOn && bIter.hasNext()) {
String bWord = bIter.next();
System.out.println("bWord="+bWord);
int r = bWord.compareTo(aWord);
System.out.println("r="+r);
if (r == 0) {
continue;
}
if (r < 0) {
aIter.previous();
aIter.add(bWord);
aIter.next();
}
else {
bIter.previous();
bGoOn = false;
}
}
}
while (bIter.hasNext()) {
a.add(bIter.next());
}
}

public static void remove(LinkedList<String> a, LinkedList<String> b) {
ListIterator<String> aIter = (ListIterator<String>) a.iterator();
ListIterator<String> bIter = (ListIterator<String>) b.iterator();
while (aIter.hasNext() && bIter.hasNext()) {
String aWord = aIter.next();
boolean bGoOn = true;
while (bGoOn && bIter.hasNext()) {
String bWord = bIter.next();
int r = bWord.compareTo(aWord);
if (r == 0) {
aIter.remove();
if (aIter.hasNext()) {
aWord = aIter.next();
}
}
else if (r < 0){
continue;
}
else {
bIter.previous();
bGoOn = false;
}
}
}
}

public static void main(String[] args) {
LinkedList<String> a = new LinkedList<String>();
LinkedList<String> b = new LinkedList<String>();
a.add("1");
a.add("4");
a.add("a");
a.add("c");

b.add("2");
b.add("3");
b.add("b");
b.add("d");
b.add("太阳");

Merger.merge(a, b);
//Merger.remove(a, b);

System.out.println(Arrays.toString(a.toArray(new String[]{})));
   // System.out.println(Arrays.toString(b.toArray(new String[]{})));
}
}

运行后为aWord=1
bWord=2
r=1
aWord=4
bWord=2
r=-2
bWord=3
r=-1
bWord=b
r=46
aWord=a
bWord=b
r=1
aWord=c
bWord=b
r=-1
bWord=d
r=1
[1, 2, 3, 4, a, b, c, d, 太阳]
这个类在程序中起到什么作用?
0 请登录后投票
   发表时间:2007-01-25  


Merger.merge()方法在com.sohospace.paoding.cjk.FileWordsLoader.java的loadCJKVocabulary()方法中使用。

目的是:将读到的多个词语清单(LinkedList的形式)合并到第一个LinkedList中,并且保持升序。从而支持多个词典文件组成一个大词典(Vocabulary)。

Merger.merge()采用的是归并算法。

0 请登录后投票
   发表时间:2007-01-25  
lz,你的代码包是gbk的,我把源码部分转成utf8传上来,需要的来下附件
  • utf8src.rar (42.2 KB)
  • 描述: lz 源码的 utf8版本
  • 下载次数: 671
0 请登录后投票
   发表时间:2007-01-25  
查了一下,楼主似乎没有处理噪声词啊
0 请登录后投票
   发表时间:2007-01-25  
netfishx 写道
查了一下,楼主似乎没有处理噪声词啊


是啊,bug!

bugfix:

请在com.sohospace.paoding.cjk.FileWordsLoader.java的loadCJKVocabulary方法返回前加上如下以行代码:
Merger.remove(base, ejk.get("x干扰词"));


经过调试解决了该bug!


alin_ass 写道
lz,你的代码包是gbk的,我把源码部分转成utf8传上来,需要的来下附件


>>>>>感谢中,我已经把说明加到主贴上了。


不知哪里有较好的网上 版本控制器 推荐下? 这样该代码就好办了。
0 请登录后投票
   发表时间:2007-01-25  
subversion不好吗?
0 请登录后投票
   发表时间:2007-01-25  

感觉在RedSage.com上申请个版本控制服务是个不错注意
0 请登录后投票
   发表时间:2007-01-25  
为了在我的eclipse里看你的代码, 我中午牺牲休息时间写了一个小小的批量转码的软件,类似iconv
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics