NLP作业01:利用HMM实现词性标注

news2024/12/25 9:16:31

作业头

这个作业属于哪个课程自然语言处理
这个作业要求在哪里利用HMM实现词性标注作业要求
我在这个课程的目标实现词性标注
这个作业在哪个具体方面帮助我实现目标代码实现
参考文献1.隐马尔科夫模型 2.基于HMM的词性标注  3.基于HMM+Viterbi算法的词性标注 Python

文章目录

        • 作业内容
        • HMM模型介绍✨
        • 维特比算法介绍
        • 代码展示

作业内容

1.利用“1998人民日报词性标注语料库”进行模型的训练。
2.根据数据估计HMM的模型参数:全部的词性集合Q,全部的词集合V ,初始概率向量PI ,词性到词性的转移矩阵A ,词性到词的转移矩阵B 。 可以采用频率估计概率的方法计算模型参数,但需要进一步采用拉普拉斯平滑处理。
3.在模型预测阶段基于维特比算法进行解码,并给出测试文本:“那个球状闪电呈橘红色,拖着一条不太长的尾迹,在夜空中沿一条变换的曲线飘行着。”的词性标注结果。
请添加图片描述

HMM模型介绍✨

  HMM,即隐马尔可夫模型(Hidden Markov Model),是一种基于状态转移的概率模型,它可以用来描述一个系统在不同状态之间转移的过程,其中状态是不可观测的,只能通过观测到的结果来推测。
  HMM模型由两个部分组成:状态序列和观测序列。状态序列是一个随机的序列,描述了系统在不同状态之间的转移过程;观测序列是由状态序列生成的观测数据,描述了在不同状态下系统产生的观测结果。
  HMM模型的基本假设是,系统的状态转移过程和观测结果都是由概率分布描述的。具体来说,HMM模型可以用一个三元组(S, O, A, B, π)来表示:

S:状态集合,包含所有可能的状态。
O:观测集合,包含所有可能的观测结果。
A:状态转移概率矩阵,描述了系统在不同状态之间转移的概率。
B:观测概率矩阵,描述了在不同状态下系统产生观测结果的概率。
π:初始状态概率向量,描述了系统在初始时各个状态的出现概率。

  HMM模型的主要应用领域是语音识别、自然语言处理、图像识别、生物信息学等领域。在语音识别中,HMM模型被广泛应用,主要用于识别语音信号中的语音单元,如音素、音节等。在自然语言处理中,HMM模型可以用来对文本进行词性标注、命名实体识别等任务。在图像识别中,HMM模型可以用来对图像序列进行分析和识别。在生物信息学中,HMM模型可以用来对DNA序列进行分析和比对。

  HMM模型的优点是可以很好地处理序列数据,能够捕捉到不同状态之间的转移过程,并且可以通过观测序列来推测系统的状态。
HMM三个基本问题:

估计问题:给定一个隐马尔科夫模型M=(A,B),如何有效计算某个观测序列O出现的概率,即计算P(O|M) (A表示转移概率,B表示发射概率) 。
解码问题:给定一个观测序列O和一个HMM模型M,寻找最好的隐序列Q以便最好的解释观测值
学习问题:依据给定的观测序列O以及HMM模型中的状态集合,学习最佳HMM参数模型A和B。

维特比算法介绍

维特比算法(Viterbi Algorithm)是一种基于动态规划的解决序列标注问题的算法。它可以用于许多应用,如语音识别、自然语言处理、生物信息学等领域。

维特比算法主要用于在隐藏马尔可夫模型(Hidden Markov Model,HMM)中寻找最有可能的状态序列。HMM是一种概率模型,它由一个隐含的马尔可夫链和一个生成观测的随机过程组成。它被广泛应用于语音识别、手写字符识别、自然语言处理、生物信息学等领域。

在HMM中,我们无法观察到隐含的状态序列,但是可以得到与状态相关的观测序列。维特比算法通过计算所有可能的状态序列的概率来寻找最有可能的状态序列,从而实现对观测序列的标注。

维特比算法的具体步骤如下:

初始化:设 t=1 时刻的各状态的最大概率为对应状态的初始状态概率。
递归计算:对于每个 t>1 的时刻和每个可能的状态 i,计算从时刻 1 到 t-1 的所有状态序列中,以状态 i 作为时刻 t-1 的状态,到时刻 t 的状态序列的最大概率以及相应的路径。
终止:最后一个时刻 T 时的各状态的最大概率即为整个序列的概率,并得到最可能的状态序列。 最终我们得到的就是最有可能的状态序列。

代码展示

存在一点问题。。。

import os
import numpy as np

# 读取语料库数据
def read_data(filename):
    with open(filename, 'r', encoding='utf-8') as f:
        data = f.read()
    return data

# 预处理,将每行数据转化为词性标注对
def pre_process(data):
    sentences = data.split('\n')[:-1]
    result = []
    for sentence in sentences:
        words = sentence.split('  ')[:-1]
        for word in words:
            w, tag = word.rsplit('/', 1)
            result.append((w, tag))
    return result

