N元语言模型

第1关:预测句子概率

任务描述

本关任务:利用二元语言模型计算句子的概率

相关知识

为了完成本关任务,你需要掌握:1.条件概率计算方式。 2.二元语言模型相关知识。

条件概率计算公式

条件概率是指事件A在事件B发生的条件下发生的概率。条件概率表示为:P(A|B)。若只有两个事件A,B,则有如下公式:

,

二元语言模型

二元语言模型也称为一节马尔科夫链,通俗的讲,我们可以认为这是一个词的概率实际上只是跟前边的词有关,那么就可以有以下的方程:

,

同时为了保证条件概率在 i=1 时有意义,同时为了保证句子内所有字符串的概率和为 1,可以在句子首尾两端增加两个标志: <BOS \W1W2…Wn\ EOS> 为了估计P(WI|WI-1)的条件概率,我们计算出wi-1,wi的词汇出此案的频率然后进行归一化,公式如下:

,

计算出每个词汇的概率后,便可根据公式求得句子的概率。

编程要求

根据提示,在右侧编辑器补充代码,计算并输出测试语句的概率

测试说明

平台会对你编写的代码进行测试: 语料库:

 
  1. 研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生。

测试输入:

  1. 研究生物专业是他的首选目标

预期输出:

  1. 0.004629629629629629
import jieba
 
jieba.setLogLevel(jieba.logging.INFO)
 
# 将句子变为"BOSxxxxxEOS"这种形式
def reform(sentence):
    if sentence.endswith("。"):
        sentence = sentence[:-1]
    sentence = sentence.replace("。", "EOSBOS")
    sentence = "BOS" + sentence + "EOS"
    return sentence
 
# 分词并统计词频
def segmentation(sentence, dic):
    jieba.suggest_freq("BOS", True)
    jieba.suggest_freq("EOS", True)  # 让jieba库知道"BOS"和"EOS"这两个词的存在,并记录它们的出现频率
    lists = jieba.lcut(sentence, HMM=False) # 当输入的文本比较短时,隐马尔科夫模型的效果可能会下降,导致分词结果不准确
    if dic is not None:
        for word in lists:
            if word not in dic:
                dic[word] = 1
            else:
                dic[word] += 1
    return lists
 
# 比较两个数列,二元语法
def compareList(ori_list, tes_list):
    count_list = [0] * len(tes_list)
    for t in range(len(tes_list)-1):
        for n in range(len(ori_list)-1):
            if tes_list[t] == ori_list[n]:
                if tes_list[t+1] == ori_list[n+1]:
                    count_list[t] += 1
    return count_list 
      
 
# 计算概率       
def probability(tes_list, ori_dic, count_list):
    flag = 0
    p = 1
    del tes_list[-1]
    for key in tes_list:
        p *= float(count_list[flag]) / float(ori_dic[key])
        flag += 1
    return p
 
if __name__ == "__main__":
    # 语料句子
    sentence_ori = "研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生。"
    ori_dict = {}
    
    # 测试句子
    sentence_test = input()
    ori_dict2 = {}
 
    sentence_ori_temp = reform(sentence_ori)
    ori_list = segmentation(sentence_ori_temp, ori_dict)
 
    sentence_tes_temp = reform(sentence_test)
    tes_list = segmentation(sentence_tes_temp, None)
 
    count_list = compareList(ori_list, tes_list)
 
    p = probability(tes_list, ori_dict, count_list)
    print(p)

第2关:数据平滑

任务描述

本关任务:实现二元语言模型的数据平滑,并利用平滑后的数据计算句子概率。

相关知识

为了完成本关任务,你需要掌握:1.模型平滑化。2.good-turning平滑。

模型平滑

在使用语言模型直接计算某个句子出现的概率时,可能会由于某个单词或单词对出现的概率为0而导致整个句子出现的概率为0。 例如下面这个场景:

例子

在上面的场景中,由于部分单词对出现的概率为0,导致最终两句话出现的概率均为0。但实际上,s1=“今天没有训练营”比s2=“今天训练营没有”更符合语法习惯,我们也更希望计算出来的P(s1)大于P(s2)。 一般来说,语言模型的平滑处理可分为以下三类:

  • Discounting(折扣):通过给概率不为0的项打折扣,来提高概率为0的项的概率;
  • Interpolation(插值):在使用N-gram模型计算某一项的概率时,同时结合低阶的模型所计算出的概率;
  • Back‐off:approximate counts of unobserved N‐gram based on the proportion of back‐off events (e.g., N‐1 gram)。

这里我们主要介绍与使用Discounting中的good-turning平滑方法。

good-turning平滑

Good-Turing技术是在1953年由古德(I.J.Good)引用图灵(Turing)的方法而提出来的,其基本思想是:用观察计数较高的N元语法数重新估计概率量的大小,并把它指派给那些具有零计数或者较低计数的N元语法。涉及的符号含义为:
c:某个N元语法出现的频数。
Nc:出现次数为c的 N-gram 词组的个数,是频数的频数

