NLP-结巴分词

NLP-结巴分词结巴分词结巴分词是有国内程序员(https://github.com/fxsjy/jieba)做的一个分词工具,刚开始是Python版本的,后来由anderscui(https://github.com/anderscui/jieba.NET)移植到.Net上面。结巴分词的分词过程大致为:·前缀词典(Trie):用于存储主词典,也可以动态增删词条,这个词典可以理解为jieba所“知道”的词,或者说已登录词;·有向无环图(DAG):通过前缀词典,可以找出句子所有可能的成词结果;·最大概率

大家好,又见面了,我是你们的朋友全栈君。

结巴分词

结巴分词是有国内程序员(https://github.com/fxsjy/jieba)做的一个分词工具,刚开始是Python版本的,后来由anderscui(https://github.com/anderscui/jieba.NET )移植到.Net上面。

结巴分词的分词过程大致为:

·前缀词典(Trie:用于存储主词典,也可以动态增删词条,这个词典可以理解为jieba知道的词,或者说已登录词;

·有向无环图(DAG:通过前缀词典,可以找出句子所有可能的成词结果;

·最大概率路径:通过DAG,可以了解所有的成词结果,每个结果对应于一条路径及其概率。由于不同词条的出现概率不同,不同的结果就对应了不同的概率,我们找出概率最大的那条路径。到这里,我们对于已登录词做出了最合理的划分;

·HMM模型Viterbi算法:最大概率路径之后,我们可能会遇到一些未登录词(不包含在前缀词典中的词),这时通过HMMViterbi尝试进一步的划分,得到最终结果

刚开始结巴分词只有分词功能,后来加入了词性标注、关键词提取等功能,加上其开源的属性,还是很好用的。

安装方法

通过NuGet包管理器安装jieba.NET

1.png

在当前项目安装了结巴分词之后,可以在当前项目的packages\jieba.NET\文件夹下看到一个Resource文件夹,里面是结巴分词所需要的各种数据文件,需要对数据文件的位置进行配置才能使用。有几种方法:

    方法一、对于VS项目来说,直接将Resource文件夹拷贝到项目的bin\Debug\目录下。

                   方法二、修改VS的配置文件app.config,加入如下配置项。

<appSettings>

    <add key=”JiebaConfigFileDir” value=fileDir />

</appSettings>

其中的fileDir就是Resource文件夹的内容所在的目录

Jieba.NET使用

分词

结巴提供了三种分词的方法:

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

全模式:把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义问题;

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

对于未登录词,采用了基于汉字成词能力的HMM模型,使用了Viterbi算法。

下面请看详细用法:

1.      精确模式

<span style="color:#333333"><span style="background-color:#f5f5f5">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JiebaNet.Analyser;
using JiebaNet.Segmenter;
namespace JiebaTest
{
    class Program
    {
        static void Main(string[] args)
               {          
                       string text = "当人类得知宇宙的黑暗森林状态后,这个在篝火旁大喊的孩子立刻 浇灭了火,在黑暗中瑟瑟发抖,连一颗火星都害怕了。在最初的几天里,甚至民用移动通信都被禁止,全球大部分通信基站 都被强令关闭。";
            var segmenter = new JiebaSegmenter();
            //使用精确模式,函数参数:待分词文本,关闭全模式,不使用hmm模型
            var result = segmenter.Cut(text,cutAll: false, hmm: false);
            Console.WriteLine("{0}", string.Join("/", result));
            Console.ReadKey();
                }
        }
}</span></span>

运行结果:

2.png

2.      全模式

与精确模式不同的只有如下一句:

<span style="color:#333333"><span style="background-color:#f5f5f5">var result1 = segmenter.Cut(text, cutAll:true, hmm: false);</span></span>

3.png

可以看到会有重复分词的现象,这是因为结巴分词把歧义词项一并列出来的缘故。

3.      搜索模式

<span style="color:#333333"><span style="background-color:#f5f5f5">            var result2 = segmenter.CutForSearch(text,hmm:true);
            Console.WriteLine("{0}", string.Join("/", result2));</span></span>

CutForSearch()只有两个参数,意义也和精确模式一样,程序运行结果:

4.png

 

自定义分词

很多时候我们需要针对自己的场景进行分词,会有一些领域内的专有词汇。这时候我们需要让分词器能识别特定的词或者不识别特定的词。有两种方法:

1. 对于少量的词汇,我们可以通过AddWord()函数添加新词和调整词频,通过DeleteWord()函数删除词典中的某一词使分词器不再将其作为一个词;若AddWord()的参数freq不是正整数,则使用自动计算出的词频,计算出的词频可保证该词被分出来。

2. 通过LoadUserDict(“usr_dict_path”)函数添加自定义的词典。开发者可以指定自定义的词典,以便包含jieba词库里没有的词。虽然jieba有新词识别能力,但是自行添加新词可以保证更高的正确率。词典格式与主词典格式相同,即一行包含:词、词频(可省略)、词性(可省略),用空格隔开。词频省略时,分词器将使用自动计算出的词频保证该词被分出。

下面请看详细介绍:

1.AddWord()和DeleteWord()的使用

程序运行结果:

<span style="color:#333333"><span style="background-color:#f5f5f5">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JiebaNet.Analyser;
using JiebaNet.Segmenter;
 
namespace JiebaTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var segmenter = new JiebaSegmenter();
            string hello = "大家好,这个人叫陈建驱";
            var result_hello = segmenter.Cut(hello,hmm:false);
            Console.WriteLine("{0}", string.Join("/", result_hello));
 
            segmenter.AddWord("陈建驱",freq:0,tag:null);
            var result_hello1 = segmenter.Cut(hello, hmm: false);
            Console.WriteLine("{0}", string.Join("/", result_hello1));
 
            segmenter.DeleteWord("陈建驱"); //使用JiebaSegmenter.DeleteWord(word)可移除一个词,使其不能被分出来
            var result_hello2 = segmenter.Cut(hello, hmm: false);
            Console.WriteLine("{0}", string.Join("/", result_hello2));
            Console.ReadKey();
        }
    }
}</span></span>

5.png

2.加载自定义词典

首先加载这个词典,我把它放到了运行目录下:

6.png

然后对比加载词典前后的区别,代码如下:

<span style="color:#333333"><span style="background-color:#f5f5f5">segmenter.LoadUserDict("usr_dict_file_path");
var result_hello1 = segmenter.Cut(hello, hmm: false);
Console.WriteLine("{0}", string.Join("/", result_hello1));</span></span>

运行结果:

待续。。。

 

关键词提取

Jieba有两种关键词提取的算法,一种是基于TF-IDF算法的关键词提取,另一种是基于TextRank算法的关键词提取。后者在语料库小时效果较差。

TF-IDF关键词抽取基于逆向文件频率(IDF),组件内置一个IDF语料库,可以配置为其它自定义的语料库。关键词抽取会过滤停用词(Stop Words),组件内置一个停用词语料库,这个语料库合并了NLTK的英文停用词和哈工大的中文停用词。

1.      基于TF-IDF的关键词提取

通过TfidfExtractor类的ExtractTags()方法调用该算法,刚方法有四个参数,各个参数的意义如下:

text:待提取的文本

count:选取权值最高的count个词返回

allowPos:对哪些词进行选取,null为默认值,表示不过滤特定的词

代码实现:

<span style="color:#333333"><span style="background-color:#f5f5f5">using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using JiebaNet.Analyser;using JiebaNet.Segmenter; namespace JiebaTest{    class Program    {        static void Main(string[] args)        {            string text1 = "在塔的二层,被剑钉在墙上的女魔法师死了,她可能是人类历史上唯 一真正的魔法师。而在这之前约十小时,短暂的魔法时代也结束了。魔 法时代开始于公元 1453 年 5 月 3 日 16 时,那时高维碎块首次接触地球; 结束于 1453 年 5 月 28 日 21 时,这时碎块完全离开地球;历时二十五天 五小时。之后,这个世界又回到了正常的轨道上。29 日傍晚,君士坦丁堡陷落了。在一天的惨烈血战接近尾声时,君士坦丁十一世面对着蜂拥而来的 奥斯曼军队,高喊一声:“滩道就没有一个基督徒来砍下我的头吗?!”然后 皇帝掀下紫袍,拔剑冲人敌阵,他那银色的盔甲像扔进暗红色镪水的一小 片锡箔,转瞬间无影无踪。。。。。。君士坦丁堡陷落的历史意义许久之后才显现出来,事情发生时人们 首先想到的,就是罗马帝国终于完全消失了。拜占庭是古罗马拖在身后 的长达千年的车辙,虽也有过辉煌,但还是终于像烈日下的水渍一样蒸发 了。当年,古罗马人在宏伟华丽的浴宫中吹着口哨,认为帝国就像身下的 浴池一样,建在整块花岗岩上,将永世延续。现在人们知道,没有不散的宴席,一切都有个尽头。";            var tf_idf = new TfidfExtractor();            var tem = tf_idf.ExtractTags(text1, count: 10, allowPos: null);            Console.WriteLine("{0}", string.Join("/", tem));            Console.WriteLine("\n");            //带权重的关键词提取            var temW = tf_idf.ExtractTagsWithWeight(text1, count: 10, allowPos: null);            foreach(var t in temW)                Console.WriteLine("{0} {1}",t.Word,t.Weight);            Console.WriteLine("\n");            Console.ReadKey();        }    }}</span></span>

运行结果:

7.png

 

2.      基于TextRank的关键词提取

该算法通过TextRankExtractor类的ExtractTags()类调用,方法参数和上面的一样。下面的代码中对提取的范围进行了限制,只分析动词和名词。

代码实现:

<span style="color:#333333"><span style="background-color:#f5f5f5">List<string> strlist = new List<string>();strlist.Add("n");strlist.Add("v");IEnumerable<string> allow=strlist;//基于TextRank的关键词提取,接口和TF-IDF一样var textRankExtractor = new TextRankExtractor();//textRankExtractor.Span = 5;//调整固定窗口的大小var tem1 = textRankExtractor.ExtractTags(text1,count:10,allowPos:allow);Console.WriteLine("{0}", string.Join("/", tem1));Console.WriteLine("\n");var tem2 = textRankExtractor.ExtractTagsWithWeight(text1, count: 10, allowPos: null);foreach (var t in tem2)  Console.WriteLine("{0} {1}", t.Word, t.Weight);Console.WriteLine("\n");</span></span>

 

运行结果:

8.png

词性标注

通过jieba.posseg.POSTokenizer(tokenizer=None) 可以自定义分词器,tokenizer 参数可指定内部使用的 jieba.Tokenizer 分词器。jieba.posseg.dt 为默认词性标注分词器。标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。

代码如下:

<span style="color:#333333"><span style="background-color:#f5f5f5">var posSegmenter = new JiebaNet.Segmenter.PosSeg.PosSegmenter();
var tokens = posSegmenter.Cut(text);
Console.WriteLine(string.Join(" ", tokens.Select(token => string.Format("{0}/{1}", token.Word, token.Flag))));</span></span>

运行结果:

9.png

词性符号采用《计算所汉语词性标记集》,详情可查看附录。

 

获取单词位置

代码实现:

<span style="color:#333333"><span style="background-color:#f5f5f5">var tk = segmenter.Tokenize(text);
//var tk1 = segmenter.Tokenize(text,TokenizerMode.Search);//搜索模式
foreach(var t in tk)
    Console.WriteLine("word{0,-12} start:{1,-3} end:{2,-3}", t.Word, t.StartIndex, t.EndIndex);</span></span>

运行结果:

10.png

 

参考文献

[1]CSDN博客:山鹰的天空. jieba.NET是jieba中文分词的.NET版本(C#实现)。.

https://blog.csdn.net/lansetiankong12/article/details/53485816. 2016-12-06

[2]博客园:Ander Cui. jieba中文分词的.NET版本:jieba.NET.

https://www.cnblogs.com/anderslly/p/jiebanet.html .2015-09-08

 

附录

计算所汉语词性标记集

Version 3.0

制订人:刘群 张华平 张浩

计算所汉语词性标记集

0.    说明

1.    名词  (1个一类,7个二类,5个三类)

2.    时间词(1个一类,1个二类)

3.    处所词(1个一类)

4.    方位词(1个一类)

5.    动词(1个一类,9个二类)

6.    形容词(1个一类,4个二类)

7.    区别词(1个一类,2个二类)

8.    状态词(1个一类)

9.    代词(1个一类,4个二类,6个三类)

10.          数词(1个一类,1个二类)

11.          量词(1个一类,2个二类)

12.          副词(1个一类)

13.          介词(1个一类,2个二类)

14.          连词(1个一类,1个二类)

15.          助词(1个一类,15个二类)

16.          叹词(1个一类)

17.          语气词(1个一类)

18.          拟声词(1个一类)

19.          前缀(1个一类)

20.          后缀(1个一类)

21.          字符串(1个一类,2个二类)

22.          标点符号(1个一类,16个二类)

 

0.          说明

计算所汉语词性标记集(共计99个,22个一类,66个二类,11个三类)主要用于中国科学院计算技术研究所研制的汉语词法分析器、句法分析器和汉英机器翻译系统。

1.          名词  (1个一类,7个二类,5个三类)

名词分为以下子类:

名词

nr 人名

nr1 汉语姓氏

nr2 汉语名字

nrj 日语人名

nrf 音译人名

ns 地名

nsf 音译地名

nt 机构团体名

nz 其它专名

nl 名词性惯用语

ng 名词性语素

2.          时间词(1个一类,1个二类)

时间词

tg 时间词性语素

3.          处所词(1个一类)

处所词

4.          方位词(1个一类)

方位词

5.          动词(1个一类,9个二类)

动词

vd 副动词

vn 名动词

vshi 动词“是”

vyou 动词“有”

vf 趋向动词

vx 形式动词

vi 不及物动词(内动词)

vl 动词性惯用语

vg 动词性语素

6.          形容词(1个一类,4个二类)

形容词

ad 副形词

an 名形词

ag 形容词性语素

al 形容词性惯用语

7.          区别词(1个一类,2个二类)

区别词

 

bl 区别词性惯用语

8.          状态词(1个一类)

状态词

9.          代词(1个一类,4个二类,6个三类)

代词

rr 人称代词

rz 指示代词

rzt 时间指示代词

rzs 处所指示代词

rzv 谓词性指示代词

ry 疑问代词

ryt 时间疑问代词

rys 处所疑问代词

ryv 谓词性疑问代词

rg 代词性语素

10.     数词(1个一类,1个二类)

数词

mq 数量词

11.     量词(1个一类,2个二类)

量词

qv 动量词

qt 时量词

12.     副词(1个一类)

副词

13.     介词(1个一类,2个二类)

介词

pba 介词“把”

pbei 介词“被”

14.     连词(1个一类,1个二类)

连词

    cc 并列连词

15.     助词(1个一类,15个二类)

助词

uzhe 

ule  

uguo 

ude1  

ude2 

ude3 

usuo 

udeng  等等 云云

uyy 一样 一般 似的 

udh 的话

uls 来讲 来说 而言 说来

 

uzhi 

ulian  (“连小学生都会”)

 

16.     叹词(1个一类)

叹词

17.     语气词(1个一类)

语气词(delete yg)

18.     拟声词(1个一类)

拟声词

19.     前缀(1个一类)

前缀

20.     后缀(1个一类)

后缀

21.     字符串(1个一类,2个二类)

字符串

    xe  Email字符串

xs 微博会话分隔符

xm 表情符合

xu 网址URL

 

 

22.     标点符号(1个一类,16个二类)

标点符号

wkz 左括号,全角:(              半角:( [ { <

wky 右括号,全角:)          半角: ) ] { >

wyz 左引号,全角:“   

wyy 右引号,全角:”  

wj 句号,全角:。

ww 问号,全角:? 半角:?

wt 叹号,全角:! 半角:!

wd 逗号,全角:, 半角:,

wf 分号,全角:; 半角: ;

wn 顿号,全角:、

wm 冒号,全角:: 半角: :

ws 省略号,全角:……  

wp 破折号,全角:――   --   ――-   半角:—  —-

wb 百分号千分号,全角:%    半角:%

wh 单位符号,全角:¥    °    半角:$

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/149464.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • AndroidStudio-断点调试-让你的调试更有效率

    AndroidStudio-断点调试-让你的调试更有效率前言:上篇博客AndroidStudio-断点调试-也许你该知道断点调试是有多么的美好,记录了AndroidStudio上断点调试的基本流程和debug面板按钮介绍.这一篇就给大家分享一点调试的小技巧,让我们的代码调试变得更有效率.你可以选择随时进入调试模式一般我们都是点击绿色小昆虫进入调试模式进行调试,其实还可以有另外一种方法.看下面的面板截图,有没有发现有两个小昆虫图标.图标E

  • 工业数据采集平台

    工业数据采集平台乐芯IOT数据采集平台产品是杭州乐芯科技有限公司为满足工业4.0大型集团工厂推出的新一代数据采集平台级产品,可满足单一平台(一个服务器)同时采集各类设备,同时兼容各种协议,单服务器压力测试达1000台,已经稳定在大型集团用户稳定运行。实现各种工业设备数据采集,包括数控机床数据采集、切割机数据采集、机器人数据采集、PLC数据采集、各种工业仪表(各类传感器、智能电表等)。并实现数据对接各大工业平台(如:根云平台、施耐德平台、阿里云平台等)。

  • JetBrains全家桶永久激活码[最新免费获取]

    (JetBrains全家桶永久激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~CIOUM2KBSU-eyJsaWNlb…

  • php allow_url_include,allow_url_include的应用和解释

    php allow_url_include,allow_url_include的应用和解释PHP常常因为它可能允许URLS被导入和执行语句被人们指责。事实上,这件事情并不是很让人感到惊奇,因为这是导致称为RemoteURLIncludevulnerabilities的php应用程序漏洞的最重要的原因之一。因为这个原因,许多安全研究人员建议在php.ini配置中禁用指向allow_url_fopen。不幸的是,许多推荐这种方法的人,并没有意识到,这样会破坏很多的应用并且并不能保证1…

  • SQL insert into select 用法

    SQL insert into select 用法SQLinsertintoselect用法一张存在的表,插入的新数据来源别的表时,可以使用insertintoselect语法。1、两种语法1、表数据user表idnamea

  • 基于java的贪吃蛇游戏的设计与实现(贪吃蛇安卓游戏源码)

    一.前言某日,看见隔壁家的小朋友在玩一款网络爆款贪吃蛇游戏,感觉很好玩。自己刚好正在学习JAVA编程,也想实现一个类似功能的游戏Demo练手,在网上查看了不少源码案例,全都是很古老的方块式贪吃蛇游戏案例,没有想要的实现,因此自己动手实现一个JAVA版的贪吃蛇游戏。我在这个Dome完成之后重写了这个游戏的Android版,并重新更名为《蛇王传说》。也欢迎大家下载试玩。游戏下载地址:https…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号