简介

平时经常用Python写些小程序。在做文本分析相关的事情时免不了进行中文分词,于是就遇到了用Python实现的结巴中文分词。jieba使用起来非常简单,同时分词的结果也令人印象深刻,有兴趣的可以到它的在线演示站点体验下(注意第三行文字)。

.NET平台上常见的分词组件是盘古分词,但是已经好久没有更新了。最明显的是内置词典,jieba的词典有50万个词条,而盘古的词典是17万,这样会造成明显不同的分词效果。另外,对于未登录词,jieba“采用了基于汉字成词能力的HMM模型,使用了Viterbi算法”,效果看起来也不错。

基于以上两点,加上对于中文分词的兴趣,就尝试将jieba移植到.NET平台上,已经把代码放在了github上:jieba.NET。在试用jieba.NET之前,先简单介绍下jieba的实现思路。

jieba实现浅析

jieba本身提供的文档较少,但我们可以在《对Python中文分词模块结巴分词算法过程的理解和分析》、《jieba 分词源代码研读(1)》这一系列文章中一窥jieba实现的整体思路。简言之,它的核心模块和分词过程大致是:

  • 前缀词典(Trie):用于存储主词典,也可以动态增删词条,这个词典可以理解为jieba所“知道”的词,或者说已登录词;
  • 有向无环图(DAG):通过前缀词典,可以找出句子所有可能的成词结果;
  • 最大概率路径:通过DAG,可以了解所有的成词结果,每个结果对应于一条路径及其概率。由于不同词条的出现概率不同,不同的结果就对应了不同的概率,我们找出概率最大的那条路径。到这里,我们对于已登录词做出了最合理的划分;
  • HMM模型Viterbi算法:最大概率路径之后,我们可能会遇到一些未登录词(不包含在前缀词典中的词),这时通过HMM和Viterbi尝试进一步的划分,得到最终结果

这个过程与人的分词过程很类似。比如看到这句话:“语言学家参加学术会议”,我们会把它划分为:“语言学家 参加 学术会议”。尽管这个过程是瞬间完成的,但是它确实包含了上述过程的前三步:分词之前,大脑中已有一个“前缀词典”,它包括语言、语言学、语言学家等等各个词条;大脑知道这句话确实存在多种分词的可能;但它最后还是选出了那个最可能的结果,舍弃了诸如“语言学 家 参加 学术 会议”这样的结果。

前面这句话仅包含了已登录词,再来看另一句话:“他来到了网易杭研大厦”。一般人可以迅速做出划分:“他 来到 了 网易 (杭研)? 大厦”,除了“杭研”这两个字,其它的都属于已登录词,容易划分出来。对于“杭研”,我们要想一想它们是两个单字呢,还是一个新词。最后,可能会伴随着这样一个过程:我知道网易是有研发中心或研究院之类的在杭州的,那么“杭研”可能是与此相关的一个缩写,嗯,又知道了一个新词。尽管这个过程与HMM不同,但我们至少了解到,jieba确实是通过某种方式去尝试寻找未登录词。

不过可以想象的是,基于状态转移概率的HMM模型(建议参考文章《中文分词之HMM模型详解》)能够发现的词应该也是比较自然或正常的词,对于新的人名、机构名或网络词(喜大普奔之类的),效果不会很好。

jieba.NET用法

jieba.NET当前版本是0.37.1,与jieba保持一致,可以通过NuGet安装:

PM> Install-Package jieba.NET

安装之后,把Resources目录copy到程序集所在目录即可。下面分别是分词、词性标注和关键词提取的示例。

分词

var segmenter = new JiebaSegmenter();
var segments = segmenter.Cut("我来到北京清华大学", cutAll: true);
Console.WriteLine("【全模式】:{0}", string.Join("/ ", segments)); segments = segmenter.Cut("我来到北京清华大学"); // 默认为精确模式
Console.WriteLine("【精确模式】:{0}", string.Join("/ ", segments)); segments = segmenter.Cut("他来到了网易杭研大厦"); // 默认为精确模式,同时也使用HMM模型
Console.WriteLine("【新词识别】:{0}", string.Join("/ ", segments)); segments = segmenter.CutForSearch("小明硕士毕业于中国科学院计算所,后在日本京都大学深造"); // 搜索引擎模式
Console.WriteLine("【搜索引擎模式】:{0}", string.Join("/ ", segments)); segments = segmenter.Cut("结过婚的和尚未结过婚的");
Console.WriteLine("【歧义消除】:{0}", string.Join("/ ", segments));

运行结果为:

