Paoding中文分词参考手册

 

Paoding中文分词参考手册

 

本文档对应paoding-analysis 2.0.4–alpha2,目前还在草稿状态。

由于没有docbook编辑文档的经验和环境,暂时以word编辑文档。

 

目录

 

一般使用

 

使用评估

参考资料

下载

开始使用

分词策略

 

高级专题

 

配置参考

PaodingMaker的设计

庖丁架构

词典的抽象与设计

词典定制

词典动态加载

自定制分词策略

 

集成指南

 

Spring XML 配置

 

 

 


 

一般使用

使用评估

暂略

参考资料

暂略

下载

zip download:http://code.google.com/p/paoding/downloads/list

svn: http://paoding.googlecode.com/svn/trunk/paoding-analysis/

 

效果体验

使用者第一步最有可能的是想要体验了解庖丁的分词效果。考虑到这样的需求,庖丁提供了一个shell文件,使用者不必写任何代码就可以获得这样的信息。进入Paoding-Analysis分发包,在命令行模式下执行analyzer.bat(windows)analyzer.sh(linux)即可。下以windows为例:

u       显示帮助

E:\Paoding-Analysis>analyzer.bat ?

 

u       分词对话

当没有在命令行参数种输入分词内容或待分词的文章时,analyzer.bat进入分词对话模式,使用者可以多次输入或粘贴不同的文字内容,查看分词效果,如:

 

E:\Paoding-Analysis>analyzer.bat

paoding> |

此时使用者可以在光标所在所在位置(|)输入或粘贴待分词的内容(以分号结束),按下Enter键换行,analyzer.bat便可以输出分词结果。比如:

paoding> 中文分词;

1:      中文/分词/

        分词器net.paoding.analysis.analyzer.PaodingAnalyzer

        内容长度 4字符, 分 2个词

        分词耗时 0ms

--------------------------------------------------

分词完毕后,又会进入以上对话模式。

