所谓的短语的语序问题,即给定一个打乱顺序的短语,我们要按照语义信息将其重新组合,新的语序通顺的短语。
  举个简单例子,比如我们在识别验证码中的文字的时候,识别出来的文字分别为“哲”,“思”,“学”,“想”,那么重合调整语序后形成的短语应该为“哲学思想”。
  这样的问题也会经常出现,除了验证码识别,还有语音识别等。解决这类的语序问题,我们通常会用到统计方面的语言模型(Language Model,LM),常见的有N-gram问题等。
  下面将讲述n-gram问题的解决办法。

原理篇

  N-gram模型是一种语言模型,语言模型是一个基于概率的判别模型,它的输入是一句话(单词的顺序序列),输出是这句话的概率,即这些单词的联合概率(joint probability)。
  假设一个句子由n个词组成: S = ( w 1 , w 2 , . . . , w n − 1 , w n ) S=(w_{1}, w_{2}, ...,w_{n-1}, w_{n}) S=(w1​,w2​,...,wn−1​,wn​),如何衡量这些词的联合概率呢?我们不妨假设每一个词语 w i w_{i} wi​都依赖于前 i − 1 i-1 i−1个词语的影响,则联合概率如下:

p ( S ) = p ( w 1 w 2 . . . w n − 1 w n ) = p ( w 1 ) p ( w 2 ∣ w 1 ) . . . p ( w n ∣ w 1 w 2 . . . w n − 1 ) p(S)=p(w_{1}w_{2}...w_{n-1}w_{n})=p(w_{1})p(w_{2}|w_{1})...p(w_{n}|w_{1}w_{2}...w_{n-1}) p(S)=p(w1​w2​...wn−1​wn​)=p(w1​)p(w2​∣w1​)...p(wn​∣w1​w2​...wn−1​)

上述的假设是合情合理的,但实际我们在计算的过程中,会发现参数空间过大和数据稀疏等问题,尤其是 i i i值越大,前 i − 1 i-1 i−1个的组合情况越少,甚至为0。
  为了避免上述问题,我们需要马尔科夫假设,即一个词的出现仅与它之前的N个词有关。如果一个词的出现仅依赖于前一个词,那么为Bi-gram的情形(N=2),公式如下:

p ( S ) = p ( w 1 w 2 . . . w n − 1 w n ) = p ( w 1 ) p ( w 2 ∣ w 1 ) . . . p ( w n ∣ w n − 1 ) p(S)=p(w_{1}w_{2}...w_{n-1}w_{n})=p(w_{1})p(w_{2}|w_{1})...p(w_{n}|w_{n-1}) p(S)=p(w1​w2​...wn−1​wn​)=p(w1​)p(w2​∣w1​)...p(wn​∣wn−1​)

如果一个词的出现仅依赖于前两个词,那么为Tri-gram的情形(N=3),公式如下:

p ( S ) = p ( w 1 w 2 . . . w n − 1 w n ) = p ( w 1 ) p ( w 2 ∣ w 1 ) p ( w 3 ∣ w 2 w 1 ) . . . p ( w n ∣ w n − 1 w n − 2 ) p(S)=p(w_{1}w_{2}...w_{n-1}w_{n})=p(w_{1})p(w_{2}|w_{1})p(w_{3}|w_{2}w_{1})...p(w_{n}|w_{n-1}w_{n-2}) p(S)=p(w1​w2​...wn−1​wn​)=p(w1​)p(w2​∣w1​)p(w3​∣w2​w1​)...p(wn​∣wn−1​wn−2​)

在实际我们计算上述等式最后面的值时,可以用频数来代替(这是根据条件概率得到的),比如:

p ( w n ∣ w n − 1 ) = C ( w n − 1 w n ) / C ( w n − 1 ) p(w_{n}|w_{n-1})=C(w_{n-1}w_{n})/C(w_{n-1}) p(wn​∣wn−1​)=C(wn−1​wn​)/C(wn−1​)

p ( w n ∣ w n − 1 w n − 2 ) = C ( w n − 2 w n − 1 w n ) / C ( w n − 2 w n − 1 ) p(w_{n}|w_{n-1}w_{n-2})=C(w_{n-2}w_{n-1}w_{n})/C(w_{n-2}w_{n-1}) p(wn​∣wn−1​wn−2​)=C(wn−2​wn−1​wn​)/C(wn−2​wn−1​)