,

c*:Good-Turing平滑计数

,

设N为测试元组集合中元组的数目,则有如下公式:

,

通过新频数可计算出经过good-turing平滑后的元组概率,公式如下:

,

编程要求

根据提示,在右侧编辑器补充代码,编写平滑函数,计算句子的概率

测试说明

平台会对你编写的代码进行测试:

语料库:

  1. 研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生。

测试输入:

  1. 他是研究物理的

预期输出:

  1. 5.6888888888888895e-05

import jieba
#语料句子
sentence_ori="研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生。"
#测试句子
sentence_test=input()
#任务:编写平滑函数完成数据平滑,利用平滑数据完成对2-gram模型的建立,计算测试句子概率并输出结果
# ********** Begin *********#
def gt(N, c):
    if c+1 not in N:
        cx = c+1
    else:
        cx = (c+1) * N[c+1]/N[c]
    return cx
jieba.setLogLevel(jieba.logging.INFO)
sentence_ori = sentence_ori[:-1]
words = jieba.lcut(sentence_ori)
words.insert(0, "BOS")
words.append("EOS")
i = 0
lengh = len(words)
while i < lengh:
    if words[i] == "。":
        words[i] = "BOS"
        words.insert(i, "EOS")
        i += 1
        lengh += 1
    i += 1
phrases = []
for i in range(len(words)-1):
    phrases.append(words[i]+words[i+1])
phrasedict = {}
for phrase in phrases:
    if phrase not in phrasedict:
        phrasedict[phrase] = 1
    else:
        phrasedict[phrase] += 1
words_test = jieba.lcut(sentence_test)
words_test.insert(0, "BOS")
words_test.append("EOS")
phrases_test = []
for i in range(len(words_test)-1):
    phrases_test.append(words_test[i]+words_test[i+1])
pdict = {}
for phrase in phrases_test:
    if phrase not in phrasedict:
        pdict[phrase] = 0
    else:
        pdict[phrase] = phrasedict[phrase]
N = {}
for i in pdict:
    if pdict[i] not in N:
        N[pdict[i]] = 1
    else:
        N[pdict[i]] += 1
N[0] += 1
Nnum = 0
for i in N:
    Nnum += i*N[i]
p = 1
for phrase in phrases_test:
    c = pdict[phrase]
    cx = gt(N, c)
    p *= cx/Nnum
print(p)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/556281.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第36题有效的数独

题目&#xff1a; 题解&#xff1a; func isValidSudoku(board [][]byte) bool {var rows, columns [9][9]intvar subboxes [3][3][9]intfor i, row : range board {for j, c : range row {if c . {continue}index : c - 1rows[i][index]columns[j][index]subboxes[i/3][j/3]…

【每日一题】2007. 从双倍数组中还原原数组-2024.4.18

题目&#xff1a; 2007. 从双倍数组中还原原数组 一个整数数组 original 可以转变成一个 双倍 数组 changed &#xff0c;转变方式为将 original 中每个元素 值乘以 2 加入数组中&#xff0c;然后将所有元素 随机打乱 。 给你一个数组 changed &#xff0c;如果 change 是 双…

如何获得合适的助听器?

要获得一个合适的助听器&#xff0c;您可以按照以下步骤进行&#xff1a; 1. 咨询专业医生或听力专家&#xff1a;首先&#xff0c;建议您咨询专业的耳鼻喉科医生或听力专家。他们可以通过听力测试来评估您的听力损失程度和类型&#xff0c;并为您提供个性化的建议。 2. 选择信…

DevOps是什么?

DevOps是一系列实践、工具和文化理念的组合&#xff0c;旨在自动化并整合软件开发和信息技术运维团队之间的流程。以下是DevOps的几个关键点&#xff1a; 沟通与协作&#xff1a;DevOps强调开发和运维团队之间的沟通与合作&#xff0c;通过改善这两个部门间的协作关系&#xff…

Labview2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 LabVIEW是一种由美国国家仪器&#xff08;NI&#xff09;公司开发的程序开发环境&#xff0c;它显著区别于其他计算机语言&#xff0c;如C和BASIC。传统的计算机语言是基于文本的语言来产生代码&#xff0c;而LabVIEW则采用图形化…

JavaEE:File类查询一个文件的路径(举例+源码 )

一、File类概述 Java 中通过 java.io.File 类来对一个文件&#xff08;包括目录&#xff09;进行抽象的描述。File 类中的方法可以对文件路径以及文件名等信息进行查询&#xff0c;也可以对文件进行各项增删改操作&#xff0c;本文主要介绍 File 类的查询方法。 二、代码示例 …

计算机系统基础知识总结

一、计算机系统概述 计算系统可以分为硬件和软件两部分。硬件主要有中央处理器、存储器、输入和输出设备组成&#xff1b;软件由系统软件和应用软件组成。 冯诺依曼计算机体系&#xff1a;将硬件划分为&#xff1a;输入、输出、运算器、存储器、控制器五部分。 中央处理器&…