# 计算模型参数,并进行拉普拉斯平滑处理
def train(train_data):
    # 获取所有不同的词和词性
    words = set([item[0] for item in train_data])
    tags = set([item[1] for item in train_data])
    
    # 统计初始概率向量
    pi = {}
    for _, tag in train_data:
        if tag not in pi:
            pi[tag] = 0
        pi[tag] += 1
    for tag in tags:
        pi[tag] = (pi.get(tag, 0) + 1) / (len(train_data) + len(tags))
        
    # 统计词性到词性的转移矩阵
    A = {}
    for i in range(len(train_data)-1):
        cur_tag, next_tag = train_data[i][1], train_data[i+1][1]
        if cur_tag not in A:
            A[cur_tag] = {}
        if next_tag not in A[cur_tag]:
            A[cur_tag][next_tag] = 0
        A[cur_tag][next_tag] += 1
    for cur_tag in tags:
        if cur_tag not in A:
            A[cur_tag] = {}
        for next_tag in tags:
            A[cur_tag][next_tag] = (A[cur_tag].get(next_tag, 0) + 1) / (sum(A[cur_tag].values()) + len(tags))
        
    # 统计词性到词的转移矩阵
    B = {}
    for word, tag in train_data:
        if tag not in B:
            B[tag] = {}
        if word not in B[tag]:
            B[tag][word] = 0
        B[tag][word] += 1
    for tag in tags:
        if tag not in B:
            B[tag] = {}
        for word in words:
            B[tag][word] = (B[tag].get(word, 0) + 1) / (sum(B[tag].values()) + len(words))

    return list(tags), list(words), pi, A, B

# 预测阶段,使用维特比算法解码
def predict(test_data, tags, words, pi, A, B):
    # 构建词性下标索引
    tag2id = {tag: i for i, tag in enumerate(tags)}

    result = []
    for i in range(len(test_data)):
        # 计算词在各个词性下的条件概率
        word = test_data[i]
        p_words = np.zeros(len(tags))
        for j in range(len(tags)):
            p_words[j] = np.log(B[tags[j]].get(word, 1e-10))
        
        # 第一个词计算初始概率
        if i == 0:
            p = np.log([pi[tag] for tag in tags]) + p_words
            max_idx = np.argmax(p)
            result.append(tags[max_idx])
        else:
            # 计算上一个词的各个词性概率
            prev_word = test_data[i-1]
            p_prev = np.zeros(len(tags))
            for j in range(len(tags)):
                p_prev[j] = np.log(A[tags[j]].get(prev_tag, 1e-10)) + np.log(B[tags[j]].get(prev_word, 1e-10))
            
            # 当前词基于上一个词的各个词性概率计算
            p = p_prev + p_words
            max_idx = np.argmax(p)
            result.append(tags[max_idx])
        
        prev_tag = result[-1]

    return result

# 加载数据并进行预处理
data = read_data('1998人民日报语料库.txt')
train_data = pre_process(data[:10000])  # 仅使用前10000个标注对进行训练
test_data = '那个球状闪电呈橘红色,拖着一条不太长的尾迹,在夜空中沿一条变换的曲线飘行着。'.split()

# 训练模型
tags, words, pi, A, B = train(train_data)

# 预测结果
result = predict(test_data, tags, words, pi, A, B)

# 输出结果
print(' '.join([f"{test_data[i]}/{result[i]}" for i in range(len(test_data))]))

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode: 673. 最长递增子序列的个数 | 动态规划】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

LeetCode 热题 HOT 100:从前序与中序遍历序列构造二叉树、二叉树展开为链表、二叉树中的最大路径和

LeetCode 热题 HOT 100 105. 从前序与中序遍历序列构造二叉树 题目: 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历, 请构造二叉树并返回其根节点。 示例 1&#xff1…

webassembly——同源策略问题的处理(浏览器不能加载本地资源的问题)

原因:在用chatGPT生成可视化地图前端文件后,打开不能正常显示 WebAssembly是一种新的二进制代码格式,它可以提供更高的性能和更好的安全性。WebAssembly遵循同源策略,这意味着只有与运行WebAssembly代码相同域名下的JavaScript代码…

Linux --- 常用命令

一、常用命令 1.1、常用命令演示 在这一部分中,我们主要介绍几个常用的命令,让大家快速感受以下Linux指令的操作方式。主要包含 以下几个指令: 1.2、Linux命令使用技巧 在我们使用Linux系统命令时,可以使用以下几个技巧&#x…

丹麦PR electronics信号隔离器3185A1 3185A2安全栅

应用 1:1 标准电流信号隔离,信号范围 0(4)...20 mA。标准 DIN 导轨安装。无论在技术或是成本上,都是电流信号电气隔离的选择。能有效抑制浪涌电流,保护控制系统远离信号噪声和瞬变的影响。消除接地环路和测量浮地信号。安装于安全区域或 Zon…

03、Cadence使用记录之超多引脚元器件的快速创建方法(OrCAD Capture CIS)