其中, C ( w n − 1 w n ) C(w_{n-1}w_{n}) C(wn−1​wn​)表示 w n − 1 w n w_{n-1}w_{n} wn−1​wn​一起在文章中出现的概率,其余类似。

实战篇

  根据上面的原理,我们来解决短语的语序问题。
  首先,我们需要语料,语料就用人民日报的NER语料,前几行如下:

海钓比赛地点在厦门与金门之间的海域。
这座依山傍水的博物馆由国内一流的设计师主持设计,整个建筑群精美而恢宏。
在发达国家,急救保险十分普及,已成为社会保障体系的重要组成部分。
日俄两国国内政局都充满变数,尽管日俄关系目前是历史最佳时期,但其脆弱性不言自明。
克马尔的女儿让娜今年读五年级,她所在的班上有30多名同学,该班的“家委会”由10名家长组成。
  解决短语的语序问题的脚本代码如下:

# -*- coding: utf-8 -*-
# author: Jclian91
# place: Pudong Shanghai
# time: 2020/5/18 4:04 下午
from itertools import permutations
from pprint import pprint
from operator import itemgetter# read corpus data in sentence format
with open("corpus.txt", "r", encoding="utf-8") as f:content = [_.strip() for _ in f.readlines()]# random characters input order
string = "哲学思想"
# string = "景德镇陶瓷"
# string = "突出贡献"
# string = "哈萨克斯坦"
# string = "管理局"
# string = "博物馆"
# string = "北京大学"
# string = "浦东发展银行"
# string = "世界杯决赛"
word_list = set(list(string))
print("模拟输入:", word_list)
candidate_list = list(permutations(word_list, r=len(word_list)))# check if a character in the corpus
for word in word_list:if word not in "".join(content):raise Exception("%s不在语料库中!" % word)# Language Model
word_prob_dict = {}
for candidate in candidate_list:candidate = list(candidate)prob = "".join(content).count(candidate[0])/len("".join(content))# 2-gram# prob = Count(W_{i}W_{i-1})/Count(W_{i-1})for i in range(1, len(candidate)):char_cnt = "".join(content).count(candidate[i-1])word_cnt = "".join(content).count("".join(candidate[i-1:i+1]))prob *= (word_cnt/char_cnt)if prob == 0:breakword_prob_dict["".join(candidate)] = prob# recognize result
# pprint(word_prob_dict)
print("最终输出结果:")
print(sorted(word_prob_dict.items(), key=itemgetter(1), reverse=True)[0])

输出结果如下:

模拟输入: {‘思’, ‘想’, ‘哲’, ‘学’}
最终输出结果:
(‘哲学思想’, 4.851640701745029e-08)

模拟输入: {‘陶’, ‘镇’, ‘德’, ‘瓷’, ‘景’}
最终输出结果:
(‘景德镇陶瓷’, 4.402324066467249e-12)

模拟输入: {‘贡’, ‘出’, ‘突’, ‘献’}
最终输出结果:
(‘突出贡献’, 4.4461494672771407e-07)

模拟输入: {‘坦’, ‘克’, ‘萨’, ‘斯’, ‘哈’}
最终输出结果:
(‘哈萨克斯坦’, 4.65260719191311e-09)

模拟输入: {‘理’, ‘局’, ‘管’}
最终输出结果:
(‘管理局’, 4.5911913512038205e-06)

模拟输入: {‘馆’, ‘物’, ‘博’}
最终输出结果:
(‘博物馆’, 5.9318486186358995e-06)

模拟输入: {‘大’, ‘京’, ‘北’, ‘学’}
最终输出结果:
(‘北京大学’, 3.491890788613219e-06)

模拟输入: {‘银’, ‘行’, ‘发’, ‘东’, ‘浦’, ‘展’}
最终输出结果:
(‘浦东发展银行’, 2.8403362134844498e-11)

模拟输入: {‘决’, ‘世’, ‘界’, ‘杯’, ‘赛’}
最终输出结果:
(‘世界杯决赛’, 6.28999814981479e-07)

总结

  上面的代码只是给出了如何解决短语的语序问题的一个实现思路,实际我们在应用的过程中还需要考虑以下问题:

  • 语料大小,本文示例语料较小,只有3万多句话,语料越大,识别的效果一般也越好;
  • 短语的长度,一般短语越长,识别的时间也越长,如何优化识别算法,从而使得识别时间更短;
  • 平滑处理,本例中不考虑分母为0的情形,实际应用中我们还需要考虑分母为0的情形,此时需要做平滑处理。

  本次分享到此结束,感谢大家的阅读~

