中文分词及其应用
Posted 统计家园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中文分词及其应用相关的知识,希望对你有一定的参考价值。
一、中文分词原理
中文分词是指将一个汉字序列切分成一个一个单独的词。分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。现有的分词方法可分为三大类,分别是基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法。
(一)基于字符串匹配的分词方法
基于字符串匹配的分词方法又称机械分词方法,它是按照一定的策略将需要分析的中文字串与一个“充分大的”机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功(识别出一个词)。该类算法的优点是速度快,实现简单,效果尚可,但对歧义和未登录词处理效果不佳。
按照扫描方向的不同,字符串匹配分词方法可以分为正向匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,可以分为单纯分词方法和分词与词性标注相结合的一体化方法。常用的字符串匹配方法主要有四种,分别是正向最大匹配法(从左到右的方向)、逆向最大匹配法(从右到左的方向)、最小切分(每一句中切出的词数最小)、双向最大匹配(进行从左到右、从右到左两次扫描)。
(二)基于理解的分词方法
基于理解的分词方法是通过让计算机模拟人对句子的理解,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法需要使用大量的语言知识和信息。由于中文语言知识的笼统、复杂性,难以将各种语言信息组织成机器可直接读取的形式,因此目前基于理解的分词系统还处在试验阶段。
(三)基于统计的分词方法
基于统计的分词方法是在给定大量已经分词的文本的前提下,利用统计机器学习模型学习词语切分的规律(称为训练),从而实现对未知文本的切分。例如最大概率分词方法和最大熵分词方法等。随着大规模语料库的建立,统计机器学习方法的研究和发展,基于统计的中文分词方法渐渐成为了主流方法,主要的统计模型有:N元文法模型、隐马尔可夫模型、最大熵模型、条件随机场模型等。
在实际的应用中,基于统计的分词系统都需要使用分词词典来进行字符串匹配分词,同时使用统计方法识别一些新词,即将字符串频率统计和字符串匹配结合起来,既发挥匹配分词切分速度快、效率高的特点,又利用了无词典分词结合上下文识别生词、自动消除歧义的优点。
二、中文分词工具
(一)jieba 分词
jieba分词是目前使用人数较多的中文分词工具。jieba分词支持精确模式、全模式、搜索引擎模式这三种模式。精确模式试图将句子最精确地切开,适合文本分析;全模式可以把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;搜索引擎模式是在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。示例代码及结果见图1。
jieba分词过程中主要涉及以下几种算法:(1)基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG);(2)采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合;(3)对于未登录词,采用了基于汉字成词能力的 HMM 模型(隐马尔可夫模型),采用Viterbi算法进行计算;(4)基于Viterbi算法做词性标注;(5)基于tf-idf和textrank模型抽取关键词。
import jieba
# 精准模式
print("|".join(jieba.cut("今天天气不错,我来到北京野生动物园,在野生动物园看到有很多凶猛的动物",cut_all=False)))
# 全模式
print("|".join(jieba.cut("今天天气不错,我来到北京野生动物园,在野生动物园看到有很多凶猛的动物",cut_all=True)))
# 搜索引擎模式
print("|".join(jieba.cut_for_search("今天天气不错,我来到北京野生动物园,在野生动物园看到有很多凶猛的动物")))
图1 jieba分词三种模式结果
(二)jieba分词的应用
1 文本的表示
在对文本进行处理之前,需要对文本进行数学表示,其中一种方法为词向量。基本思路是,在已建立的词库基础上,根据文本中各词汇进行位置判断,最后构成向量表示文本。对文本进行向量表示的前提是对文本进行拆分,因此需要对文本进行中文分词。示例代码及结果见图2。
import jieba
# 词库
word_vector_list = ["我们","来","学习","人工智能","和","Python"]
# 用户输入的语句
s1 = "我来学习Python"
s2 = "我学习人工智能"
# 转化成向量的方法
def get_vector(data):
vector_list = []
for i in word_vector_list:
if i in list(jieba.cut(data)):
vector_list.append(1)
else:
vector_list.append(0)
return vector_list
# 打印向量
print(get_vector(s1))
print(get_vector(s2))
图2 文本的向量表示
2 文本相似度的计算
实现了文本的向量表示后,可以进行文本间距离的计算,即文本相似度计算。在文本相似度的计算中,比较常见的一种相似度计算方式为余弦相似度,余弦相似度的本质是计算两点所构成向量夹角的余弦值,如图3所示。
图3 余弦相似度计算
三、中文分词的应用:简单的聊天机器人开发
通过中文分词以及文本向量表示,可以实现对文本的解析,在此基础上,可进行简单聊天机器人的开发,其程序逻辑为:1数据准备:预先建立fenci.txt文件存储一段文字,通过对文字的分词处理构建语料库;预先建立的content_file.txt文件存储了一些标题和回帖的内容,这些内容是来源于网上的一些帖子内容。我们把title看作是相关的聊天主题,而reply看作是回答的答案。2主程序的构建:a.用户输入一段文本;b.对用户输入的文本进行分词;c.把用户输入的结果与content_file.txt文件中的title字段进行相似度计算,匹配到最为相似的主题;d.以最大相似度主题下的reply内容作为答案进行输出。(fenci.txt文件和content_file.txt文件部分内容展示见图4、图5)具体代码如下:
图4 fenci.txt文件部分内容
图5 content_file.txt文件部分内容
f1 = open("D:\软件\PyCharm Community Edition 2020.1.2\项目\项目\projects-ch2-chatbot\夸夸机器人\\fenci.txt",encoding='utf-8')
f2 = open("fenci_res.txt",'a',encoding='utf-8')
lines = f1.readlines()
for line in lines:
line.replace("\t","").replace("\n","").replace(" ","").replace("!","").replace("\r","")
line = re.sub(r"[0-9\s+_,$%^*()?;;:-【】\"\'\/\s\,\.\~]+|[+—!,;:。?、~@#¥%…&*()]+","",line)
seg_list = jieba.cut(line)
# for i in seg_list:
# #print(i)
# word_list.append(i)
f2.write(" ".join(seg_list))
f1.close()
f2.close()
# print(word_list)
sentences = word2vec.Text8Corpus("fenci_res.txt")
model = word2vec.Word2Vec(sentences)
model.save("word2vec.model")
model = word2vec.Word2Vec.load("word2vec.model")
while True:
word_list = []
words = input("输入>>")
words =re.sub(r"[0-9\s+_,$%^*()?;;:-【】\"\'\/\s\,\.\~]+|[+—!,;:。?、~@#¥%…&*()]+","",words)
if words == "再见":
print("再见!")
break
words_gen = jieba.cut(words)
for i in words_gen:
word_list.append(i)
#print(word_list)
file = open("content_file.txt",encoding='utf-8')
answers = json.load(file)
max_similarity = 0
max_title = ''
max_answer = []
for line in answers:
answer_list = []
answer = jieba.cut(line['title'])
for i in answer:
answer_list.append(i)
try:
similarity = model.wv.n_similarity(word_list,answer_list)
except:
continue
if similarity >= max_similarity:
max_similarity = similarity
max_title = line['title']
max_answer = line['reply']
if max_title != '':
print("最相似的问题为:{0},相似度为{1}".format(max_title,max_similarity))
index = random.randint(0,len(max_answer)-1)
choosed_answer = max_answer[index]
print(choosed_answer)
else:
print("未找到合适的答案")
以上是关于中文分词及其应用的主要内容,如果未能解决你的问题,请参考以下文章