【WP】猿人学4 雪碧图、样式干扰

https://match.yuanrenxue.cn/match/4 探索 首先打开Fiddler&#xff0c;发现每个包的除了page参数一样&#xff0c;然后重放攻击可以实现&#xff0c;尝试py复现 Python可以正常拿到数据&#xff0c;这题不考请求&#xff0c;这题的难点原来在于数据的加密&#xff0c;这些数字…

什么是301重定向,什么时候应该使用?301重定向详细说明

如果您将网站从一个URL移动到另一个URL&#xff0c;您需要采取必要的步骤来确保您的访问者被发送到正确的位置。在技术领域&#xff0c;这被称为301重定向。 在这里&#xff0c;我们将讨论什么是301重定向&#xff0c;何时需要使用&#xff0c;以及如何在网站或WordPress中重定…

网络流的C++代码实现与过程讲解

网络流是一种非常重要的图论算法,它在许多实际问题中得到广泛应用。本文将介绍网络流算法的C++代码实现与过程讲解。 算法概述 网络流算法是通过将图中的边看作流量通道,将图的点看作流量的起点或终点,来求解图中的最大或最小流量的问题。它是一种非常重要的最优化算法,广…

闲谈跨部门工作

先附上一张网络流传的IT职场江湖图 然后再来探讨一下在工作中如何跨部门沟通&#xff0c;作为一个团队leader&#xff0c;或者团队的核心开发人员&#xff0c;如何有效的跨部门沟通。 在当今快节奏的软件开发行业中&#xff0c;一个公司的组织架构必然是多样化的&#xff0c;多…

15个真正免费的Mac数据恢复软件

由于不同的情况&#xff0c;从Mac或其他存储设备丢失重要文件对我们来说确实是一个巨大的痛苦&#xff0c;但没有人可以避免。现在&#xff0c;您丢失了宝贵的数据&#xff0c;如何找回它&#xff1f; 如果您始终备份数据&#xff0c;则可以从 Time Machine 或其他备份位置恢复…

邮箱签名有什么用?管理员怎么统一设置邮箱签名?

电子邮箱签名能够为个人随意设置&#xff0c;但对企业来说&#xff0c;职工签名代表企业形象&#xff0c;好的公司签名能够反映企业标准化和统一。那样&#xff0c;企业管理员怎样设置统一的签名呢&#xff1f;下面小编将带您深入了解。 一、邮箱签名的功能和作用 在发邮件时…

混合app开发

安卓与h5交互 原生调用js js调用原生 ios与h5交互 代码演示 ios调用h5 xcode创建一个ios项目 h5调用原生 h5部分代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" conten…

pygame 烟花效果

# 初始化 pygame.init() screen_width 800 screen_height 600 screen pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption(烟花效果) # 焰火发射 particles [] # 焰火粒子 def firework(x, y): num_particles 100 # 每次发射的…

华为云服务镜像手动更换

操作步骤&#xff1a; 1、进入华为云首页点击云容器引擎CCE&#xff1b; 2、选择你所要更换镜像的环境【这里以dev环境演示】&#xff1b; 3、点击dev环境后选择顶部的命名空间&#xff0c;点击【工作负载】中右侧栏的【升级】按钮&#xff1b; 4、点【更换镜像】选择你在test…

三级等保安全解决方案——实施方案

实施方案设计 本方案将依照国家有关信息安全建设的一系列法规和政策&#xff0c;为电台建立体系完整、安全功能强健、系统性能优良的网络安全系统。以“统一规划、重点明确、合理建设、逐步强化”为基本指导原则。根据电台网络系统不同信息的重要性调整保护策略&#xff0c;不欠…

06-vscode+espidf开发调试方法(内置JTAG调试)

使用VS Code和ESP-IDF进行ESP32开发和调试 在我们搭建 IDF 框架后&#xff0c;OpenOCD 已经自动下载好了&#xff0c; 我们通过 JTAG 接口连接使用 OpenOCD 进行调试。而ESP32芯片中内置 了JTAG 电路&#xff0c;无需额外芯片即可调试&#xff0c;更加方便&#xff0c;所以这里…

ubuntu下交叉编译ffmpeg到目标架构为aarch架构的系统

Ubuntu下FFmpeg的aarch64-linux-gnu架构交叉编译教程 一、前言 有时候真的很想报警的&#xff0c;嵌入式算法部署花了好多时间了&#xff0c;RKNN 1808真是问题不少&#xff1b;甲方那边也是老是提新要求&#xff0c;真是受不了。 由于做目标检测&#xff0c;在C代码中有对视…

Maven的dependencyManagement与dependencies区别

先说结论&#xff1a;Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。 在maven多模块项目的pom文件中&#xff0c;有的小伙伴会发现最外层的pom文件和里面的pom文件有个地方不一样 如下图 父pom 子pom 一般来说是在maven的最外父工程pom文件里&…