1 文本分析的基本过程

分词就是中学学的断句:

举个例子来说明:假设我们输入一句话:北京欢迎你。则有可能的断句为:

北,京,欢,迎,你

北京,欢,迎,你

北京,欢迎,你  等等如果没有语料库的话就是这样的枚举。

分词我们可以根据语料库里面的次来分,比如语料库里面有[北京,欢迎,你,欢,迎]则上面列出的就是我们可能的分词结果用程序来是实现就是

需要的语料库:

https://github.com/liangqi/chinese-frequency-word-list

给出了每个词出现的概率。相当于建立unigram模型代码如下

from collections import Counter
import random
import numpy as np
with open('./data/现代汉语常用词表.txt') as f:lines = f.readlines()
sum = 0
word_prob = Counter()
for line in lines:columns = line.strip().split()# 重复词频率直接相加,(相同词多次出现是因为发音不同,即语义也不同,这里不做区分)word_prob[columns[0]] += int(columns[-1])sum += int(columns[-1])
# 频率转为概率
for word in word_prob:word_prob[word] /= sum

这段代码的功能是读取语料库中的单词,并统计每个词出现的概率,我们可以去测试一下。

print([{word: word_prob[word]} for word in random.sample(word_prob.keys(), 2)])
print("词典大小:%d" % len(word_prob))
print(np.sum(list(word_prob.values())))

成功读取语料库并计算出每个词的概率后,我们可以开始基于每个词的概率开始进行分割。代码如下

def sentence_break(str):"""求该句话在当前词典下的全切分。思路:状态转移,设M[i]是从句子开始到第i个字所组成句的全切分,word是以字i结尾的可在词典中找到的词,则M[i] = M[i-len(word)] + wordstr: 字符串,传入的句子"""# 存储状态memory = [[] for _ in range(len(str))]for i in range(0, len(str)):for j in range(0, i+1):# 从开始到当前cursor视为一个词if j == 0:if str[j:i+1] in word_prob:memory[i].append([str[j:i+1]])continue# 确定依赖的之前状态存在且(达成转移条件:词存在)if memory[j-1] and str[j:i+1] in word_prob:# 状态转移过程for state in memory[j-1]:memory[i].append(state + [str[j:i+1]])return memory[-1]

测试

print(sentence_break("北京欢迎你"))

计算每一句话出现的概率,并返回最大概率的一句话

## TODO 编写word_segment_naive函数来实现对输入字符串的分词
import mathdef word_segment_naive(input_str):"""1. 对于输入字符串做分词,并返回所有可行的分词之后的结果。2. 针对于每一个返回结果,计算句子的概率3. 返回概率最高的最作为最后结果input_str: 输入字符串   输入格式:“今天天气好”best_segment: 最好的分词结果  输出格式:["今天","天气","好"]"""# TODO: 第一步: 计算所有可能的分词结果,要保证每个分完的词存在于词典里,这个结果有可能会非常多。 segments = sentence_break(input_str)  # 存储所有分词的结果。如果次字符串不可能被完全切分,则返回空列表(list)# 格式为:segments = [["今天",“天气”,“好”],["今天",“天“,”气”,“好”],["今“,”天",“天气”,“好”],...]# TODO: 第二步:循环所有的分词结果,并计算出概率最高的分词结果,并返回best_segment = list()best_score = 0for seg in segments:# TODO ...if seg:score = 0for word in seg:# 防止下溢,取logscore += math.log(word_prob[word])if best_score == 0:best_segment = segbest_score = scoreelse:if score > best_score:best_segment = segbest_score = scorereturn best_segment

因为上面的分词和计算概率分开进行,我们可以通过建立一个有向无环图来实现同时进行(维特比算法)

## TODO 编写word_segment_viterbi函数来实现对输入字符串的分词
import mathdef word_segment_viterbi(input_str):"""1. 基于输入字符串,词典,以及给定的unigram概率来创建DAG(有向图)。2. 编写维特比算法来寻找最优的PATH3. 返回分词结果input_str: 输入字符串   输入格式:“今天天气好”best_segment: 最好的分词结果  输出格式:["今天","天气","好"]"""# TODO: 第一步:根据词典,输入的句子,以及给定的unigram概率来创建带权重的有向图(Directed Graph)#      有向图的每一条边是一个单词的概率(只要存在于词典里的都可以作为一个合法的单词),这些概率在 word_prob,如果不在word_prob里的单词但在#      词典里存在的,统一用概率值1e-100。# 图是为了直观起见,边表示字或词及其概率,节点存储状态,图有没有其实无所谓,从本质上讲其实就是个状态转移算法# 每个节点的状态包含-log(P)和当前最优切分memory = [[0, []] for _ in range(len(input_str)+1)]# TODO: 第二步: 利用维特比算法来找出最好的PATH, 这个PATH是P(sentence)最大或者 -log P(sentence)最小的PATH。# TODO: 第三步: 根据最好的PATH, 返回最好的切分for i in range(1, len(input_str)+1):for j in range(i):# 这里偷个懒,默认没有形成词的单字可以在词典中找到(如果不成立事实上会返回完整句子,因为-log(1e-100)必然小于该值加某个非负数word = input_str[j:i]prob = word_prob[word] if word in word_prob else 1e-100score = memory[j][0] - math.log(prob)# 状态更新if memory[i][0] == 0:memory[i][0] = scorememory[i][1] = memory[j][1] + [word]else:if score < memory[i][0]:memory[i][0] = scorememory[i][1] = memory[j][1] + [word]return memory[-1][1]