03、Cadence使用记录之超多引脚元器件的快速创建方法(OrCAD Capture CIS) 参考的教程是B站的视频:allegro软件入门视频教程全集100讲 前置教程: 01、Cadence使用记录之新建工程与基础操作(原理图绘制:OrC…

个人建议:真的不要去小公司...

软件测试人员如果想要有更好的发展真的不要去小公司! 为什么? 小公司的测试团队相对较小,往往只有一两个人,缺乏资源和技术支持,难以优化测试流程和提高测试效率。 小公司一般缺乏完善的软件开发流程和质量管理体系&a…

基于LSTM神经网络的通用股票预测源代码+模型+数据集

基于神经网络的通用股票预测模 下载地址:基于LSTM神经网络的通用股票预测源代码模型数据集 0 使用方法 How to use 使用getdata.py下载数据,或者使用自己的数据源,将数据放在stock_daily目录下 使用data_preprocess.py预处理数据&#xff…

基于RK3568的Linux驱动开发——GPIO知识点(一)

authordaisy.skye的博客_CSDN博客-Qt,嵌入式,Linux领域博主系列基于RK3568的Linux驱动开发—— GPIO知识点(二)_daisy.skye的博客-CSDN博客 gpio bank RK3568 有 5 组 GPIO bank:GPIO0~GPIO4,每组又以 A0-A7、B0-B7、 C0-C7、 D0…

CSS基础样式

1.高度和宽度 .c1{height:300px;width:500px; } 注意事项: 宽度,支持百分比 行内标签:默认无效 块级标签:默认有效(右侧区域就算是空白,也不给占用) 2.块级和行内标签 css样式:标签…

软件工程实验:用例图设计

目录 前言 实验目的 实验要求 实验步骤 结果展示 总结 前言 软件工程导论实验是一门旨在培养学生掌握软件开发过程中的基本方法和技能的课程。本实验的主题是用例图设计,用例图是一种描述系统功能需求的图形化工具,它可以帮助分析和设计系统的行为…

初识Tkinter弹窗

Tkinter弹窗 Tkinter是什么 Tkinter 是使用 python 进行窗口视窗设计的模块。Tkinter模块(“Tk 接口”)是Python的标准Tk GUI工具包的接口。作为 python 特定的GUI界面,是一个图像的窗口,tkinter是python 自带的,可以编辑的GUI界面&#xff…

【蓝桥杯省赛真题17】python删除字符串 青少年组蓝桥杯python编程省赛真题解析

目录 python删除字符串 一、题目要求 1、编程实现 2、输入输出 二、解题思路

Qt创建SDK库(dll动态库)并调用SDK库(dll动态库)

Qt创建SDK库(dll动态库)并调用SDK库(dll动态库) 一、项目场景 在日常的项目中,我们经常会遇到调用别人的数学库、线程库、图形库等操作。这些库通常就被称为SDK,SDK全称是Software Development Kit(软件开发工具包),…

【C++ 五】结构体

结构体 文章目录 结构体前言1 结构体基本概念2 结构体定义和使用3 结构体数组4 结构体指针5 结构体嵌套结构体6 结构体做函数参数7 结构体中 const 使用场景8 结构体案例8.1 案例一8.2 案例二 总结 前言 本文包含结构体基本概念、结构体定义和使用、结构体数组、结构体指针、结…

gitlab CI CD基础概念

gitlab CI CD基础概念 本文目录 gitlab CI CD基础概念基础概念Pipelines:流水线JobsStage .gitlab-ci.yml使用模式1:官网gitlab 本地gitlab runner使用模式2:docker gitlab docker gitlab runner 基础概念 开发模式转变:瀑布模…

【MySQL】(5)聚合函数

文章目录 聚合函数COUNT 函数SUM 函数AVG 函数MAX 函数 MIN 函数 group by 子句简介示例:scott 数据库单列分组多列分组 having 子句总结 聚合函数 在 MySQL 中,聚合函数是用于计算多行数据的统计信息的函数,例如总和、平均值、最大值、最小…

图扑数字孪生工厂合集 | 智慧工厂可视化,推动行业数字化转型

前言 图扑软件基于 HTML5(Canvas/WebGL/WebVR)标准的 Web 技术,满足了工业物联网跨平台云端化部署实施的需求,以低代码的形式自由构建三维数字孪生、大屏可视化、工业组态等等。从 SDK 组件库,到 2D 和 3D 编辑&#…

LeetCode算法小抄--花式遍历二叉树

LeetCode算法小抄--花式遍历二叉树花式遍历二叉树翻转二叉树[226. 翻转二叉树](https://leetcode.cn/problems/invert-binary-tree/)填充节点的右侧指针[116. 填充每个节点的下一个右侧节点指针](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/)将…

OpenCV实例(一)人脸检测

OpenCV实例(一)人脸检测 1.人脸检测和识别概述2.使用OpenCV进行人脸检测2.1静态图像中的人脸检测2.2视频中的人脸检测 作者:Xiou 1.人脸检测和识别概述 计算机视觉使很多任务成为现实,其中两项任务就是人脸检测(在图…