【全模式】:我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
【精确模式】:我/ 来到/ 北京/ 清华大学
【新词识别】:他/ 来到/ 了/ 网易/ 杭研/ 大厦
【搜索引擎模式】:小明/ 硕士/ 毕业/ 于/ 中国/ 科学/ 学院/ 科学院/ 中国科学院/ 计算/ 计算所/ ,/ 后/ 在/ 日本/ 京都/ 大学/ 日本京都大学/ 深造
【歧义消除】:结过婚/ 的/ 和/ 尚未/ 结过婚/ 的

JiebaSegmenter.Cut方法可通过cutAll来支持两种模式,精确模式和全模式。精确模式是最基础和自然的模式,试图将句子最精确地切开,适合文本分析;而全模式,把句子中所有的可以成词的词语都扫描出来, 速度更快,但是不能解决歧义,因为它不会扫描最大概率路径,也不会通过HMM去发现未登录词。

CutForSearch采用的是搜索引擎模式,在精确模式的基础上对长词再次切分,提高召回率,适合用于搜索引擎分词

词性标注

词性标注采用和ictclas兼容的标记法,关于ictclas和jieba中使用的标记法列表,请参考:词性标记

var posSeg = new PosSegmenter();
var s = "一团硕大无朋的高能离子云,在遥远而神秘的太空中迅疾地飘移"; var tokens = posSeg.Cut(s);
Console.WriteLine(string.Join(" ", tokens.Select(token => string.Format("{0}/{1}", token.Word, token.Flag))));

运行结果

一团/m 硕大无朋/i 的/uj 高能/n 离子/n 云/ns ,/x 在/p 遥远/a 而/c 神秘/a 的/uj 太空/n 中/f 迅疾/z 地/uv 飘移/v

关键词提取

看下面来自维基百科的关于算法的文字:

在数学和计算机科学/算学之中,算法/算则法(Algorithm)为一个计算的具体步骤,常用于计算、数据处理和自动推理。精确而言,算法是一个表示为有限长列表的有效方法。算法应包含清晰定义的指令用于计算函数。

算法中的指令描述的是一个计算,当其运行时能从一个初始状态和初始输入(可能为空)开始,经过一系列有限而清晰定义的状态最终产生输出并停止于一个终态。一个状态到另一个状态的转移不一定是确定的。随机化算法在内的一些算法,包含了一些随机输入。

形式化算法的概念部分源自尝试解决希尔伯特提出的判定问题,并在其后尝试定义有效计算性或者有效方法中成形。这些尝试包括库尔特·哥德尔、雅克·埃尔布朗和斯蒂芬·科尔·克莱尼分别于1930年、1934年和1935年提出的递归函数,阿隆佐·邱奇于1936年提出的λ演算,1936年Emil Leon Post的Formulation 1和艾伦·图灵1937年提出的图灵机。即使在当前,依然常有直觉想法难以定义为形式化算法的情况。

现在来尝试提取其中的关键词。jieba.NET提供了TF-IDF和TextRank两种算法来提取关键词,TF-IDF对应的类是JiebaNet.Analyser.TfidfExtractor,TextRank的是JiebaNet.Analyser.TextRankExtractor

var extractor = new TfidfExtractor();
// 提取前十个仅包含名词和动词的关键词
var keywords = extractor.ExtractTags(text, , Constants.NounAndVerbPos);
foreach (var keyword in keywords)
{
Console.WriteLine(keyword);
}

运行结果是

算法
定义
计算
尝试
形式化
提出
状态
指令
输入
包含

相应的ExtractTagsWithWeight方法的返回结果中除了包含关键词,还包含了相应的权重值。TextRankExtractor的接口与TfidfExtractor完全一致,不再赘述。

小结

分词、词性标注和关键词提取是jieba的三个主要功能模块,jieba.NET目前尽量在功能和接口上与jieba保持一致,但以后可能会在jieba基础上提供其它扩展功能。jieba.NET的开发刚刚开始,还有很多细节需要完善。非常欢迎大家的试用和反馈,也希望能和大家一起讨论,共同实现更好的中文分词库。

参考:

结巴中文分词

对Python中文分词模块结巴分词算法过程的理解和分析

中文分词之HMM模型详解

结巴分词Java版

