分词算法python
㈠ python中怎样处理汉语的同义词用结巴分词
python中文分词:结巴分词
中文分词是中文文本处理的一个基础性工作,结巴分词利用进行中文分词。其基本实现原理有三点:
基于Trie树结构实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG)
采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合
对于未登录词,采用了基于汉字成词能力的HMM模型,使用了Viterbi算法
安装(Linux环境)
下载工具包,解压后进入目录下,运行:python setup.py install
模式
默认模式,试图将句子最精确地切开,适合文本分析
全模式,把句子中所有的可以成词的词语都扫描出来,适合搜索引擎
接口
组件只提供jieba.cut 方法用于分词
cut方法接受两个输入参数:
第一个参数为需要分词的字符串
cut_all参数用来控制分词模式
待分词的字符串可以是gbk字符串、utf-8字符串或者unicode
jieba.cut返回的结构是一个可迭代的generator,可以使用for循环来获得分词后得到的每一个词语(unicode),也可以用list(jieba.cut(...))转化为list
实例
#! -*- coding:utf-8 -*-
import jieba
seg_list = jieba.cut("我来到北京清华大学", cut_all = True)
print "Full Mode:", ' '.join(seg_list)
seg_list = jieba.cut("我来到北京清华大学")
print "Default Mode:", ' '.join(seg_list)
㈡ 如何对excel表格里的词结巴分词python
#-*-coding:utf-8-*-
importjieba
'''''
Createdon2015-11-23
'''
defword_split(text):
"""
Splitatextinwords.
(word,location).
"""
word_list=[]
windex=0
word_primitive=jieba.cut(text,cut_all=True)
forwordinword_primitive:
iflen(word)>0:
word_list.append((windex,word))
windex+=1
returnword_list
definverted_index(text):
"""
CreateanInverted-.
{word:[locations]}
"""
inverted={}
forindex,wordinword_split(text):
locations=inverted.setdefault(word,[])
locations.append(index)
returninverted
definverted_index_add(inverted,doc_id,doc_index):
"""
AddInvertd-Indexdoc_indexofthedocumentdoc_idtothe
Multi-DocumentInverted-Index(inverted),
usingdoc_idasdocumentidentifier.
{word:{doc_id:[locations]}}
"""
forword,locationsindoc_index.iteritems():
indices=inverted.setdefault(word,{})
indices[doc_id]=locations
returninverted
defsearch_a_word(inverted,word):
"""
searchoneword
"""
word=word.decode('utf-8')
ifwordnotininverted:
returnNone
else:
word_index=inverted[word]
returnword_index
defsearch_words(inverted,wordList):
"""
searchmorethanoneword
"""
wordDic=[]
docRight=[]
forwordinwordList:
ifisinstance(word,str):
word=word.decode('utf-8')
ifwordnotininverted:
returnNone
else:
element=inverted[word].keys()
element.sort()
wordDic.append(element)
numbers=len(wordDic)
inerIndex=[0foriinrange(numbers)]
docIndex=[wordDic[i][0]foriinrange(numbers)]
flag=True
whileflag:
ifmin(docIndex)==max(docIndex):
docRight.append(min(docIndex))
inerIndex=[inerIndex[i]+1foriinrange(numbers)]
foriinrange(numbers):
ifinerIndex[i]>=len(wordDic[i]):
flag=False
returndocRight
docIndex=[wordDic[i][inerIndex[i]]foriinrange(numbers)]
else:
minIndex=min(docIndex)
minPosition=docIndex.index(minIndex)
inerIndex[minPosition]+=1
ifinerIndex[minPosition]>=len(wordDic[minPosition]):
flag=False
returndocRight
docIndex=[wordDic[i][inerIndex[i]]foriinrange(numbers)]
defsearch_phrase(inverted,phrase):
"""
searchphrase
"""
docRight={}
temp=word_split(phrase)
wordList=[temp[i][1]foriinrange(len(temp))]
docPossible=search_words(inverted,wordList)
fordocindocPossible:
wordIndex=[]
indexRight=[]
forwordinwordList:
wordIndex.append(inverted[word][doc])
numbers=len(wordList)
inerIndex=[0foriinrange(numbers)]
words=[wordIndex[i][0]foriinrange(numbers)]
flag=True
whileflag:
ifwords[-1]-words[0]==numbers-1:
indexRight.append(words[0])
inerIndex=[inerIndex[i]+1foriinrange(numbers)]
foriinrange(numbers):
ifinerIndex[i]>=len(wordIndex[i]):
flag=False
docRight[doc]=indexRight
break
ifflag:
words=[wordIndex[i][inerIndex[i]]foriinrange(numbers)]
else:
minIndex=min(words)
minPosition=words.index(minIndex)
inerIndex[minPosition]+=1
ifinerIndex[minPosition]>=len(wordIndex[minPosition]):
flag=False
break
ifflag:
words=[wordIndex[i][inerIndex[i]]foriinrange(numbers)]
returndocRight
if__name__=='__main__':
doc1="""
中文分词指的是将一个汉字序列切分成一个一个单独的词。分词就是将连续的字序列按照一定的规范
重新组合成词序列的过程。我们知道,在英文的行文中,单词之间是以空格作为自然分界符的,而中文
只是字、句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,虽然英文也同样
存在短语的划分问题,不过在词这一层上,中文比之英文要复杂的多、困难的多。
"""
doc2="""
存在中文分词技术,是由于中文在基本文法上有其特殊性,具体表现在:
与英文为代表的拉丁语系语言相比,英文以空格作为天然的分隔符,而中文由于继承自古代汉语的传统,
词语之间没有分隔。古代汉语中除了连绵词和人名地名等,词通常就是单个汉字,所以当时没有分词
书写的必要。而现代汉语中双字或多字词居多,一个字不再等同于一个词。
在中文里,“词”和“词组”边界模糊
现代汉语的基本表达单元虽然为“词”,且以双字或者多字词居多,但由于人们认识水平的不同,对词和
短语的边界很难去区分。
例如:“对随地吐痰者给予处罚”,“随地吐痰者”本身是一个词还是一个短语,不同的人会有不同的标准,
同样的“海上”“酒厂”等等,即使是同一个人也可能做出不同判断,如果汉语真的要分词书写,必然会出现
混乱,难度很大。
中文分词的方法其实不局限于中文应用,也被应用到英文处理,如手写识别,单词之间的空格就不很清楚,
中文分词方法可以帮助判别英文单词的边界。
"""
doc3="""
作用
中文分词是文本挖掘的基础,对于输入的一段中文,成功的进行中文分词,可以达到电脑自动识别语句含义的效果。
中文分词技术属于自然语言处理技术范畴,对于一句话,人可以通过自己的知识来明白哪些是词,哪些不是词,
但如何让计算机也能理解?其处理过程就是分词算法。
影响
中文分词对于搜索引擎来说,最重要的并不是找到所有结果,因为在上百亿的网页中找到所有结果没有太多的意义,
没有人能看得完,最重要的是把最相关的结果排在最前面,这也称为相关度排序。中文分词的准确与否,常常直接
影响到对搜索结果的相关度排序。从定性分析来说,搜索引擎的分词算法不同,词库的不同都会影响页面的返回结果
"""
doc4="""
这种方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行配,
若在词典中找到某个字符串,则匹配成功(识别出一个词)。按照扫描方向的不同,串匹配分词方法可以分为正向
匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;常用的几种
机械分词方法如下:
正向最大匹配法(由左到右的方向);
逆向最大匹配法(由右到左的方向);
最少切分(使每一句中切出的词数最小);
双向最大匹配法(进行由左到右、由右到左两次扫描)
还可以将上述各种方法相互组合,例如,可以将正向最大匹配方法和逆向最大匹配方法结合起来构成双向匹配法。
由于汉语单字成词的特点,正向最小匹配和逆向最小匹配一般很少使用。一般说来,逆向匹配的切分精度略高于
正向匹配,遇到的歧义现象也较少。统计结果表明,单纯使用正向最大匹配的错误率为,单纯使用逆向
最大匹配的错误率为。但这种精度还远远不能满足实际的需要。实际使用的分词系统,都是把机械分词
作为一种初分手段,还需通过利用各种其它的语言信息来进一步提高切分的准确率。
一种方法是改进扫描方式,称为特征扫描或标志切分,优先在待分析字符串中识别和切分出一些带有明显特征
的词,以这些词作为断点,可将原字符串分为较小的串再来进机械分词,从而减少匹配的错误率。另一种方法
是将分词和词类标注结合起来,利用丰富的词类信息对分词决策提供帮助,并且在标注过程中又反过来对分词
结果进行检验、调整,从而极大地提高切分的准确率。
对于机械分词方法,可以建立一个一般的模型,在这方面有专业的学术论文,这里不做详细论述。
"""
doc5="""
从形式上看,词是稳定的字的组合,因此在上下文中,相邻的字同时出现的次数越多,就越有可能构成一个词。
因此字与字相邻共现的频率或概率能够较好的反映成词的可信度。可以对语料中相邻共现的各个字的组合的频度
进行统计,计算它们的互现信息。定义两个字的互现信息,计算两个汉字的相邻共现概率。互现信息体现了
汉字之间结合关系的紧密程度。当紧密程度高于某一个阈值时,便可认为此字组可能构成了一个词。这种方法
只需对语料中的字组频度进行统计,不需要切分词典,因而又叫做无词典分词法或统计取词方法。但这种方法
也有一定的局限性,会经常抽出一些共现频度高、但并不是词的常用字组,例如“这一”、“之一”、“有的”、
“我的”、“许多的”等,并且对常用词的识别精度差,时空开销大。实际应用的统计分词系统都要使用一部基本
的分词词典(常用词词典)进行串匹配分词,同时使用统计方法识别一些新的词,即将串频统计和串匹配结合起来,
既发挥匹配分词切分速度快、效率高的特点,又利用了无词典分词结合上下文识别生词、自动消除歧义的优点。
另外一类是基于统计机器学习的方法。首先给出大量已经分词的文本,利用统计机器学习模型学习词语切分的规律
(称为训练),从而实现对未知文本的切分。我们知道,汉语中各个字单独作词语的能力是不同的,此外有的字常
常作为前缀出现,有的字却常常作为后缀(“者”“性”),结合两个字相临时是否成词的信息,这样就得到了许多
与分词有关的知识。这种方法就是充分利用汉语组词的规律来分词。这种方法的最大缺点是需要有大量预先分好词
的语料作支撑,而且训练过程中时空开销极大。
到底哪种分词算法的准确度更高,目前并无定论。对于任何一个成熟的分词系统来说,不可能单独依靠某一种算法
来实现,都需要综合不同的算法。例如,海量科技的分词算法就采用“复方分词法”,所谓复方,就是像中西医结合
般综合运用机械方法和知识方法。对于成熟的中文分词系统,需要多种算法综合处理问题。
"""
#BuildInverted-Indexfordocuments
inverted={}
documents={'doc1':doc1,'doc2':doc2,'doc3':doc3,'doc4':doc4,'doc5':doc5}
fordoc_id,textindocuments.iteritems():
doc_index=inverted_index(text)
inverted_index_add(inverted,doc_id,doc_index)
#Searchoneword
aWord="分词"
result_a_word=search_a_word(inverted,aWord)
ifresult_a_word:
result_a_word_docs=result_a_word.keys()
print"'%s'isappearedat"%(aWord)
forresult_a_word_docinresult_a_word_docs:
result_a_word_index=result_a_word[result_a_word_doc]
forindexinresult_a_word_index:
print(str(index)+''),
print"of"+result_a_word_doc
print""
else:
print"Nomatches! "
#Searchmorethanoneword
words=["汉语","切分"]
result_words=search_words(inverted,words)
ifresult_words:
print("["),
foriinrange(len(words)):
print("%s"%(words[i])),
print("]areappearedatthe"),
forresult_words_docinresult_words:
print(result_words_doc+''),
print" "
else:
print"Nomatches! "
#Searchphrase
phrase="中文分词"
result_phrase=search_phrase(inverted,phrase)
ifresult_phrase:
result_phrase_docs=result_phrase.keys()
print"'%s'isappearedatthe"%(phrase)
forresult_phrase_docinresult_phrase_docs:
result_phrase_index=result_phrase[result_phrase_doc]
forindexinresult_phrase_index:
print(str(index)+''),
print"of"+result_phrase_doc
print""
else:
print"Nomatches! "
㈢ 用python怎么能够将一句中文分割为单个的字
字符串可以直接分片或者索引访问,比如s[0]=我,s[-1]=做。等等。
如果是要转成list,可以直接构造,如: l=list('abc')或者l=list(s)
分词需要相应的算法和词典支持。pymmseg-cpp是一个不错的python中文分词库。你可以试试。
https://github.com/pluskid/pymmseg-cpp/
㈣ Python中,已经得到一个包含所有单词的词典,如何统计词典中的单词在每一句话中出现的次数
众所周知,英文是以词为单位的,词和词之间是靠空格隔开,而中文是以字为单位,句子中所有的字连起来才能描述一个意思。例如,英文句子I am a student,用中文则为:“我是一个学生”。计算机可以很简单通过空格知道student是一个单词,但是不能很容易明白“学”、“生”两个字合起来才表示一个词。把中文的汉字序列切分成有意义的词,就是中文分词,有些人也称为切词。我是一个学生,分词的结果是:我 是 一个 学生。
中文分词技术属于自然语言处理技术范畴,对于一句话,人可以通过自己的知识来明白哪些是词,哪些不是词,但如何让计算机也能理解?其处理过程就是分词算法。
现有的分词算法可分为三大类:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法。
1、基于字符串匹配的分词方法
这种方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行配,若在词典中找到某个字符串,则匹配成功(识别出一个词)。按照扫描方向的不同,串匹配分词方法可以分为正向匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与标注相结合的一体化方法。常用的几种机械分词方法如下:
1)正向最大匹配法(由左到右的方向);
2)逆向最大匹配法(由右到左的方向);
3)最少切分(使每一句中切出的词数最小)。
还可以将上述各种方法相互组合,例如,可以将正向最大匹配方法和逆向最大匹配方法结合起来构成双向匹配法。由于汉语单字成词的特点,正向最小匹配和逆向最小匹配一般很少使用。一般说来,逆向匹配的切分精度略高于正向匹配,遇到的歧义现象也较少。统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/245。但这种精度还远远不能满足实际的需要。实际使用的分词系统,都是把机械分词作为一种初分手段,还需通过利用各种其它的语言信息来进一步提高切分的准确率。
一种方法是改进扫描方式,称为特征扫描或标志切分,优先在待分析字符串中识别和切分出一些带有明显特征的词,以这些词作为断点,可将原字符串分为较小的串再来进机械分词,从而减少匹配的错误率。另一种方法是将分词和词类标注结合起来,利用丰富的词类信息对分词决策提供帮助,并且在标注过程中又反过来对分词结果进行检验、调整,从而极大地提高切分的准确率。
对于机械分词方法,可以建立一个一般的模型,在这方面有专业的学术论文,这里不做详细论述。
2、基于理解的分词方法
这种分词方法是通过让计算机模拟人对句子的理解,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法需要使用大量的语言知识和信息。由于汉语语言知识的笼统、复杂性,难以将各种语言信息组织成机器可直接读取的形式,因此目前基于理解的分词系统还处在试验阶段。
3、基于统计的分词方法
从形式上看,词是稳定的字的组合,因此在上下文中,相邻的字同时出现的次数越多,就越有可能构成一个词。因此字与字相邻共现的频率或概率能够较好的反映成词的可信度。可以对语料中相邻共现的各个字的组合的频度进行统计,计算它们的互现信息。定义两个字的互现信息,计算两个汉字X、Y的相邻共现概率。互现信息体现了汉字之间结合关系的紧密程度。当紧密程度高于某一个阈值时,便可认为此字组可能构成了一个词。这种方法只需对语料中的字组频度进行统计,不需要切分词典,因而又叫做无词典分词法或统计取词方法。但这种方法也有一定的局限性,会经常抽出一些共现频度高、但并不是词的常用字组,例如“这一”、“之一”、“有的”、“我的”、“许多的”等,并且对常用词的识别精度差,时空开销大。实际应用的统计分词系统都要使用一部基本的分词词典(常用词词典)进行串匹配分词,同时使用统计方法识别一些新的词,即将串频统计和串匹配结合起来,既发挥匹配分词切分速度快、效率高的特点,又利用了无词典分词结合上下文识别生词、自动消除歧义的优点。
到底哪种分词算法的准确度更高,目前并无定论。对于任何一个成熟的分词系统来说,不可能单独依靠某一种算法来实现,都需要综合不同的算法。笔者了解,海量科技的分词算法就采用“复方分词法”,所谓复方,相当于用中药中的复方概念,即用不同的药才综合起来去医治疾病,同样,对于中文词的识别,需要多种算法来处理不同的问题。
㈤ Python中文分词的原理你知道吗
中文分词,即 Chinese Word Segmentation,即将一个汉字序列进行切分,得到一个个单独的词。表面上看,分词其实就是那么回事,但分词效果好不好对信息检索、实验结果还是有很大影响的,同时分词的背后其实是涉及各种各样的算法的。
中文分词与英文分词有很大的不同,对英文而言,一个单词就是一个词,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,需要人为切分。根据其特点,可以把分词算法分为四大类:
基于规则的分词方法
基于统计的分词方法
基于语义的分词方法
基于理解的分词方法
下面我们对这几种方法分别进行总结。
基于规则的分词方法
这种方法又叫作机械分词方法、基于字典的分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行匹配。若在词典中找到某个字符串,则匹配成功。该方法有三个要素,即分词词典、文本扫描顺序和匹配原则。文本的扫描顺序有正向扫描、逆向扫描和双向扫描。匹配原则主要有最大匹配、最小匹配、逐词匹配和最佳匹配。
最大匹配法(MM)。基本思想是:假设自动分词词典中的最长词条所含汉字的个数为 i,则取被处理材料当前字符串序列中的前 i 个字符作为匹配字段,查找分词词典,若词典中有这样一个 i 字词,则匹配成功,匹配字段作为一个词被切分出来;若词典中找不到这样的一个 i 字词,则匹配失败,匹配字段去掉最后一个汉字,剩下的字符作为新的匹配字段,再进行匹配,如此进行下去,直到匹配成功为止。统计结果表明,该方法的错误率 为 1/169。
逆向最大匹配法(RMM)。该方法的分词过程与 MM 法相同,不同的是从句子(或文章)末尾开始处理,每次匹配不成功时去掉的是前面的一个汉字。统计结果表明,该方法的错误率为 1/245。
逐词遍历法。把词典中的词按照由长到短递减的顺序逐字搜索整个待处理的材料,一直到把全部的词切分出来为止。不论分词词典多大,被处理的材料多么小,都得把这个分词词典匹配一遍。
设立切分标志法。切分标志有自然和非自然之分。自然切分标志是指文章中出现的非文字符号,如标点符号等;非自然标志是利用词缀和不构成词的词(包 括单音词、复音节词以及象声词等)。设立切分标志法首先收集众多的切分标志,分词时先找出切分标志,把句子切分为一些较短的字段,再用 MM、RMM 或其它的方法进行细加工。这种方法并非真正意义上的分词方法,只是自动分词的一种前处理方式而已,它要额外消耗时间扫描切分标志,增加存储空间存放那些非 自然切分标志。
最佳匹配法(OM)。此法分为正向的最佳匹配法和逆向的最佳匹配法,其出发点是:在词典中按词频的大小顺序排列词条,以求缩短对分词词典的检索时 间,达到最佳效果,从而降低分词的时间复杂度,加快分词速度。实质上,这种方法也不是一种纯粹意义上的分词方法,它只是一种对分词词典的组织方式。OM 法的分词词典每条词的前面必须有指明长度的数据项,所以其空间复杂度有所增加,对提高分词精度没有影响,分词处理的时间复杂度有所降低。
此种方法优点是简单,易于实现。但缺点有很多:匹配速度慢;存在交集型和组合型歧义切分问题;词本身没有一个标准的定义,没有统一标准的词集;不同词典产生的歧义也不同;缺乏自学习的智能性。
基于统计的分词方法
该方法的主要思想:词是稳定的组合,因此在上下文中,相邻的字同时出现的次数越多,就越有可能构成一个词。因此字与字相邻出现的概率或频率能较好地反映成词的可信度。可以对训练文本中相邻出现的各个字的组合的频度进行统计,计算它们之间的互现信息。互现信息体现了汉字之间结合关系的紧密程度。当紧密程 度高于某一个阈值时,便可以认为此字组可能构成了一个词。该方法又称为无字典分词。
该方法所应用的主要的统计模型有:N 元文法模型(N-gram)、隐马尔可夫模型(Hiden Markov Model,HMM)、最大熵模型(ME)、条件随机场模型(Conditional Random Fields,CRF)等。
在实际应用中此类分词算法一般是将其与基于词典的分词方法结合起来,既发挥匹配分词切分速度快、效率高的特点,又利用了无词典分词结合上下文识别生词、自动消除歧义的优点。
基于语义的分词方法
语义分词法引入了语义分析,对自然语言自身的语言信息进行更多的处理,如扩充转移网络法、知识分词语义分析法、邻接约束法、综合匹配法、后缀分词法、特征词库法、矩阵约束法、语法分析法等。
扩充转移网络法
该方法以有限状态机概念为基础。有限状态机只能识别正则语言,对有限状态机作的第一次扩充使其具有递归能力,形成递归转移网络 (RTN)。在RTN 中,弧线上的标志不仅可以是终极符(语言中的单词)或非终极符(词类),还可以调用另外的子网络名字分非终极符(如字或字串的成词条件)。这样,计算机在 运行某个子网络时,就可以调用另外的子网络,还可以递归调用。词法扩充转移网络的使用, 使分词处理和语言理解的句法处理阶段交互成为可能,并且有效地解决了汉语分词的歧义。
矩阵约束法
其基本思想是:先建立一个语法约束矩阵和一个语义约束矩阵, 其中元素分别表明具有某词性的词和具有另一词性的词相邻是否符合语法规则, 属于某语义类的词和属于另一词义类的词相邻是否符合逻辑,机器在切分时以之约束分词结果。
基于理解的分词方法
基于理解的分词方法是通过让计算机模拟人对句子的理解,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法需要使用大量的语言知识和信息。目前基于理解的分词方法主要有专家系统分词法和神经网络分词法等。
专家系统分词法
从专家系统角度把分词的知识(包括常识性分词知识与消除歧义切分的启发性知识即歧义切分规则)从实现分词过程的推理机中独立出来,使知识库的维护与推理机的实现互不干扰,从而使知识库易于维护和管理。它还具有发现交集歧义字段和多义组合歧义字段的能力和一定的自学习功能。
神经网络分词法
该方法是模拟人脑并行,分布处理和建立数值计算模型工作的。它将分词知识所分散隐式的方法存入神经网络内部,通过自学习和训练修改内部权值,以达到正确的分词结果,最后给出神经网络自动分词结果,如使用 LSTM、GRU 等神经网络模型等。
神经网络专家系统集成式分词法
该方法首先启动神经网络进行分词,当神经网络对新出现的词不能给出准确切分时,激活专家系统进行分析判断,依据知识库进行推理,得出初步分析,并启动学习机制对神经网络进行训练。该方法可以较充分发挥神经网络与专家系统二者优势,进一步提高分词效率。
以上便是对分词算法的基本介绍。
㈥ 部分常用分词工具使用整理
以下分词工具均能在Python环境中直接调用(排名不分先后)。
1、jieba(结巴分词) 免费使用
2、HanLP(汉语言处理包) 免费使用
3、SnowNLP(中文的类库) 免费使用
4、FoolNLTK(中文处理工具包) 免费使用
5、Jiagu(甲骨NLP) 免费使用
6、pyltp(哈工大语言云) 商用需要付费
7、THULAC(清华中文词法分析工具包) 商用需要付费
8、NLPIR(汉语分词系统) 付费使用
1、jieba(结巴分词)
“结巴”中文分词:做最好的 Python 中文分词组件。
项目Github地址:jieba
安装 :
pip install jieba
使用 :
import jieba
jieba.initialize()
text = '化妆和服装'
words = jieba.cut(text)
words = list(words)
print(words)
2、HanLP(汉语言处理包)
HanLP是一系列模型与算法组成的NLP工具包,由大快搜索主导并完全开源,目标是普及自然语言处理在生产环境中的应用。HanLP具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点。
项目Github地址:pyhanlp
安装:
pip install pyhanlp
使用 :
import pyhanlp
text = '化妆和服装'
words = []
for term in pyhanlp.HanLP.segment(text):
words.append(term.word)
print(words)
3、SnowNLP(中文的类库)
SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英文的,于是写了一个方便处理中文的类库,并且和TextBlob不同的是,这里没有用NLTK,所有的算法都是自己实现的,并且自带了一些训练好的字典。
项目Github地址:snownlp
安装:
pip install snownlp
使用:
import snownlp
text = '化妆和服装'
words = snownlp.SnowNLP(text).words
print(words)
4、FoolNLTK(中文处理工具包)
可能不是最快的开源中文分词,但很可能是最准的开源中文分词。
项目Github地址:FoolNLTK
安装:
pip install foolnltk
使用:
import fool
text = '化妆和服装'
words = fool.cut(text)
print(words)
5、Jiagu(甲骨NLP)
基于BiLSTM模型,使用大规模语料训练而成。将提供中文分词、词性标注、命名实体识别、关键词抽取、文本摘要、新词发现等常用自然语言处理功能。参考了各大工具优缺点制作,将Jiagu回馈给大家。
项目Github地址:jiagu
安装:
pip3 install jiagu
使用:
import jiagu
jiagu.init()
text = '化妆和服装'
words = jiagu.seg(text)
print(words)
6、pyltp(哈工大语言云)
pyltp 是 LTP 的 Python 封装,提供了分词,词性标注,命名实体识别,依存句法分析,语义角色标注的功能。
项目Github地址:pyltp,3.4模型下载链接:网盘
安装:
pip install pyltp
使用:
import pyltp
segmentor = pyltp.Segmentor()
segmentor.load('model/ltp_data_v3.4.0/cws.model') # 模型放置的路径
text = '化妆和服装'
words = segmentor.segment(text)
words = list(words)
print(words)
7、THULAC(清华中文词法分析工具包)
THULAC(THU Lexical Analyzer for Chinese)由清华大学自然语言处理与 社会 人文计算实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能。
项目Github地址:THULAC-Python
安装:
pip install thulac
使用:
import thulac
thu = thulac.thulac(seg_only=True)
text = '化妆和服装'
words = thu.cut(text, text=True).split()
print(words)
NLPIR(汉语分词系统)
主要功能包括中文分词;英文分词;词性标注;命名实体识别;新词识别;关键词提取;支持用户专业词典与微博分析。NLPIR系统支持多种编码、多种操作系统、多种开发语言与平台。
项目Github地址:pynlpir
安装:
pip install pynlpir
下载证书覆盖到安装目录,NLPIR.user 例如安装目录:/usr/lib64/python3.4/site-packages/pynlpir/Data
使用 :
import pynlpir
pynlpir.open()
text = '化妆和服装'
words = pynlpir.segment(text, pos_tagging=False)
print(words)
pynlpir.close()
㈦ jieba分词详解
“结巴”分词是一个Python 中文分词组件,参见 https://github.com/fxsjy/jieba
可以对中文文本进行 分词、词性标注、关键词抽取 等功能,并且支持自定义词典。
本文包括以下内容:
1、jieba分词包的 安装
2、jieba分词的 使用教程
3、jieba分词的 工作原理与工作流程
4、jieba分词所涉及到的 HMM、TextRank、TF-IDF等算法介绍
可以直接使用pip来进行安装:
sudo pip install jieba
或者
sudo pip3 install jieba
关键词抽取有两种算法,基于TF-IDF和基于TextRank:
jieba分词有三种不同的分词模式: 精确模式、全模式和搜索引擎模式 :
对应的,函数前加l即是对应得到list结果的函数:
精确模式是最常用的分词方法,全模式会将句子中所有可能的词都列举出来,搜索引擎模式则适用于搜索引擎使用。具体的差别可在下一节工作流程的分析中详述。
在上述每个函数中,都有名为HMM的参数。这一项表示是否在分词过程中利用HMM进行新词发现。关于HMM,本文附录中将简述相关知识。
另外分词支持自定义字典,词典格式和 dict.txt 一样,一个词占一行;每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。
具体使用方法为:
关键词抽取的两个函数的完整参数为:
可以通过
来打开或关闭并行分词功能。
个人感觉一般用不到,大文件分词需要手动实现多进程并行,句子分词也不至于用这个。
jieba分词主要通过词典来进行分词及词性标注,两者使用了一个相同的词典。正因如此,分词的结果优劣将很大程度上取决于词典,虽然使用了HMM来进行新词发现。
jieba分词包整体的工作流程如下图所示:
下面将根据源码详细地分析各个模块的工作流程。
在之后几节中,我们在 蓝色的方框 中示范了关键步骤的输出样例或词典文件的格式样例。在本节中都采用类似的表示方式。
jieba分词中,首先通过对照典生成句子的 有向无环图 ,再根据选择的模式不同,根据词典 寻找最短路径 后对句子进行截取或直接对句子进行截取。对于未登陆词(不在词典中的词)使用 HMM 进行新词发现。
词典的格式应为
word1 freq1 word_type1
word2 freq2 word_type2
…
其中自定义用户词典中词性word_type可以省略。
词典在其他模块的流程中可能也会用到,为方便叙述,后续的流程图中将会省略词典的初始化部分。
图b演示了搜索引擎模式的工作流程,它会在精确模式分词的基础上,将长词再次进行切分。
在这里我们假定读者已经了解HMM相关知识,如果没有可先行阅读下一章内容中的HMM相关部分或者跳过本节。
在jieba分词中,将字在词中的位置B、M、E、S作为隐藏状态,字是观测状态,使用了词典文件分别存储字之间的表现概率矩阵(finalseg/prob_emit.py)、初始概率向量(finalseg/prob_start.py)和转移概率矩阵(finalseg/prob_trans.py)。这就是一个标准的 解码问题 ,根据概率再利用 viterbi算法 对最大可能的隐藏状态进行求解。
词性分析部分与分词模块用了同一个基础的分词器,对于词典词的词性,将直接从词典中提取,但是对于新词,词性分析部分有一个 专属的新词及其词性的发现模块 。
用于词性标注的HMM模型与用于分词的HMM模型相似,同样将文字序列视为可见状态,但是隐藏状态不再是单单的词的位置(B/E/M/S),而变成了词的位置与词性的组合,如(B,v)(B,n)(S,n)等等。因此其初始概率向量、转移概率矩阵和表现概率矩阵和上一节中所用的相比都要庞大的多,但是其本质以及运算步骤都没有变化。
具体的工作流程如下图所示。
jieba分词中有两种不同的用于关键词抽取的算法,分别为TextRank和TF-IDF。实现流程比较简单,其核心在于算法本身。下面简单地画出实现流程,具体的算法可以参阅下一章内容。
TextRank方法默认筛选词性,而TF-IDF方法模型不进行词性筛选。
在本章中,将会简单介绍相关的算法知识,主要包括用于新词发现的 隐马尔科夫模型 和 维特比算法 、用于关键词提取的 TextRank 和 TF-IDF 算法。
HMM即隐马尔科夫模型,是一种基于马尔科夫假设的统计模型。之所以为“隐”,是因为相较于马尔科夫过程HMM有着未知的参数。在世界上,能看到的往往都是表象,而事物的真正状态往往都隐含在表象之下,并且与表象有一定的关联关系。
其中,S、O分别表示状态序列与观测序列。
如果读者还对这部分内容心存疑问,不妨先往下阅读,下面我们将以一个比较简单的例子对HMM及解码算法进行实际说明与演示,在读完下一小节之后再回来看这些式子,或许能够恍然大悟。
下面以一个简单的例子来进行阐述:
假设小明有一个网友小红,小红每天都会在朋友圈说明自己今天做了什么,并且假设其仅受当天天气的影响,而当天的天气也只受前一天天气的影响。
于小明而言,小红每天做了什么是可见状态,而小红那里的天气如何就是隐藏状态,这就构成了一个HMM模型。一个HMM模型需要有五个要素:隐藏状态集、观测集、转移概率、观测概率和初始状态概率。
即在第j个隐藏状态时,表现为i表现状态的概率。式中的n和m表示隐藏状态集和观测集中的数量。
本例中在不同的天气下,小红要做不同事情的概率也不同, 观测概率 以表格的形式呈现如下:
其中
除此之外,还需要一个初始状态概率向量π,它表示了观测开始时,即t=0时,隐藏状态的概率值。本例中我们指定 π={0,0,1} 。
至此,一个完整的 隐马尔科夫模型 已经定义完毕了。
HMM一般由三类问题:
概率计算问题 ,即给定 A,B,π 和隐藏状态序列,计算观测序列的概率;
预测问题 ,也成解码问题,已知 A,B,π 和观测序列,求最优可能对应的状态序列;
学习问题 ,已知观测序列,估计模型的 A,B,π 参数,使得在该模型下观测序列的概率最大,即用极大似然估计的方法估计参数。
在jieba分词中所用的是解码问题,所以此处对预测问题和学习问题不做深入探讨,在下一小节中我们将继续以本节中的例子为例,对解码问题进行求解。
在jieba分词中,采用了HMM进行新词发现,它将每一个字表示为B/M/E/S分别代表出现在词头、词中、词尾以及单字成词。将B/M/E/S作为HMM的隐藏状态,而连续的各个单字作为观测状态,其任务即为利用观测状态预测隐藏状态,并且其模型的 A,B,π 概率已经给出在文件中,所以这是一个标准的解码问题。在jieba分词中采用了 Viterbi算法 来进行求解。
Viterbi算法的基本思想是: 如果最佳路径经过一个点,那么起始点到这个点的路径一定是最短路径,否则用起始点到这点更短的一条路径代替这段,就会得到更短的路径,这显然是矛盾的;从起始点到结束点的路径,必然要经过第n个时刻,假如第n个时刻有k个状态,那么最终路径一定经过起始点到时刻n中k个状态里最短路径的点 。
将时刻t隐藏状态为i所有可能的状态转移路径i1到i2的状态最大值记为
下面我们继续以上一节中的例子来对viterbi算法进行阐述:
小明不知道小红是哪里人,他只能通过小红每天的活动来推断那里的天气。
假设连续三天,小红的活动依次为:“睡觉-打游戏-逛街”,我们将据此计算最有可能的天气情况。
表示第一天为雨天能够使得第二天为晴天的概率最大(也就是说如果第二天是晴天在最短路径上的话,第一天是雨天也一定在最短路径上,参见上文中Viterbi算法的基本思想)
此时已经到了最后的时刻,我们开始回溯。
其计算过程示意图如下图所示。
)的路径。
TF-IDF(词频-逆文本频率)是一种用以评估字词在文档中重要程度的统计方法。它的核心思想是,如果某个词在一篇文章中出现的频率即TF高,并且在其他文档中出现的很少,则认为这个词有很好的类别区分能力。
其中:
TextRank是一种用以关键词提取的算法,因为是基于PageRank的,所以先介绍PageRank。
PageRank通过互联网中的超链接关系确定一个网页的排名,其公式是通过一种投票的思想来设计的:如果我们计算网页A的PageRank值,那么我们需要知道哪些网页链接到A,即首先得到A的入链,然后通过入链给网页A进行投票来计算A的PR值。其公式为:
其中:
d为阻尼系数,取值范围为0-1,代表从一定点指向其他任意点的概率,一般取值0.85。
将上式多次迭代即可直到收敛即可得到结果。
TextRank算法基于PageRank的思想,利用投票机制对文本中重要成分进行排序。如果两个词在一个固定大小的窗口内共同出现过,则认为两个词之间存在连线。
公式与PageRank的基本相同。多次迭代直至收敛,即可得到结果。
在jieba分词中,TextRank设定的词窗口大小为5,将公式1迭代10次的结果作为最终权重的结果,而不一定迭代至收敛。
㈧ 自然语言处理(NLP)的基础难点:分词算法
自然语言处理(NLP,Natural Language Processing)是人工智能领域中的一个重要方向,主要研究人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理的底层任务由易到难大致可以分为词法分析、句法分析和语义分析。分词是词法分析(还包括词性标注和命名实体识别)中最基本的任务,也是众多NLP算法中必不可少的第一步,其切分准确与否往往与整体结果息息相关。
金融领域分词的难点
分词既简单又复杂。简单是因为分词的算法研究已经很成熟了,大部分的算法(如HMM分词、CRF分词)准确率都可以达到95%以上;复杂则是因为剩下的5%很难有突破,主要可以归结于三点:
▲粒度,即切分时的最小单位,不同应用对粒度的要求不一样,比如“融资融券”可以是一个词也可以是两个词
▲歧义,比如“恒生”一词,既可指恒生公司,又可指恒生指数
▲未登录词,即未出现在算法使用的词典中的词,比如不常见的专业金融术语,以及各种上市公司的名称
在金融领域中,分词也具有上述三个难点,并且在未登录词方面的难点更为突出,这是因为金融类词汇本来就多,再加上一些专有名词不仅有全称还有简称,这就进一步增大了难度。
在实际应用中,以上难点时常会造成分词效果欠佳,进而影响之后的任务。尤其是在一些金融业务中,有许多需要与用户交互的场景,某些用户会用口语化的词汇描述业务,如果分词错误会影响用户意图的解析,这对分词的准确性提出了更高的要求。因此在进行NLP上层应用开发时,需要对分词算法有一定的了解,从而在效果优化时有能力对分词器进行调整。接下来,我们介绍几种常用的分词算法及其应用在金融中的优劣。
几种常见的分词算法
分词算法根据其核心思想主要分为两种:
第一种是基于字典的分词,先把句子按照字典切分成词,再寻找词的最佳组合方式,包括最大匹配分词算法、最短路径分词算法、基于N-Gram model的分词算法等;
第二种是基于字的分词,即由字构词,先把句子分成一个个字,再将字组合成词,寻找最优的切分策略,同时也可以转化成序列标注问题,包括生成式模型分词算法、判别式模型分词算法、神经网络分词算法等。
最大匹配分词寻找最优组合的方式是将匹配到的最长词组合在一起,主要的思路是先将词典构造成一棵Trie树(也称为字典树),Trie树由词的公共前缀构成节点,降低了存储空间的同时可以提升查找效率。
最大匹配分词将句子与Trie树进行匹配,在匹配到根结点时由下一个字重新开始进行查找。比如正向(从左至右)匹配“他说的确实在理”,得出的结果为“他/说/的确/实在/理”。如果进行反向最大匹配,则为“他/说/的/确实/在理”。
这种方式虽然可以在O(n)时间对句子进行分词,但是只单向匹配太过绝对,尤其是金融这种词汇较丰富的场景,会出现例如“交易费/用”、“报价单/位”等情况,所以除非某些词的优先级很高,否则要尽量避免使用此算法。
最短路径分词算法首先将一句话中的所有词匹配出来,构成词图(有向无环图DAG),之后寻找从起始点到终点的最短路径作为最佳组合方式,例:
我们认为图中每个词的权重都是相等的,因此每条边的权重都为1。
在求解DAG图的最短路径问题时,总是要利用到一种性质:即两点之间的最短路径也包含了路径上其他顶点间的最短路径。比如S->A->B->E为S到E到最短路径,那S->A->B一定是S到B到最短路径,否则会存在一点C使得d(S->C->B)<d(S->A->B),那S到E的最短路径也会变为S->C->B->E,这就与假设矛盾了。利用上述的最优子结构性质,可以利用贪心算法或动态规划两种求解算法:
(1)基于Dijkstra算法求解最短路径,该算法适用于所有带权有向图,求解源节点到其他所有节点的最短路径,并可以求得全局最优解;
(2)N-最短路径分词算法,该方法是对Dijkstra算法的扩展,在每一步保存最短的N条路径,并记录这些路径上当前节点的前驱,在最后求得最优解时回溯得到最短路径。这种方法的准确率优于Dijkstra算法,但在时间和空间复杂度上都更大。
相较于最大匹配分词算法,最短路径分词算法更加灵活,可以更好地把词典中的词组合起来,能更好地解决有歧义的场景。比如上述“他说的确实在理”这句话,用最短路径算法的计算结果为“他/说/的/确实/在理”,避免了正向最大匹配的错误。但是对于词典中未存在的词基本没有识别能力,无法解决金融领域分词中的“未登录词”难点。
N-Gram(又称N元语法模型)是基于一个假设:第n个词出现与前n-1个词相关,而与其他任何词不相关。在此种假设下,可以简化词的条件概率,进而求解整个句子出现的概率。
现实中,常用词的出现频率或者概率肯定比罕见词要大。因此,可以将求解词图最短路径的问题转化为求解最大概率路径的问题,即分词结果为“最有可能的词的组合“。
计算词出现的概率,仅有词典是不够的,还需要充足的语料,所以分词任务已经从单纯的“算法”上升到了“建模”,即利用统计学方法结合大数据挖掘,对“语言”(句子出现的概率)进行建模。
我们将基于N-gram模型所统计出的概率分布应用到词图中,可以得到词的概率图。对该词图用最短路径分词算法求解最大概率的路径,即可得到分词结果。
相较于前两种分词算法,基于N-Gram model的分词算法对词频进行了统计建模,在切分有歧义的时候力求得到全局最优值,比如在切分方案“证券/自营/业务”和“证券/自/营业/务”中,统计出“证券/自营/业务”出现的概率更大,因此结果有更高的准确率。但也依然无法解决金融场景中未登录词的问题。
生成式模型主要有隐马尔可夫模型(HMM,Hidden Markov Model)、朴素贝叶斯分类等。HMM是常用的分词模型,基于Python的jieba分词器和基于Java的HanLP分词器都使用了HMM。
HMM模型认为在解决序列标注问题时存在两种序列,一种是观测序列,即人们显性观察到的句子,另一种是隐状态序列,即观测序列的标签。假设观测序列为X,隐状态序列是Y,则因果关系为Y->X。因此要得到标注结果Y,必须对X的概率、Y的概率、P(X|Y)进行计算,即建立P(X,Y)的概率分布模型。
HMM算法可以在一定程度上解决未登录词的问题,但生成式模型的准确率往往没有接下来要谈到的判别式模型高。
判别式模型主要有感知机、支持向量机(SVM,Support Vector Machine)、条件随机场(CRF,Conditional Random Field)、最大熵模型等,其中感知机模型和CRF模型是常用的分词模型。
(1)平均感知机分词算法
感知机是一种简单的二分类线性模型,通过构造超平面,将特征空间(输入空间)中的样本分为正负两类。通过组合,感知机也可以处理多分类问题。但由于每次迭代都会更新模型的所有权重,被误分类的样本会造成很大影响,因此采用平均的方法,在处理完一部分样本后对更新的权重进行平均。
(2)CRF分词算法
CRF可以看作一个无向图模型,假设给定的标注序列为Y,观测序列为X,CRF对条件概率P(Y|X)进行定义,而不是对联合概率建模。
平均感知机算法虽然速度快,但仍不够准确。适合一些对速度要求高、对准确性要求相对不那么高的场景。CRF分词算法可以说是目前最常用的分词、词性标注和实体识别算法,它对未登陆词也有很好的识别能力,是目前在速度、准确率以及未登录词识别上综合表现最突出的算法,也是我们目前所采用的解决方案,但速度会比感知机慢一些。
在NLP中,最常用的神经网络为循环神经网络(RNN,Recurrent Neural Network),它在处理变长输入和序列输入问题中有着巨大的优势。LSTM(Long Short-Term Memory,长短期记忆网络)为RNN变种的一种,在一定程度上解决了RNN在训练过程中梯度消失和梯度爆炸的问题。
目前对于序列标注任务,业内公认效果最好的模型是BiLSTM+CRF。相比于上述其它模型,双向循环神经网络BiLSTM,可以更好地编码当前字等上下文信息,并在最终增加CRF层,核心是用Viterbi算法进行解码,以得到全局最优解,避免B,S,E这种不可能的标记结果的出现,提高准确率。
神经网络分词虽然能在准确率、未登录词识别上有更好的表现,但RNN无法并行计算,在速度上没有优势,所以该算法通常在算法研究、句子精确解析等对速度要求不高的场景下使用。
分词作为NLP底层任务之一,既简单又重要,很多时候上层算法的错误都是由分词结果导致的。因此,对于底层实现的算法工程师,不仅需要深入理解分词算法,更需要懂得如何高效地实现和调试。
而对于上层应用的算法工程师,在实际分词时,需要根据业务场景有选择地应用上述算法,比如在搜索引擎对大规模网页进行内容解析时,对分词对速度要求大于精度,而在智能问答中由于句子较短,对分词的精度要求大于速度。
㈨ 在python 环境下,使用结巴分词,自动导入文本,分词,提取关键词.脚本 大侠给个
#-*-coding:UTF-8-*-
importjieba
__author__='lpe234'
seg_list=jieba.cut("我来到北京天安门",cut_all=True)
print','.join(seg_list)
...
Loadingmodelfromcache/var/folders/sv//T/jieba.cache
我,来到,北京,天安,天安门
Loadingmodelcost0.433seconds.
.
Processfinishedwithexitcode0