键入:e:q退出会话 (包括:符号

键入:?显示帮助(包括:符号

 

u       对文件进行分词

analyzer.bat允许对指定的文件进行分词体验。文件以路径名给出可以使绝对地址、相对当前目录的地址,或以classpath:为前缀的类路径地址。示例如下:

paoding> :-f E:/content.txt

paoding> :-f E:/content.txt -c gbk

paoding> :-f E:/content.txt -c gbk -m max

开始使用

庖丁中文分词需要一套词典,这些词典需要统一存储在某个目录下,这个目录称为词典安装目录。词典安装目录可以是文件系统的任何目录,它不依赖于应用程序的运行目录。将词典拷贝到词典安装目录的过程称为安装词典。增加、删除、修改词典目录下的词典的过程称为自定制词典。

在linux下,我们可以考虑将词典安装在一个专门存储数据的分区下某目录,以笔者为例,笔者将/data作为系统的一个独立分区,笔者便是将词典保存在/data/paoding/dic下。

在windows下,我们可以考虑将词典安装在非系统盘的另外分区下的某个目录,以笔者为例,笔者可能将词典保存在E:/data/paoding/dic下。

使用者安装辞典后,应该设置系统环境变量PAODING_DIC_HOME指向词典安装目录。

在linux下,通过修改/etc/profile,在文件末尾加上以下2行,然后保存该文件并退出即可。

PAODING_DIC_HOME=/data/paoding/dic

export PAODING_DIC_HOME

在windows下,通过“我的电脑”属性之“高级”选项卡,然后在进入“环境变量”编辑区,新建环境变量,设置“变量名”为PAODING_DIC_HOME;“变量值”为E:/data/paoding/dic

3步,把paoding-analysis.jar拷贝到应用运行时的类路径(classpath)下。使用集成开发环境(IDE)开发应用的使用者,需要把paoding-analysis.jar拷贝到工程中,然后使用IDE向导引入该Jar包,以便开发应用时IDE能够认识它。

至此,便可以在应用代码中使用庖丁提供的中文分析器了。

提醒:以下示例代码中的IDNEX_PATH表示索引库地址,读者运行以下代码前,应该赋与一个不重要的地址,比如/data/paoding/test_index E:/paoding_test_index,以免一时疏忽将重要数据丢失。

示例代码:建立索引库,并依此查询

String IDNEX_PATH = "E:/paoding_test_index";

//获取Paoding中文分词器

Analyzer analyzer = new PaodingAnalyzer();

//建立索引

IndexWriter writer = new IndexWriter(IDNEX_PATH, analyzer, true);

Document doc = new Document();

Field field = new Field("content""你好,世界!", Field.Store.YES,

    Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);

doc.add(field);

writer.addDocument(doc);

writer.close();

System.out.println("Indexed success!");

 

//检索

IndexReader reader = IndexReader.open(IDNEX_PATH);

QueryParser parser = new QueryParser("content", analyzer);

Query query = parser.parse("你好");

Searcher searcher = new IndexSearcher(reader);

Hits hits = searcher.search(query);

if (hits.length() == 0) {

    System.out.println("hits.length=0");

}

Document doc2 = hits.doc(0);

//高亮处理

String text = doc2.get("content");

TermPositionVector tpv = (TermPositionVector) reader.getTermFreqVector(

                0, "content");

TokenStream ts = TokenSources.getTokenStream(tpv);

Formatter formatter = new Formatter() {

    public String highlightTerm(String srcText, TokenGroup g) {

        if (g.getTotalScore() <= 0) {

            return srcText;

        }

        return "<b>" + srcText + "</b>";

    }

};

Highlighter highlighter = new Highlighter(formatter, new QueryScorer(

        query));

String result = highlighter.getBestFragments(ts, text, 5, "…");

System.out.println("result:\n\t" + result);

reader.close();

分词策略

暂时以测试用例体现如下:

 

package net.paoding.analysis;

 

import java.io.StringReader;

 

import junit.framework.TestCase;

import net.paoding.analysis.analyzer.PaodingAnalyzer;

 

import org.apache.lucene.analysis.Token;

import org.apache.lucene.analysis.TokenStream;

 

public class AnalyzerTest extends TestCase {

 

    protected PaodingAnalyzer analyzer = new PaodingAnalyzer();

 

    protected StringBuilder sb = new StringBuilder();

 

    protected String dissect(String input) {

       try {

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

           Token token;

           sb.setLength(0);

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

              sb.append(token.termText()).append('/');

           }

           if (sb.length() > 0) {

              sb.setLength(sb.length() - 1);

           }

           return sb.toString();

       } catch (Exception e) {

           e.printStackTrace();

           return "error";

       }

    }

 

    /**

     *

     */

    public void test000() {

       String result = dissect("a");

       assertEquals("", result);

    }

 

    /**

     *

     */

    public void test001() {

       String result = dissect("空格 a 空格");

       assertEquals("空格/空格", result);

    }

 

    /**

     *

     */

    public void test002() {

       String result = dissect("A");

       assertEquals("a", result);

    }

   

    /**

     *

     */

    public void test003() {

       String result = dissect("u");

       assertEquals("u", result);

    }

 

    public void test004() {

       String result = dissect("刚买的u盘的容量");

       assertEquals("/买的/u/容量", result);

    }

   

    public void test005() {

       String result = dissect("K歌之王很好听");

       assertEquals("k歌之王/很好/好听", result);

    }

    // --------------------------------------------------------------

    // 仅包含词语的句子分词策略

    // --------------------------------------------------------------

 

    /**

     * 句子全由词典词语组成,但词语之间没有包含、交叉关系

     */

    public void test100() {

       String result = dissect("台北中文国际");

       assertEquals("台北/中文/国际", result);

    }

 

    /**

     * 句子全由词典词语组成,但词语之间有包含关系

     */

    public void test101() {

       String result = dissect("北京首都机场");

       assertEquals("北京/首都/机场", result);

    }

 

    /**

     * 句子全由词典词语组成,但词语之间有交叉关系

     */

    public void test102() {

       String result = dissect("东西已经拍卖了");

       assertEquals("东西/已经/拍卖/卖了", result);

    }

 

    /**

     * 句子全由词典词语组成,但词语之间有包含、交叉等复杂关系

     */

    public void test103() {

       String result = dissect("羽毛球拍");

       assertEquals("羽毛/羽毛球/球拍", result);

    }

 

    // --------------------------------------------------------------

    // noise词汇和单字的分词策略

    // --------------------------------------------------------------

 

    /**

     * 词语之间有一个noise()

     */

    public void test200() {

       String result = dissect("足球的魅力");

       assertEquals("足球/魅力", result);

    }

 

    /**

     * 词语之间有一个noise词语(因之)

     */

    public void test201() {

       String result = dissect("主人因之生气");

       assertEquals("主人/生气", result);

    }

 

    /**

     * 词语前后分别有单字和双字的noise词语(,有关)

     */

    public void test202() {

       String result = dissect("与谋杀有关");

       assertEquals("谋杀", result);

    }

 

    /**

     * 前有noise词语(哪怕),后面跟随了连续的noise单字(,)

     */

    public void test203() {

       String result = dissect("哪怕朋友背叛了你");

       assertEquals("朋友/背叛", result);

    }

 

    /**

     * 前后连续的noise词汇(虽然,某些),词语中有noise单字()

     */

    public void test204() {

       String result = dissect("虽然某些动物很凶恶");

       assertEquals("动物/凶恶", result);

    }

 

    // --------------------------------------------------------------

    // 词典没有收录的字符串的分词策略

    // --------------------------------------------------------------

 

   

    /**

     * 1个字的非词汇串(,西,,)

     */

    public void test300() {

       String result = dissect("&&西&&&&");

       assertEquals("/西//", result);

    }

 

   

    /**

     * 仅两个字的非词汇串(古哥,谷歌,收狗,搜狗)

     */

    public void test302() {

       String result = dissect("古哥&&谷歌&&收狗&&搜狗");

       assertEquals("古哥/谷歌/收狗/搜狗", result);

    }

   

    /**

     * 多个字的非词汇串

     */

    public void test303() {

       String result = dissect("这是鸟语:玉鱼遇欲雨");

       assertEquals("这是/鸟语/玉鱼/鱼遇/遇欲/欲雨", result);

    }

   

    /**

     * 两个词语之间有一个非词汇的字()

     */

    public void test304() {

       String result = dissect("朋友真背叛了你了!");

       assertEquals("朋友//背叛", result);

    }

   

    /**

     * 两个词语之间有一个非词汇的字符串(盒蟹)

     */

    public void test305() {

       String result = dissect("建设盒蟹社会");

       assertEquals("建设/盒蟹/社会", result);

    }

   

    /**

     * 两个词语之间有多个非词汇的字符串(盒少蟹)

     */

    public void test306() {

       String result = dissect("建设盒少蟹社会");

       assertEquals("建设/盒少/少蟹/社会", result);

    }

 

    // --------------------------------------------------------------

    // 不包含小数点的汉字数字

    // --------------------------------------------------------------

 

 

    /**

     * 单个汉字数字

     */

    public void test400() {

       String result = dissect("");

       assertEquals("2", result);

    }

 

    /**

     * 两个汉字数字

     */

    public void test61() {

       String result = dissect("五六");

       assertEquals("56", result);

    }

 

    /**

     * 多个汉字数字

     */

    public void test62() {

       String result = dissect("三四五六");

       assertEquals("3456", result);

    }

 

    /**

     * 十三

     */

    public void test63() {

       String result = dissect("十三");

       assertEquals("13", result);

    }

 

    /**

     * 二千

     */

    public void test65() {

       String result = dissect("二千");

       assertEquals("2000", result);

    }

 

    /**

     * 两千

     */

    public void test651() {

       String result = dissect("两千");

       assertEquals("2000", result);

    }

    /**

     * 两千

     */

    public void test6511() {

       String result = dissect("两千个");

       assertEquals("2000/", result);

    }

 

    /**

     * 2

     */

    public void test652() {

       String result = dissect("2");

       assertEquals("2000", result);

    }

   

    /**

     *

     */

    public void test653() {

       String result = dissect("3千万");

       assertEquals("30000000", result);

    }

   

    /**

     *

     */

    public void test654() {

       String result = dissect("3千万个案例");

       assertEquals("30000000//案例", result);

    }

 

 

    /**

     *

     */

    public void test64() {

       String result = dissect("千万");

       assertEquals("千万", result);

    }

 

    public void test66() {

       String result = dissect("两两");

       assertEquals("两两", result);

    }

 

    public void test67() {

       String result = dissect("二二");

       assertEquals("22", result);

    }

 

    public void test68() {

       String result = dissect("2.2");

       assertEquals("2.2/", result);

    }

 

    public void test69() {

       String result = dissect("二两");

       assertEquals("2/", result);

    }

 

 

    public void test690() {

       String result = dissect("2");

       assertEquals("2/", result);

    }

 

    public void test691() {

       String result = dissect("2千克");

       assertEquals("2000/", result);

    }

 

    public void test692() {

       String result = dissect("2公斤");

       assertEquals("2/公斤", result);

    }

 

    public void test693() {

       String result = dissect("2世纪");

       assertEquals("2/世纪", result);

    }

 

    public void test7() {

       String result = dissect("哪怕二");

       assertEquals("2", result);

    }

 

}


 

高级专题

(正在完成……)

配置文件

 

PaodingMaker的设计

 

庖丁架构

 

词典的抽象与设计

 

词典定制

 

词典动态加载

 

自定制分词策略

 


 

集成指南

(正在完成……)

Spring XML 配置

 

Plugin

 


 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值