热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

二阶HMM词性标注

HMM在自然语言处理中十分有用,这里介绍其在词性标注中的应用。首先NLP中需要对数据稀疏问题进行处理,一般包括加一平滑、留存估计、GoodTuring平滑以及线性插值。本文介绍一下GoodT

  HMM在自然语言处理中十分有用,这里介绍其在词性标注中的应用。

  首先NLP中需要对数据稀疏问题进行处理,一般包括加一平滑、留存估计、GoodTuring平滑以及线性插值。本文介绍一下GoodTuring平滑方法,GoodTuring基于的方法是将数据分布看成多项式分布。根据Zif理论,设在语料库中出现r次的词在语料库中共有Nr个,那么r越大,Nr越小,并且两者的乘积大致是一个常数,那么也就是说r*Nr=(r+1)*Nr+1,所以这给我们一个启示可以通过已知事件去估计未知事件,即在语料库中出现0次的词在估计中出现N1/N0次,为了保证估计的准确性,一般只对低频的词进行重新估计。

def good_turing(counts):
N
= sum(counts) # 总的出现次数
prob = [0] * len(counts)

if N == 0:
return prob

Nr
= [0] * (max(counts) + 1) # 出现r次的词个数
for r in counts:
Nr[r]
+= 1

smooth_boundary
= min(len(Nr)-1, 8) # 使用good-turing方法进行平滑
for r in range(smooth_boundary):
if Nr[r] != 0 and Nr[r+1] != 0:
Nr[r]
= (r+1) * Nr[r+1] / Nr[r]
else:
Nr[r]
= r
for r in range(smooth_boundary, len(Nr)):
Nr[r]
= r

for i in range(len(counts)):
prob[i]
= Nr[counts[i]]
total
= sum(prob)
return [p/total for p in prob] # 归一化输出
View Code

  接下来进行的对数据进行训练,计算HMM的参数(发射矩阵和转移矩阵)

def train(self, wrd_path, tag_path):
emission_counts
= defaultdict(int)
trigram_counts
= defaultdict(int)
tags
= set()
words
= set()

wrd_iter
= sent_iterator(corpus_iterator(wrd_path))
tag_iter
= sent_iterator(corpus_iterator(tag_path))

# 统计词频
for (wrd_sent, tag_sent) in zip(wrd_iter, tag_iter):
for (wrd, tag) in zip(wrd_sent, tag_sent):
words.add(wrd)
tags.add(tag)
emission_counts[(wrd, tag)]
+= 1
tag_boundary
= 2 * ['*']
tag_boundary.extend(tag_sent)
tag_boundary.append(
'STOP')
for i in range(len(tag_boundary) - 2):
trigram_counts[tuple(tag_boundary[i:i
+3])] += 1

# 对词语和词性做映射
for tag in tags:
self.tag2num[tag]
= self.ntags
self.num2tag.append(tag)
self.ntags
+= 1
for wrd in words:
self.nwords
+= 1
self.word2num[wrd]
= self.nwords

print(self.ntags, ' ', self.nwords)

# 计算发射矩阵和转移矩阵
nt = self.ntags
nw
= self.nwords
self.em_prob
= [None for i in range(nt)]
self.tr_prob
= [[None for i in range(nt+1)] for j in range(nt+1)]
# 发射矩阵
for i in range(nt):
tag
= self.num2tag[i]
counts
= [0] * (nw+1)
for wrd in words:
counts[self.word2num[wrd]]
= emission_counts[(wrd, tag)]
self.em_prob[i]
= good_turing(counts)
# 转移矩阵(u, v, w)或者(u, v, 'STOP')
for i in range(nt):
u
= self.num2tag[i]
for j in range(nt):
v
= self.num2tag[j]
counts
= [0] * (nt+1)
for w in tags:
counts[self.tag2num[w]]
= trigram_counts[(u, v, w)]
counts[nt]
= trigram_counts[(u, v, 'STOP')]
self.tr_prob[i][j]
= good_turing(counts)
# 转移矩阵(*, v, w)
for j in range(nt):
v
= self.num2tag[j]
counts
= [0] * (nt+1)
for w in tags:
counts[self.tag2num[w]]
= trigram_counts[('*', v, w)]
counts[nt]
= trigram_counts[('*', v, 'STOP')]
self.tr_prob[nt][j]
= good_turing(counts)
# 转移矩阵(*, *, w)
counts = [0] * nt
for w in tags:
counts[self.tag2num[w]]
= trigram_counts[('*', '*', w)]
self.tr_prob[nt][nt]
= good_turing(counts)

  最后利用发射矩阵和转移矩阵预计新句子的词性,使用算法就是经典的Viterbi算法

