.NET Core 中文分词组件 jieba.NET Core

Posted DotNet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET Core 中文分词组件 jieba.NET Core相关的知识,希望对你有一定的参考价值。


来源:linezero

cnblogs.com/linezero/p/jiebanetcore.html


.NET Core中文分词组件jieba.NET Core,由于实际的一些需求,需要做中文分词。


找到了一个 jieba.NET ,不过发现没有.NET Core 版本,看到有人在issue提.NET Core,便将jieba.NET 支持.NET Core。


jieba.NET Core版: https://github.com/linezero/jieba.NET


jieba分词特点


特点


  • 支持三种分词模式:


    精确模式,试图将句子最精确地切开,适合文本分析;


    全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义。具体来说,分词过程不会借助于词频查找最大概率路径,亦不会使用HMM;


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


  • 支持繁体分词


  • 支持添加自定义词典和自定义词


jieba.NET Core 用法


下载代码使用VS 2017 打开,或者使用VS Code 打开项目。


选择jieba.NET 为起始项目,Program.cs 代码如下:


class Program

{

    static void Main(string[] args)

    {

        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

        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));

        Console.ReadKey();

    }

}


运行程序结果如下:



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


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


词性标注


词性标注采用和ictclas兼容的标记法,关于ictclas和jieba中使用的标记法列表,请参考:词性标记。(https://gist.github.com/luw2007/6016931)


在TestDemo.cs 中PosCutDemo 方法为词性标注。


public void PosCutDemo()

{

    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))));

}


调用结果如下:


.NET Core 中文分词组件 jieba.NET Core


关键词提取


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


public void ExtractTagsDemo()

{

    var text =

        "程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、高级程序员、系统分析员和项目经理四大类。";

    var extractor = new TfidfExtractor();

    var keywords = extractor.ExtractTags(text);

    foreach (var keyword in keywords)

    {

        Console.WriteLine(keyword);

    }

}



public void ExtractTagsDemo2()

{

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

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

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


    var extractor = new TfidfExtractor();

    var keywords = extractor.ExtractTags(text, 10, Constants.NounAndVerbPos);

    foreach (var keyword in keywords)

    {

        Console.WriteLine(keyword);

    }

}


ExtractTagsDemo 方法为提取所有关键词。


.NET Core 中文分词组件 jieba.NET Core


ExtractTagsDemo2 方法为提取前十个仅包含名词和动词的关键词


.NET Core 中文分词组件 jieba.NET Core


ExtractTagsWithWeight方法的返回结果中除了包含关键词,还包含了相应的权重值。


返回词语在原文的起止位置


public void TokenizeDemo()

{

    var segmenter = new JiebaSegmenter();

    var s = "永和服装饰品有限公司";

    var tokens = segmenter.Tokenize(s);

    foreach (var token in tokens)

    {

        Console.WriteLine("word {0,-12} start: {1,-3} end: {2,-3}", token.Word, token.StartIndex, token.EndIndex);

    }

}


调用 TokenizeDemo 方法会返回对应位置


.NET Core 中文分词组件 jieba.NET Core


新词加入


代码加入


var segmenter = new JiebaSegmenter();

var segments = segmenter.Cut(@".NETCore2.0的发布时间,.NET Core 2.0预览版及.NET Standard 2.0 Preview大概在5月中旬或下旬发布。");

Console.WriteLine("【精确模式】:{0}", string.Join("/ ", segments));

segmenter.AddWord("发布时间");

segmenter.AddWord(".NETCore2.0");

segments = segmenter.Cut(@".NETCore2.0的发布时间,.NET Core 2.0预览版及.NET Standard 2.0 Preview大概在5月中旬或下旬发布。");

Console.WriteLine("【精确模式】:{0}", string.Join("/ ", segments));


调用 segmenter.AddWord添加新词,这里添加了发布时间及.NETCore2.0



可以看到新加入的词被识别出来。


词典加入


词典格式如下:词典格式与主词典格式相同,即一行包含:词、词频(可省略)、词性(可省略),用空格隔开。词频省略时,分词器将使用自动计算出的词频保证该词被分出。


创新办 3 i

云计算 5

凱特琳 nz

台中

机器学习 3

深度学习 8

linezero 2


然后使用segmenter.LoadUserDict() 方法,传入词典路径。


更多详细内容,可以查看代码及readme.md


参考文档:http://www.cnblogs.com/anderslly/p/jiebanet.html


看完本文有收获?请转发分享给更多人

关注「DotNet」,提升.Net技能 

以上是关于.NET Core 中文分词组件 jieba.NET Core的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core MVC 查看组件搜索路径

Solr7.x学习-创建core并使用分词器

在 ASP.NET Core 站点中实现 Blazor - 组件不在视图中呈现

jieba分词工具的使用

.net core razor 页面中的多个视图组件未正确绑定

net core体系-web应用程序7asp.net core日志组件