NLP(三十一)短语的语序问题相关推荐

  1. 【FastDev4Android框架开发】RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)...

    转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息] ...

  2. Python编程基础:第三十一节 文件读取Read a File

    第三十一节 文件读取Read a File 前言 实践 前言 当我们检测到文件之后就可以读取其中的内容,读取所用到的函数是read(). 实践 我们依然以上一节的lyric.txt为例展示如何读取文件 ...

  3. OpenCV学习笔记(三十一)——让demo在他人电脑跑起来 OpenCV学习笔记(三十二)——制作静态库的demo,没有dll也能hold住 OpenCV学习笔记(三十三)——用haar特征训练自己

    OpenCV学习笔记(三十一)--让demo在他人电脑跑起来 这一节的内容感觉比较土鳖.这从来就是一个老生常谈的问题.学MFC的时候就知道这个事情了,那时候记得老师强调多次,如果写的demo想在人家那 ...

  4. 三十一、Java多线程编程(下篇)

    @Author:Runsen @Date:2019/11/07 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业 ...

  5. FreeSql (三十一)分区分表

    分区 分区就是把一个数据表的文件和索引分散存储在不同的物理文件中.把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,数据库不同实现方式有所不同. 与分表不同,一张大表进行 ...

  6. 第三十一章 考试作弊

    第三十一章 考试作弊 "对了,还有李淳风,把李淳风也一并记录上,并移送官府." "李丽质,你搞错了没有,把我移送官府干什么?我又没参与考试,并且这些都会,我凭什么作弊,我 ...

  7. 【零基础学Java】—Java 日期时间(三十一)

    [零基础学Java]-Java 日期时间(三十一) java.util.Date:表示日期和时间的类 类Date表示特定的瞬间,精确到毫秒 毫秒:千分之一秒,1000毫秒=1秒 特定的时间:一个时间点 ...

  8. JavaScript学习(三十一)—在输入框中如何判断输入的是一个正确的网址

    JavaScript学习(三十一)-在输入框中如何判断输入的是一个正确的网址 function isUrl(url) {const a = document.createElement("a ...

  9. 485串口测试工具软件_探索者 STM32F407 开发板资料连载第三十一章 485 实验

    1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第三十一章 485 实验 ...

最新文章

  1. 那些年,我们一起学过的R语言
  2. mysql组合索引的命中情况
  3. ASP.NET使用母版页后动态加载JS/CSS
  4. Java基础复习-八大基本数据类型-内存模型-基本算法-网络编程
  5. Python3 爬虫学习笔记 C03 【Ajax 数据爬取】
  6. python做视频抽帧图_Python提取视频中图片的示例(按帧、按秒)
  7. 04-07递归解法问题
  8. ZStack CMP多云管理平台有何不同?
  9. 【浙大第19届校赛:B】Even Number Theory (数论n!中有多少个质因子2+java大数)
  10. iOS UDID与UUID
  11. Modbus CRC计算器(编译环境:C-Free 5.0)
  12. 国产FPGA高云GW1NSR-4C,集成ARM Cortex-M3硬核
  13. unity3d学习笔记-动画(2.控制动画与Animator Controller)
  14. 小白兔笑话全集笑死人不偿命(转+转)
  15. [数据分析] RFM分析方法
  16. 复习JavaEE笔记
  17. Tensorboard打开方式
  18. Python 基础之匿名函数 迭代器和高阶函数
  19. 网上python培训骗局-培训三个月拿“高薪”?起底Python“速成班”忽悠大法
  20. 【论文写作】英文论文写作指南

热门文章

  1. ElasticSearch学习(三)-正排索引和倒排索引
  2. php延时5秒显示,在JS/jQuery中如何实现DIV延时几秒后消失或显示
  3. ChatGPT 从入门到精通12:教你如何用AI 五分钟做出一个高大上的PPT
  4. html css hack
  5. 2021年5月15日 星期六 阴霾
  6. Div的宽度与高度的100%设定
  7. pdd为什么下架iPhone12了 拼多多等电商平台不能买iPhone12了?
  8. Ubuntu安卓手机投屏
  9. 酷睿i5 8250u和i5 8265u差距 i58250u和i58265u区别
  10. Mysql中空间扩展 - 查询你附近的餐厅或酒店