简介

平时经常用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. LinkedHashMap源码阅读笔记(基于jdk1.8)

    LinkedHashMap是HashMap的子类,很多地方都是直接引用HashMap中的方法,所以需要注意的地方并不多.关键的点就是几个重写的方法: 1.Entry是继承与Node类,也就是Linke ...

  2. Linux学习笔记(8)-exec族函数

    昨天学习了Linux下的进程创建,创建一个进程的方法极为简单,只需要调用fork函数就可以创建出一个进程,但是-- 介绍fork()函数的时候提到,在创建进程后,子进程与父进程有相同的代码空间,执行的 ...

  3. test imetro

    haha hahah2 hahah3 hahah4 text int main() { cout << "helloworld" << endl; } pi ...

  4. js闭包-在你身边却不知

    今天组里小伙很纳闷的问了我js绑事件带出的一个小问题,随便聊聊闭包那点事,背景如下: 当点击Button的时候给li绑定事件,事件的大概内容是获取li位置的index再做点事,据他描述代码看上去也没错 ...

  5. Windows下搭建Spark+Hadoop开发环境

    Windows下搭建Spark+Hadoop开发环境需要一些工具支持. 只需要确保您的电脑已装好Java环境,那么就可以开始了. 一. 准备工作 1. 下载Hadoop2.7.1版本(写Spark和H ...

  6. (转)Vsdocman7.2 注册版

    Vsdocman是一个优秀的.NET源代码注释编写工具,方便的以GUI的方式设计.NET源代码的注释.我们只是大自然的搬运工:http://download.csdn.net/detail/iamyg ...

  7. 浏览器全屏事件(Html5)

    <button onclick="launchFullscreen(document.documentElement);"></button> functi ...

  8. SDOI 2016 游戏

    树链剖分 线段树维护区间最小值,区间最大值 更新,对于每一个区间,找到当前区间的最小值的最大值,和要更新的值比较,如果比最大值还大,则此数对于以后的询问无任何贡献,直接返回即可,若有贡献,则一直递归到 ...

  9. 剑指offer编程题java实现(正在更新)

    面试题三:查找二维数组中元素问题 public static void main(String[] args){ int[][] num = {{1,2,8,9},{2,4,9,12},{4,7,10 ...

  10. VS2013.3 & VS2014 任务资源管理器

    Web 开发,特别是前端 Web 开发,正迅速变得像传统的后端开发一样复杂和精密.前端生成过程,可以囊括SASS 和LESS扩展.CSS/JS的压缩包.JSHint 或 JSLint的运行时 .或者更 ...