目前比较流行的中文分词工具

jieba:做最好的 Python 中文分词组件https://github.com/fxsjy/jieba
清华大学THULAC:一个高效的中文词法分析工具包
中科院计算所NLPIR
哈工大LTP
FoolNLTK可能不是最快的开源中文分词,但很可能是最准的开源中文分词
参考资料:https://zhuanlan.zhihu.com/p/95599399

零基础入门NLP之搭建中文分词工具相关推荐

  1. Task01——零基础入门NLP - 新闻文本分类之赛题理解

    本篇目标 首先本篇文章会对赛题进行介绍以及个人对赛题的理解,带大家接触NLP的预处理.模型构建和模型训练等知识点. 赛题介绍 赛题名称:零基础入门NLP - 新闻文本分类 赛题任务:赛题以自然语言处理 ...

  2. 零基础入门NLP - 天池新闻文本分类Task3笔记

    零基础入门NLP - 天池新闻文本分类 以下以Datawhale与天池举办的新闻文本分类这个NLP赛题做的NLP入门Task2笔记 赛题链接:https://tianchi.aliyun.com/co ...

  3. 零基础入门NLP之新闻文本分类挑战赛——赛题理解

    假期还有两周左右就结束了,正巧,Datawhale联合天池发布了零基础入门NLP的学习,于是报名参加了零基础入门NLP-新闻文本分类. 本人之前刚接触NLP没多久,记录一下学习的历程,供和我一样的小白 ...

  4. 天池零基础入门NLP竞赛实战:Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类

    Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类 因为天池这个比赛的数据集是脱敏的,无法利用其它已经预训练好的模型,所以需要针对这个数据集自己从头预训练一个模型. 我们利用H ...

  5. 零基础入门NLP - 新闻文本分类

    本文是对阿里云新人竞赛中的"零基础入门NLP - 新闻文本分类"解体过程进行的记录,目前仅使用了textCNN模型进行预测,后续还会考虑使用LSTM进行对比. 赛题数据 赛题以新闻 ...

  6. 零基础入门NLP - 新闻文本分类,正式赛第一名方案分享

    零基础入门NLP - 新闻文本分类,正式赛第一名方案分享:https://mp.weixin.qq.com/s/7WpZUqdlItBToLYuRLm44g

  7. 【初学者入门】零基础入门NLP - 新闻文本分类

    序言 从今天开始入门学习NLP,虽然有点晚,但是我觉得任何时候都值得开始,尤其是面对你去感兴趣的事情.今天的任务是 [零基础入门NLP - 新闻文本分类],这是天池大赛中的入门级算法比赛,入口链接请自 ...

  8. 天池零基础入门NLP - 新闻文本分类Top1方案的bert4torch复现

    天池有些长期比赛可以练习玩玩(还可以继续提交),于是试了下简单的新闻文本分类任务,Top1的解决方案思路是"预训练+fgm+交叉验证模型融合",代码是基于bert4keras的,本 ...

  9. NLP笔记:中文分词工具简介

    中文分词工具简介 0. 引言 1. jieba分词 1. jieba分词的基本用法 2. jieba分词的进阶版用法 1. 全模式的分词 2. 自定义领域词表加入 3. 使用jieba进行关键词抽取 ...

最新文章

  1. 组策略(八)使用使用自定义RealVNC adm模板对域内工作站设置统一标准设置
  2. 11g内存管理新特性的internal表现
  3. 格式化json_在Spring Boot中格式化JSON日期
  4. python和java二选一该学啥_Python和Java二选一该学啥?
  5. c和python的区别动图_C语言与Python 对程序员的差别到底在哪?
  6. 校门外的树——树状数组+区间修改
  7. Quartz.NET快速入门指南
  8. 95-290-340-源码-内存管理-Buffer-ByteBuffer简介
  9. 你三十岁有什么巨大变化吗?
  10. IIS 7 启用 gzip 静态压缩 压缩js和css文件
  11. string.Empty与,null的区别
  12. 电脑连上网,可是软件、谷歌等浏览器都显示未连接到互联网。远程计算机设备将不受连接,两个解决方法。
  13. QQ微云图标升级方法 空间免费扩容攻略
  14. 编辑器,编译器与集成开发环境(IDE)
  15. 当WebRTC Pion示例无音频流的时候,如何添加音频模块并通过浏览器播放?
  16. 关于element的日历组件改造为考勤页面
  17. 算法 | 03 字符串(KMP)
  18. 平行四边形符号怎么打?
  19. 基于遗传算法的大规模工程优化设计方法初探
  20. 12家大厂软件测试大牛,联合打造:<如何从零开始学习软件测试>系列视频+完整版文档分享

热门文章

  1. how to covid free at cambridge?
  2. 唐人街探案3观后感:大四学生的看法
  3. Optimizing graphics performance
  4. C++学习札记(2011-09-30)
  5. 从CES 2017看今年智能汽车发展趋势之三:智能座舱异军突起
  6. shell,自动挂载磁盘
  7. AIX Study之--AIX网卡配置管理(ent0、en0、et0)
  8. 基于Web的质量和测试度量指标
  9. JUnit的各种断言
  10. 理解SharePoint中的Managed Path