Document

中文分词 《第七篇》

一、分词的方法

  分词的方法主要有以下几种:

  1、单字切分

  单字切分就是把一段文字按照每个字去建立索引。

  如果用来切分“我爱你伟大的中国”,就会切成“我”,“爱”,“你”,“伟”,“大”,“的”,“中”,“国”。这种分词效率低,但也能解决一些问题,聊胜于无。

  2、二分法

  二分法就是把一段文字的每两个相邻的字算作一个词。同样对于上面的句子就会切成“我爱”,“爱你”,“你伟”,“伟大”,“大的”,“的中”,“中国”7个词。

  3、词典法

  词典法就是建立一个词典文件,然后使用词典和文字段落进行匹配,从而得出分词结果。在这种分词方法中,词典和匹配算法是关键。

  做词典很容易,维护词典也不能,统计而已。

  匹配算法不好办,有最大匹配和最小匹配,正向匹配和逆向匹配。二二得四,就成了“最大正向匹配”,“最大逆向匹配”,“最小正向匹配”和“最小逆向匹配”。

  这四种分次发哪种最好没有定论,要根据具体文本段落而定。

  4、语义法

  这个方法在理论上是存在的,但从实际上讲也只是个名词。看到任何一段文字,让计算机将其正确理解出来,这个想法几乎不可能。即使是人也很难全部理解。

二、盘古分词

  在.Net环境中,分词比较常用的是盘古分词,项目地址是:http://pangusegment.codeplex.com/

  盘古分词词库下载地址是:http://pangusegment.codeplex.com/releases/view/47411

  下载解压后如下:

  

  1. Demo.exe是分词的示例程序,用于测试分词效果。
  2. DictManage.exe用于词库管理。

  分词测试效果就不说了,下面用一张图片来说明,如何对词库进行管理。

  

  1、盘古分词初始设置说明

  1、配置选项

  盘古分词在初始化的时候,需要首先配置一些参数,这些参数可以通过MatchOptions类由代码设定,然后通过一些支持该类对象的构造方法来动态设置。

  ICollection<WordInfo> words= segment.DoSegment(text); 
  ICollection<WordInfo> words= segment.DoSegment(text, options); 
  ICollection<WordInfo> words= segment.DoSegment(text, options, parameters);
  • text 为需要分词的文本
  • options 为自定义分词选项,默认为 pangu.xml 中指定的分词选项
  • parameters 为分词参数,默认为 pangu.xml 中指定的分词参数

  配置项列表如下:

MatchOptions属性 说明
ChineseNameIdentify 是否开启中文人名识别
FrequencyFirst  词频优先
MultiDimensionality 是否开启多元分词
EnglishMultiDimensionality 英文多元分词,这个开关,会将英文中的字母和数字分开
FilterStopWords 是否过滤停用词
IgnoreSpace 是否忽略空格、回车、Tab
ForceSingleWord 是否强制一元分词
TraditionalChineseEnabled 是否开启繁体中文分词
OutputSimplifiedTraditional 是否同时输出简体和繁体
UnknownWordIdentify 是否开启未登录词别
FilterEnglish 是否过滤英文,这个选项只有在过滤停用词选项生效时才有效
FilterNumeric 是否过滤数字,这个选项只有在过滤停用词选项生效时才有效
IgnoreCapital 是否忽略英文大小写
EnglishSegment 英文分词
SynonymOutput 同义词输出功能一般用于对搜索字符串的分词,不建议在索引时使用
WildcardOutput 同义词输出功能一般用于对搜索字符串的分词,不建议在索引时使用
WildcardSegment 对通配符匹配的结果分词
CustomRule 是否进行用户自定义规则匹配

  2、配置参数

  配置参数通过MatchParameter类设定,在xml里设定也可以:

MatchParameter属性 说明
Redundancy 多元分词冗余度
UnknowRank 未登录词权值
BestRank 最匹配词权值
SecRank 次匹配词权值
ThirdRank 再次匹配词权值
SingleRank 强行输出的单字的权值
NumericRank 数字的权值
EnglishRank 英文词汇权值
SymbolRank 符号的权值
SimplifiedTraditionalRank 强制同时输出简繁汉字时,非原来文本的汉字输出权值。原来文本是简体,这里就是输出的繁体字的权值,反之亦然
SynonymRank 同义词权值
WildcardRank 通配符匹配结果的权值
FilterEnglishLength 过滤英文选项生效时,过滤大于这个长度的英文
FilterNumericLength 过滤数字选项生效时,过滤大于这个长度的数字
CustomRuleAssemblyFileName 用户自定义规则的配件文件名
CustomRuleFullClassName 用户自定义规则的类的完整名,即带名字空间的名称

  默认的PanGu.xml示例如下:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<PanGuSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.codeplex.com/pangusegment">
  <DictionaryPath>..\Dictionaries</DictionaryPath>
  <MatchOptions>
    <ChineseNameIdentify>true</ChineseNameIdentify>
    <FrequencyFirst>false</FrequencyFirst>
    <MultiDimensionality>false</MultiDimensionality>
    <FilterStopWords>true</FilterStopWords>
    <IgnoreSpace>true</IgnoreSpace>
    <ForceSingleWord>false</ForceSingleWord>
    <TraditionalChineseEnabled>false</TraditionalChineseEnabled>
    <OutputSimplifiedTraditional>false</OutputSimplifiedTraditional>
  </MatchOptions>
  <Parameters>
    <UnknowRank>1</UnknowRank>
    <BestRank>5</BestRank>
    <SecRank>3</SecRank>
    <ThirdRank>2</ThirdRank>
    <SingleRank>1</SingleRank>
    <NumericRank>1</NumericRank>
    <EnglishRank>5</EnglishRank>
    <SymbolRank>1</SymbolRank>
    <SimplifiedTraditionalRank>1</SimplifiedTraditionalRank>
    <Redundancy>0</Redundancy>
  </Parameters>
</PanGuSettings>
复制代码

  配置项与上面两个类的属性一一对应。

  2、查看分词示例

  下面,先写个小Demo看看如何分词:

复制代码
    PanGu.Segment.Init(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/PanGu.xml");
    Segment segment = new Segment();
    ICollection<WordInfo> words = segment.DoSegment("张飞武功很好");
    foreach (WordInfo w in words)
    {
        Console.WriteLine(w.Word);
    }
复制代码

  分词效果如下:

  

  4、整合Lucene.net进行索引、搜索示例

  下面是一个简单的示例:

复制代码
    static void Main(string[] args)
    {
        PanGu.Segment.Init(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/PanGu.xml");
        //写入数据到索引
        Analyzer analyzer = new PanGuAnalyzer();
        Directory directory = new RAMDirectory();
        IndexWriter.MaxFieldLength maxFieldLength = new IndexWriter.MaxFieldLength(10000);

        using (IndexWriter writer = new IndexWriter(directory, analyzer, maxFieldLength))
        {
            Document document1 = new Document();
            document1.Add(new Field("Sentence", "张三是一个牛人", Field.Store.YES, Field.Index.ANALYZED));
            writer.AddDocument(document1);
        }
        //查找
        using (IndexSearcher searcher = new IndexSearcher(directory))
        {
            PanGuTokenizer ktTokenizer = new PanGuTokenizer();
            ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos("一个"); 
            StringBuilder result = new StringBuilder();
            foreach(WordInfo word in words) 
            { 
                if (word == null)
                { 
                    continue; 
                }
                result.AppendFormat("{0}^{1}.0", word.Word,(int)Math.Pow(3,word.Rank)); 
            } 

            QueryParser queryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "Sentence", new PanGuAnalyzer(true));
            Query query = queryParser.Parse(result.ToString());
            TopDocs docs = searcher.Search(query, null, 1000);
            Document doc = searcher.Doc(docs.ScoreDocs[0].Doc);
            Console.WriteLine(doc.Get("Sentence"));
        }
        Console.ReadKey();
    }
复制代码

  5、盘古分词高亮组件

  直接上示例:

复制代码
    //创建HTMLFormatter,参数为高亮单词的前后缀
    PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color=\"red\">", "</font>");
    //创建Highlighter ,输入HTMLFormatter 和盘古分词对象Semgent
    PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new Segment());
    //设置每个摘要段的字符数
    highlighter.FragmentSize = 50;
    //获取最匹配的摘要段
    string ContentLighter = highlighter.GetBestFragment("一个", "张三是一个牛人");
    Console.WriteLine(ContentLighter);
复制代码

  输出如下:

  

 

 

posted @ 2016-05-05 15:01  从未被超越  阅读(402)  评论(0编辑  收藏  举报