jieba中文分词的.NET版本:jieba.NET的更多相关文章

  1. .net 的一个分词系统(jieba中文分词的.NET版本:jieba.NET)

    简介 平时经常用Python写些小程序.在做文本分析相关的事情时免不了进行中文分词,于是就遇到了用Python实现的结巴中文分词.jieba使用起来非常简单,同时分词的结果也令人印象深刻,有兴趣的可以 ...

  2. (转)jieba中文分词的.NET版本:jieba.NET

    简介 平时经常用Python写些小程序.在做文本分析相关的事情时免不了进行中文分词,于是就遇到了用Python实现的结巴中文分词.jieba使用起来非常简单,同时分词的结果也令人印象深刻,有兴趣的可以 ...

  3. jieba中文分词

      jieba中文分词¶   中文与拉丁语言不同,不是以空格分开每个有意义的词,在我们处理自然语言处理的时候,大部分情况下,词汇是对句子和文章的理解基础.因此需要一个工具去把完整的中文分解成词. ji ...

  4. python安装Jieba中文分词组件并测试

    python安装Jieba中文分词组件 1.下载http://pypi.python.org/pypi/jieba/ 2.解压到解压到python目录下: 3.“win+R”进入cmd:依次输入如下代 ...

  5. 《机学一》特征工程1 ——文本处理:sklearn抽取、jieba中文分词、TF和IDF抽取

    零.机器学习整个实现过程: 一.机器学习数据组成 特征值: 目标值: 二.特征工程和文本特征提取 1.概要: 1.特征工程是什么 2.特征工程的意义:直接影响预测结果 3.scikit-learn库 ...

  6. jieba中文分词(python)

    问题小结 1.安装 需要用到python,根据python2.7选择适当的安装包.先下载http://pypi.python.org/pypi/jieba/ ,解压后运行python setup.py ...

  7. 中文分词中的战斗机-jieba库

    英文分词的第三方库NLTK不错,中文分词工具也有很多(盘古分词.Yaha分词.Jieba分词等).但是从加载自定义字典.多线程.自动匹配新词等方面来看. 大jieba确实是中文分词中的战斗机. 请随意 ...

  8. Python分词模块推荐:jieba中文分词

    一.结巴中文分词采用的算法 基于Trie树结构实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG)采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合对于未登录词,采 ...

  9. NLP自然语言处理 jieba中文分词,关键词提取,词性标注,并行分词,起止位置,文本挖掘,NLP WordEmbedding的概念和实现

    1. NLP 走近自然语言处理 概念 Natural Language Processing/Understanding,自然语言处理/理解 日常对话.办公写作.上网浏览 希望机器能像人一样去理解,以 ...

随机推荐

  1. Redis 数据库入门指南

    Redis 是一个开源数据库,它使用内存数据结构存储,可作为数据库.缓存和消息代理使用.Redis 支持丰富的数据结构,有:字符串(Strings).哈希(Hashs).列表(Lists).集合(Se ...

  2. LeetCode 104. Maximum Depth of Binary Tree

    Problem: Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along ...

  3. iOS Start developing ios apps (OC) pdf

    这是苹果官方最后一次更新的基于OC的iOS开发基础教程, 如果英文的看不懂,还有中文的版本哦. 点击下面的链接 好东西,分享给大家! 如果确实有帮到你,麻烦star一下我的github吧!

  4. 【原】iOS学习之tableView的常见BUG

    1.TableView头视图不随视图移动,头视图出现错位 错误原因:tableView的 UITableViewStyle 没有明确的声明 解决方法:在tableView声明的时候明确为 UITabl ...

  5. Shell运算符:Shell算数运算符、关系运算符、布尔运算符、字符串运算符等

    摘自:http://c.biancheng.net/cpp/view/2736.html

  6. tornado学习笔记18 _RequestDispatcher 请求分发器

    根据Application的配置,主要负责将客户端的请求分发到具体的RequestHandler.这个类实现了HTTPMessageDelegate接口. 18.1 构造函数 定义: def __in ...

  7. javaFx:使用弹出对话框 Alert

    javaFx8 自带的对话框非常好用,类似的使用方式如下: /** * 弹出一个通用的确定对话框 * @param p_header 对话框的信息标题 * @param p_message 对话框的信 ...

  8. .net core Jwt 添加

    Jwt 已经成为跨平台身份验证通用方案,如不了解请关注:https://jwt.io/. 为了和微软其他验证模块有个比较好的衔接,项目中采用了微软开发的jwt组件: System.IdentityMo ...

  9. java分享第十七天-02(封装操作excel类)

     java解析EXCEL用的是POI的JAR包,兼容EXCEL2003及2007+版本的EXCEL所需要的JAR包:poi-3.8.jarpoi-ooxml.jarpoi-ooxml-schemas. ...

  10. java基础2_运算符,选择语句

    算数运算符  +    相加  字符串的连接  正数 -    相减  负数 *    相乘 /    相除    10 / 3 ==> 3  两个操作数中精度最高的是int 结果也是int % ...