def viterbi(self, sent):
n
= len(sent)
nt
= self.ntags
y
= [None] * n
path
= [[[0]*nt for i in range(nt)] for j in range(n-1)]
val
= [[[0]*nt for i in range(nt)] for j in range(n-1)]

# 如果句子只有一个单词,则单独处理
if (n == 1):
max_val
= -100000
for v in range(nt):
tmp
= self.tr_prob[nt][nt][v] * self.em_prob[v][self.word2num[sent[0]]] * self.tr_prob[nt][v][nt]
if tmp > max_val:
max_val
= tmp
y[0]
= v
return [self.num2tag[y[0]]]

# 句子开头
for u in range(nt):
for v in range(nt):
val[0][u][v]
= self.tr_prob[nt][nt][u] * self.em_prob[u][self.word2num[sent[0]]] * \
self.tr_prob[nt][u][v]
* self.em_prob[v][self.word2num[sent[1]]]
path[0][u][v]
= -1
# 动态规划求解
for k in range(1, n-1):
for u in range(nt):
for v in range(nt):
max_val
= -100000
best_tag
= -1
for w in range(nt):
tmp
= val[k-1][w][u] * self.tr_prob[w][u][v] * self.em_prob[v][self.word2num[sent[k+1]]]
if tmp > max_val:
max_val
= tmp
best_tag
= w
val[k][u][v]
= max_val
path[k][u][v]
= best_tag
# 结尾
max_val = -100000
for u in range(nt):
for v in range(nt):
tmp
= val[n-2][u][v] * self.tr_prob[u][v][nt]
if tmp > max_val:
max_val
= tmp
y[
-1] = v; y[-2] = u

# 找到最佳标注
for k in range(n-3, -1, -1):
y[k]
= path[k+1][y[k+1]][y[k+2]]

return [self.num2tag[t] for t in y]
View Code

 


推荐阅读
  • 干货 | 携程AI推理性能的自动化优化实践
    作者简介携程度假AI研发团队致力于为携程旅游事业部提供丰富的AI技术产品,其中性能优化组为AI模型提供全方位的优化方案,提升推理性能降低成本࿰ ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • bat大牛带你深度剖析android 十大开源框架_请收好!5大领域,21个必知的机器学习开源工具...
    全文共3744字,预计学习时长7分钟本文将介绍21个你可能没使用过的机器学习开源工具。每个开源工具都为数据科学家处理数据库提供了不同角度。本文将重点介绍五种机器学习的 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 本文介绍了200个经典c语言源代码,包括函数的使用,如sqrt函数、clanguagefunct等。这些源代码可以帮助读者更好地理解c语言的编程方法,并提供了实际应用的示例。 ... [详细]
  • 本文介绍了贝叶斯垃圾邮件分类的机器学习代码,代码来源于https://www.cnblogs.com/huangyc/p/10327209.html,并对代码进行了简介。朴素贝叶斯分类器训练函数包括求p(Ci)和基于词汇表的p(w|Ci)。 ... [详细]
  • oracle安装时找不到启动,Oracle没有开机自启是怎么回事?这一步骤很重要
    重启Oracle数据库重启Oracle数据库包括启动Oracle数据库服务进程和启动Oracle数据库两步,大家继续往下看。按照《【Oracle】什么?作为DBA&# ... [详细]
  • 深度学习与神经网络——邱锡鹏
    深度学习与神经网络——邱锡鹏-一、绪论人工智能的一个子领域神经网络:一种以(人工))神经元为基本单元的模型深度学习:一类机器学习问题,主要解决贡献度分配问题知识结构:路线图:顶 ... [详细]
  • 微服务应用性能分析实战15 数据磐石:APM 收集端的存储模型
    分布式监控的重要设计就是数据存储模型,而SkyWalking的分布式追踪数据模型就是一个经典代表,这也是它会在APM领域脱颖而出的原因。所以今天我就以 ... [详细]
  • 基于神经网络的智能对话系统(二)——机器学习背景知识
    2.机器学习背景知识本章简要回顾了深度学习和强化学习,这些学习与后续章节中的会话AI最相关。2.1机器学习基础Mitchell(1997)将机器学习广义地定义为包括任何计算机程序, ... [详细]
author-avatar
小晶晶妮妮宝贝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有