jieba库头歌学习总结
基于jieba的中文分词
jieba的特点
-
社区活跃
-
功能丰富
-
提供多种编程语言实现
-
使用简单
jieba分词原理
结合了基于规则和基于统计这两类方法。首先基于前缀词典进行词图扫描,前缀词典是指词典中的词按照前缀包含的顺序排列。如果将词看作节点,词和词之间的分词符看作边,那么一种分词方案则对应着从第一个字到最后一个字的一条分词路径。
jieba分词的三种模式
精确模式:试图将句子最精确地切开,适合文本分析;
jieba.cut(sentence, cut_all=False)
全模式:把句子中所有可以成词的词语都扫描出来,速度非常快,但是不能解决歧义;
jieba.cut(sentence, cut_all=True)
搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
jieba.cut_for_search(sentence)
词频统计算法
import jieba
text= input()
words = jieba.lcut(text)
data={} # 词典
for word in words:
if len(word) < 2: # 判断word是否大于2个字,构成一个词
continue
if word in data:
data[word] += 1 # word再次出现
else:
data[word] = 1 # word首次出现
data = sorted(data.items(), key=lambda x: x[1], reverse=True) # 排序
print(data[:3],end="")
规则分词法
正向最大匹配法(MM法)
算法过程
从左向右取待切分汉语句的 m 个字符作为匹配字段, m 是机器词典中最长词条的字符数;查找机器词典并进行匹配。匹配成功则将匹配字段作为一个词切分出来,匹配失败则将匹配字段的最后一个字去掉,剩下的字符串作为新的匹配字段,进行再匹配,一直重复上述过程直到切分出所有词。
文字示例
我们现有的分词词典中最长的长度为5,词典中有南京市、长江、大桥三词,现采用 MM 法对句子南京市长江大桥进行分词,那么首先从句子中取出前5个字南京市长江,发现词典中没有该词,于是缩小长度,取前4个字南京市长,发现词典中还是没有该词,于是继续缩小长度,取前3个字南京市,词典中存在该词,于是该词被确认切分。再将剩下的长江大桥按照同样方式进行切分,得到长江和大桥,最终切分为南京市/长江/大桥3个词。
逆向最大匹配法(RMM法)
算法过程
逆向最大匹配( RMM 法)法的基本思想与 MM 法相同,不同的是分词切分的方向与 MM 法相反。逆向最大匹配法从右到左来进行切分。每次取最右边(末端)的 m 个字符作为匹配字段, 若匹配失败,则去掉匹配字段最左边(前面)的一个字,继续匹配。
文字示例
南京市长江大桥,按照逆向最大匹配,分词词典中最长词条的字符数长度为5,分词词典中有南京市长和长江大桥两词,现采用 RMM 法对句子南京市长江大桥进行分词,那么首先从句子中从右到左取出前5个字市长江大桥,发现词典中没有该词,于是缩小长度,取前4个字长江大桥,词典中存在该词,于是该词被确认切分。再将剩下的南京市按照同样方式进行切分,得到南京市,最终切分为南京市/长江大桥2个词。当然,如此切分并不代表完全正确,可能有个叫江大桥的南京市长也说不定。
双向最大匹配法
算法过程
比较正向最大匹配和逆向最大匹配结果;
如果分词数量结果不同,那么取分词数量较少的那个;
在分词数量结果相同的情况下,如果分词结果相同,则可以返回任何一个;如果分词结果不同,则返回单字数比较少的那个。
文字示例
北京大学生前来应聘这个句子,如果通过正向最大匹配算法得到的结果为北京大学 / 生前 / 来 / 应聘,其中分词数量为4,单字数为 1;而通过逆向最大匹配算法所得到的结果为北京/ 大学生/ 前来 / 应聘,其中分词数量为4,单字数为0。则根据双向最大匹配算法,逆向匹配单字数少,因此返回逆向匹配的结果。
代码实现
class BiMM():
def __init__(self):
self.window_size = 3 # 字典中最长词数
def MMseg(self, text, dict): # 正向最大匹配算法
result = []
index = 0
text_length = len(text)
while text_length > index:
for size in range(self.window_size + index, index, -1):
piece = text[index:size]
if piece in dict:
index = size - 1
break
index += 1
result.append(piece)
return result
def RMMseg(self, text, dict): # 逆向最大匹配算法
result = []
index = len(text)
while index > 0:
for size in range(index - self.window_size, index):
piece = text[size:index]
if piece in dict:
index = size + 1
break
index = index - 1
result.append(piece)
result.reverse()
return result
def main(self, text, r1, r2):
# 任务:完成双向最大匹配算法的代码描述
# 分词数量若不同,则选取少的那个
if len(r1) < len(r2):
print(r1)
elif len(r1) > len(r2):
print(r2)
# 分词数量若相同
else:
# 判断分词元素是否一致
if set(sorted(r1)) != set(sorted(r2)): # 若不一致,判断单字分词个数
count1 = sum(1 for i in r1 if len(i) == 1)
count2 = sum(1 for j in r2 if len(j) == 1)
print(r1) if count1 < count2 else print(r2)
else:
print(r1)
词性标注
什么是词性标注?
词性标注(Part-of-Speech Tagging,简称POS Tagging)是自然语言处理(NLP)中的一种技术,它将每个单词标注为相应的词性(如名词、动词、形容词等),以明确其在句子中的语法功能。
词性标注的目的在于为文本的进一步处理奠定基础,帮助理解句子的结构、解析语法,或者为机器翻译、文本摘要等高级任务提供信息。
调用方法
import jieba.posseg as peg # jieba库中词性分析模块
peg.cut('sentence')
运行逻辑
首先基于正则表达式进行汉字判断;
若符合汉字正则表达式,则基于前缀词典构建有向无环图,再基于有向无环图计算最大概率路径,同时在前缀词典中找出它所分出的词性,若在词典中未找到,则赋予词性为 x (代表未知)。当然,若在这个过程中,设置使用 HMM ,且待标注词为未登录词,则会通过 HMM 方式进行词性标注;
若不符合上面的正则表达式,那么将继续通过正则表达式进行类型判断,分别赋予 x 、 m (数词)和 eng (英文)。
代码示例
import jieba.posseg as peg # jieba库中词性分析模块
text = input()
def cut_words():
words = psg.cut(text)
for word, flag in words:
print(word + "/" + flag, end=" ")
命名实体识别
什么是命名实体识别?
命名实体识别(Named Entity Recognition,简称NER)是自然语言处理(NLP)中的一项核心任务,旨在从文本中识别出具有特定意义的实体,并将它们分类为预定义的类别。
NER的目标是在给定的文本中找出这些实体,并将它们标注为相应的类别。例如,句子“乔布斯于2004年创立了苹果公司”中的“乔布斯”是人名,“苹果公司”是组织名,“2004年”是时间。
调用方法
Python的第三方库HanLP——一系列模型与算法组成的工具包,目标是普及自然语言处理在生产环境中的应用。
安装方法
pip install pyhanlp
from pyhanlp import HanLP # 使用前导入 HanLP工具
识别逻辑
基于HMM 算法对人名进行识别
代码示例
from pyhanlp import HanLP
text = input()
# 任务:完成对 text 文本的人名识别并输出结果
segment = HanLP.newSegment().enableNameRecognize(True); # 构建人名识别器
# segment = HanLP.newSegment().enablePlaceRecognize(True); # 构建地名识别器
result = segment.seg(text)
print(result)