【自然语言处理】文本情感分析

文本情感分析

1 任务目标

1.1 案例简介

情感分析旨在挖掘文本中的主观信息,它是自然语言处理中的经典任务。在本次任务中,我们将在影评文本数据集(Rotten Tomato)上进行情感分析,通过实现课堂讲授的模型方法,深刻体会自然语言处理技术在生活中的应用。

同学们需要实现自己的情感分析器,包括特征提取器(可以选择词袋模型、n-gram模型或词向量模型)、简单的线性分类器以及梯度下降函数。随后在数据集上进行训练和验证。我们提供了代码框架,同学们只需补全model.py中的两个函数。

1.2 数据说明

我们使用来自Rotten Tomato的影评文本数据。其中训练集data_rt.train和测试集data_rt.test均包含了3554条影评,每条影评包含了文本和情感标签。示例如下:

+1 visually , 'santa clause 2' is wondrously creative .

其中,+1 表示这条影评蕴涵了正面感情,后面是影评的具体内容。

1.3 数据特征提取

TODO:补全featureExtractor函数

在这个步骤中,同学们需要读取给定的训练和测试数据集,并提取出文本中的特征,输出特征向量。

同学们可以选择选择词袋模型、n-gram模型或词向量模型中的一种,也可以对比三者的表现有何差异。

1.4 训练分类器

TODO:补全learnPredictor函数

我们提供的训练数据集中,每句话的标签在文本之前,其中+1表示这句话蕴涵了正面感情,-1表示这句话蕴涵了负面感情。因此情感分析问题就成为一个分类问题。

我们采用最小化hinge loss的方法训练分类器,假设我们把每条影评文本 x x x映射为对应的特征向量 ϕ ( x ) \phi(x) ϕ(x),hinge loss的定义为
L ( x , y ; w ) = max ⁡ ( 0 , 1 − w ⋅ ϕ ( x ) y ) L(x,y; \mathbf{w})=\max(0,1-\mathbf{w}\cdot\phi(x)y) L(x,y;w)=max(0,1wϕ(x)y)
同学们需要实现一个简单的线性分类器,并推导出相应的梯度下降函数。

1.5 实验与结果分析

在训练集上完成训练后,同学们需要在测试集上测试分类器性能。本小节要求同学们画出训练集上的损失函数下降曲线和测试集的最终结果,并对结果进行分析。

1.6 评分要求

同学们需要提交源代码和实验报告。实验报告中应包含两部分内容:

  • 对hinge loss反向传播的理论推导,请写出参数的更新公式。
  • 对实验结果的分析,请描述采用的模型结构、模型在训练集上的损失函数下降曲线和测试集的最终结果,并对结果进行分析。分析可以从模型的泛化能力、参数对模型性能的影响以及不同特征的影响等方面进行。

2 代码构建

2.1 数据特征提取

  1. 词袋模型

    词袋模型将文本中的每个单词作为一个特征,特征值为该单词在文本中出现的次数。

    def extractFeatures_bow(x):features = collections.defaultdict(float)for word in x.split():features[word] += 1.0return features
    
  2. n-gram模型

    n-gram模型考虑了文本中的n个连续单词,将它们作为特征。在本实验中,我们使用了2-gram模型。

    def extractFeatures_ngram(x, n=2):features = collections.defaultdict(float)words = x.split()for i in range(len(words) - n + 1):ngram = ' '.join(words[i:i+n])features[ngram] += 1.0return features
    
  3. 词向量模型

    本实验词向量模型采用了预训练的 word2vec 模型(FastText Word Embeddings)加载词向量。

    # 使用预训练的word2vec模型(FastText Word Embeddings)加载词向量 
    def loadWord2VecModel(filename):wordVectors = {}with open(filename, 'r', encoding='utf-8') as f:for line in f:values = line.split()word = values[0]vector = np.array(values[1:], dtype='float32')wordVectors[word] = vectorreturn wordVectorswiki_news= './data/wiki-news-300d-1M.vec'
    wordVectors = loadWord2VecModel(wiki_news)
    

    词向量模型使用预训练的词向量(如FastText、Word2Vec)将文本中的单词表示为向量,并将这些向量的平均值作为文本的特征向量。

    def extractFeatures_wordvec(x):# 将句子x拆分成单个字符或单词tokens = x.split()# 句子的词向量表示vectors = [wordVectors[token] for token in tokens if token in wordVectors.keys()]# 将句子中的每个单词转换为对应的词向量,然后将这些词向量的平均值作为该句子的特征向量if vectors:# 将句子中的每个单词转换为对应的词向量,然后将这些词向量的平均值作为该句子的特征向量vectors = np.mean(vectors, axis=0)else:# 处理句子中所有单词都不在模型中的情况vectors = np.zeros(len(next(iter(wordVectors.values()))))# 将特征向量表示为字典featureDict = {}for i, value in enumerate(vectors):featureDict[f'feature_{i}'] = valuereturn featureDict
    

2.2 训练分类器

训练数据集中,每句话的标签在文本之前,其中+1表示这句话蕴涵了正面感情,-1表示这句话蕴涵了负面感情。因此情感分析问题就成为一个分类问题。

在情感分析任务中,我们的目标是学习一个分类器,将文本表示为特征向量,并根据这些特征向量对文本进行分类。我们使用的是最小化hinge loss的方法训练分类器。

  1. 参数更新公式推导

    假设我们的分类器参数为 w \mathbf{w} w,对于给定的训练样本 ( x i , y i ) (x_i, y_i) (xi,yi),其中 x i x_i xi 是文本的特征向量, y i y_i yi 是其对应的情感标签(+1 或 -1)。

    我们的目标是最小化hinge loss,即:

    L ( x i , y i ; w ) = max ⁡ ( 0 , 1 − w ⋅ ϕ ( x i ) ⋅ y i ) L(x_i, y_i; \mathbf{w}) = \max(0, 1 - \mathbf{w} \cdot \phi(x_i) \cdot y_i) L(xi,yi;w)=max(0,1wϕ(xi)yi)

    其中 ϕ ( x i ) \phi(x_i) ϕ(xi) 是文本 x i x_i xi 的特征向量。

    我们使用随机梯度下降法来更新参数 w \mathbf{w} w。参数的更新公式可以通过对hinge loss进行梯度下降来得到。梯度的计算需要考虑 hinge loss 在 w ⋅ ϕ ( x i ) ⋅ y i ≤ 1 \mathbf{w} \cdot \phi(x_i) \cdot y_i \leq 1 wϕ(xi)yi1 w ⋅ ϕ ( x i ) ⋅ y i > 1 \mathbf{w} \cdot \phi(x_i) \cdot y_i > 1 wϕ(xi)yi>1 两种情况下的情况:

    w ⋅ ϕ ( x i ) ⋅ y i ≤ 1 \mathbf{w} \cdot \phi(x_i) \cdot y_i \leq 1 wϕ(xi)yi1 时,梯度为:

    ∂ L ∂ w = − ϕ ( x i ) ⋅ y i \frac{\partial L}{\partial \mathbf{w}} = - \phi(x_i) \cdot y_i wL=ϕ(xi)yi

    w ⋅ ϕ ( x i ) ⋅ y i > 1 \mathbf{w} \cdot \phi(x_i) \cdot y_i > 1 wϕ(xi)yi>1 时,梯度为零。

    因此,参数的更新公式为:

    $$
    \mathbf{w} := \mathbf{w} + \eta \cdot \left{
    \begin{array}{ll}

    • \phi(x_i) \cdot y_i & \text{if } \mathbf{w} \cdot \phi(x_i) \cdot y_i \leq 1 \
      0 & \text{otherwise}
      \end{array}
      \right.
      $$

    其中 η \eta η 是学习率。

  2. 代码

    代码中同时加入了绘制曲线部分。

    def learnPredictor(trainExamples, testExamples, featureExtractor, numIters, eta):'''给定训练数据和测试数据,特征提取器|featureExtractor|、训练轮数|numIters|和学习率|eta|,返回学习后的权重weights你需要实现随机梯度下降优化权重'''weights = collections.defaultdict(float)trainErrors = []testErrors = []trainLosses = []testLosses = []for i in range(numIters):totalTrainLoss = 0totalTestLoss = 0for x, y in trainExamples:featureVector = featureExtractor(x)predicted = dotProduct(featureVector, weights)loss = max(0, 1 - predicted * y)totalTrainLoss += lossif loss > 0:for feature, value in featureVector.items():weights[feature] += eta * value * yfor x, y in testExamples:featureVector = featureExtractor(x)predicted = dotProduct(featureVector, weights)loss = max(0, 1 - predicted * y)totalTestLoss += losstrainError = evaluatePredictor(trainExamples, lambda x: (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))testError = evaluatePredictor(testExamples, lambda x: (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))trainErrors.append(trainError)testErrors.append(testError)trainLosses.append(totalTrainLoss / len(trainExamples))testLosses.append(totalTestLoss / len(testExamples))print("At iteration %d, loss on training set is %f, loss on test set is %f, error rate on training set is %f, error rate on test set is %f" %(i, totalTrainLoss / len(trainExamples), totalTestLoss / len(testExamples), trainError, testError))plt.figure(figsize=(12, 5))plt.subplot(1, 2, 1)plt.plot(range(numIters), trainLosses, label="Train Loss")plt.plot(range(numIters), testLosses, label="Test Loss")plt.xlabel("Epoch")plt.ylabel("Loss")plt.title("Loss vs. Epoch")plt.legend()plt.subplot(1, 2, 2)plt.plot(range(numIters), trainErrors, label="Train Error Rate")plt.plot(range(numIters), testErrors, label="Test Error Rate")plt.xlabel("Epoch")plt.ylabel("Error Rate")plt.title("Error Rate vs. Epoch")plt.legend()plt.tight_layout()plt.show()return weights
    

3 训练结果

3.1 词袋模型训练结果

  1. 训练代码

    设置超参数,训练轮次epoch为30,学习率为0.01。

    def BOW_Model(numIters, eta):trainExamples = readExamples('data/data_rt.train')testExamples = readExamples('data/data_rt.test')featureExtractor = extractFeatures_bowweights = learnPredictor(trainExamples, testExamples, featureExtractor, numIters=numIters, eta=eta)trainError = evaluatePredictor(trainExamples, lambda x : (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))testError = evaluatePredictor(testExamples, lambda x : (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))print ("train error = %s, test error = %s" % (trainError, testError))BOW_Model(30, 0.01)
    
  2. 训练结果

    image-20240603231245392

    train error = 0.013787281935846933, test error = 0.27124366910523356
    

3.2 n-gram模型训练结果

  1. 训练代码

    设置超参数,训练轮次epoch为30,学习率为0.01。

    def Ngram_Model(numIters, eta):trainExamples = readExamples('data/data_rt.train')testExamples = readExamples('data/data_rt.test')featureExtractor = extractFeatures_ngramweights = learnPredictor(trainExamples, testExamples, featureExtractor, numIters=numIters, eta=eta)trainError = evaluatePredictor(trainExamples, lambda x : (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))testError = evaluatePredictor(testExamples, lambda x : (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))print ("train error = %s, test error = %s" % (trainError, testError))Ngram_Model(30, 0.01)
    
  2. 训练结果

    image-20240603231336449

    train error = 0.0005627462014631402, test error = 0.33061339335959483
    

    可以看到,使用n-gram模型的收敛速度比词袋模型稍快,但训练结果却更差,明显产生了过拟合。

3.3 词向量模型训练结果

  1. 训练代码

    设置超参数,训练轮次epoch为30,学习率为0.01。

    def Word2Vec_Model(numIters, eta):trainExamples = readExamples('data/data_rt.train')testExamples = readExamples('data/data_rt.test')featureExtractor = extractFeatures_wordvecweights = learnPredictor(trainExamples, testExamples, featureExtractor, numIters=numIters, eta=eta)trainError = evaluatePredictor(trainExamples, lambda x : (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))testError = evaluatePredictor(testExamples, lambda x : (1 if dotProduct(featureExtractor(x), weights) >= 0 else -1))print ("train error = %s, test error = %s" % (trainError, testError))Word2Vec_Model(30, 0.01)
    
  2. 训练结果

    image-20240603231418657

    train error = 0.22031513787281937, test error = 0.236916150815982
    

    可以看到,使用预训练模型的词向量训练结果最好,得到的erro值最低,并且没有过拟合。

4 总结

以下是各特征提取方法的最终训练和测试误差:

特征提取方法训练误差测试误差
词袋模型0.01380.2712
n-gram模型0.00060.3306
词向量模型0.22030.2369

从表格可以看出,n-gram模型在训练集上的误差最低,但在测试集上的误差却最高,表明其可能过拟合了训练数据。词袋模型在训练集和测试集上的误差较为平衡,而词向量模型在测试集上的表现最好,尽管其在训练集上的误差较高。

  1. 性能:

    • 词袋模型在训练集上表现很好,但在测试集上有较高的误差,可能存在一定的过拟合。

    • n-gram模型在训练集上表现最佳,但在测试集上表现最差,明显过拟合。

    • 词向量模型在测试集上的误差最低,泛化能力最好。

  2. 泛化能力:

    • 词袋模型和n-gram模型都有一定的过拟合风险,尤其是在处理复杂文本时。

    • 词向量模型由于捕捉到词语的语义关系,能够更好地泛化到未见过的数据。

  3. 权重可解释性:

    • 词袋模型的权重最易解释,可以直接看到每个词对情感预测的影响。

    • n-gram模型的权重解释性相对较低,但仍能提供一定的短语信息。

    • 词向量模型的权重解释性最差,但它在捕捉语义信息方面表现最好。

根据以上分析,我们可以得出以下结论:

  • 如果需要一个解释性较强的模型,可以选择词袋模型。
  • 如果需要一个泛化能力较好的模型,可以选择词向量模型。
  • n-gram模型在小数据集上容易过拟合,不建议在数据较少或分布复杂时使用。

实际应用中,可以根据具体需求选择合适的特征提取方法和模型,并通过调整学习率、正则化等超参数来优化模型性能。

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

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

相关文章

OpenStack无效数据清空脚本

​​​​​​​介绍 在以openstack为底层开发的一些项目中,常常会遇到项目中数据与openstack数据不同步的问题,为了简化清空无效数据的繁琐,提供以下脚本便于运维操作。 环境变量 [rootcloud ~]# cat admin.sh export OS_USERNAMEadmin ex…

蓝图collapseNodes很有用

学到了,选中N个节点后,再右键collapseNode,可以使代码很清晰,双击后可以看到相应的代码,具有层次感。

【python科学文献计量】关于中国知网检索策略的验证,以事故伤害严重程度检索为例

关于中国知网检索策略的验证,以事故伤害严重程度检索为例 1 背景2 文献下载3 数据处理1 背景 由于要进行相关研究内容的综述,需要了解当前我国对于事故伤害严重程度的研究现状,采用国内较为知名的检索网站(中国知网)进行文献数据集检索 由于最近知网出bug,检索的结果在…

【最新鸿蒙应用开发】——使用axios完成手机号注册业务

使用Axios请求实现目标效果图: 短信验证码登录 校验图形验证码,校验通过 发送短信验证码到用户手机上,可通过在线 WebSocket查看:wss://guardian-api.itheima.net/verifyCode 根据 手机号 短信验证码 实现登录 更新图形验证码…

日本指数实时API接口

日本 指数 实时API接口 # Restful API https://tsanghi.com/api/fin/index/JPN/realtime?token{token}&ticker{ticker}指定指数代码,获取该指数的实时行情(开、高、低、收、量)。 更新周期:实时。 请求方式:GET。…

CV每日论文--2024.6.4

1、Mixed Diffusion for 3D Indoor Scene Synthesis 中文 标题:用于 3D 室内场景合成的混合扩散 简介:这篇论文提出了一种名为MiDiffusion的混合离散-连续扩散模型,用于从给定的房间类型、平面图和可能存在的物体中合成逼真的3D室内场景。 作者指出,该…

【Unity实战篇 】 | Unity实现UGUI颜色渐变,支持透明渐变

前言 【Unity实战篇 】 | Unity实现UGUI颜色渐变,支持透明渐变一、双层颜色渐变1.1 组件属性面板1.2 效果及代码 二、多层颜色渐变2.1 组件属性面板2.2 效果及代码 总结 前言 在Unity中UGUI的实现图片和文字颜色渐变效果是一个很常见的需求。下面就来看一下颜色渐变…

机器学习中的集成学习

💬内容概要 1 集成学习概述及主要研究领域 2 简单集成技术  2.1 投票法  2.2 平均法  2.3 加权平均 3 高级集成技术  3.1 Bagging  3.2 Boosting  3.3 Bagging vs Boosting 4 基于Bagging和Boosting的机器学习算法  4.1 sklearn中的Bagging算法  4.2 sklea…

1961. 检查字符串是否为数组前缀 - 力扣

1. 题目 给你一个字符串 s 和一个字符串数组 words ,请你判断 s 是否为 words 的 前缀字符串 。 字符串 s 要成为 words 的 前缀字符串 ,需要满足:s 可以由 words 中的前 k(k 为 正数 )个字符串按顺序相连得到&#xf…

大型语言模型的工作原理(LLM:从零学起)

目录 一、说明 二、LLM如何运作 三、预训练:基本模型 四、微调:培训助手 五、RLHF:从人类反馈中强化学习 六、提示工程 七、总结 一、说明 这是我们谈论LLM系列的第二篇文章。在本文中,我们旨在为大型语言模型 (LLM&am…

企业微信hook接口协议,ipad协议http,chatid转群id

chatid转群id 参数名必选类型说明uuid是String每个实例的唯一标识,根据uuid操作具体企业微信 请求示例 {"uuid":"3240fde0-45e2-48c0-90e8-cb098d0ebe43","chatid":"wrO9o4EAAAeR_nSlmjeX1RWrKAKxN8jQ" } 返回示例 {&…

【银河麒麟V10服务器OS-系统根分区扩容】指导教程手册

【银河麒麟V10服务器OS-系统根分区扩容】指导教程手册 环境信息:VMware虚拟软件16.0 首先查看KylinOS服务器版本:nkvers 备注: (Tercel) 版本是 V10 SP1 版本, (Sword) 版本是 V10 SP2 版本, (Lance) 版本是 V10 …

UE4 使用样条线做鱼儿封闭路径动画

描述:鱼儿的游动动画的特点 1.通常是始终保持Y (Pitch)轴角度不变 2.调头的时候改变的是Z轴角度 效果:调头的时候比较自然 蓝图: 最后为了让鱼儿有恒定的游动速度,增加以下蓝图节点,游动速度为50

CTFHUB-技能树-web-web前置技能-HTTP协议全

目录 1.请求方式 2.302跳转 3.Cookie 4.基础认证 5.响应包源码 1.请求方式 curl -v -X http://challenge-3022c877a8dcedeb.sandbox.ctfhub.com:10800/index.php 2.302跳转 参考链接:http://t.csdnimg.cn/aqdNG 301——永久性重定向。该状态码表示请求的资源已…

Avue-data数据大屏显示柱状图(附Demo讲解)

目录 前言1. 接口方式2. SQL查询 前言 由于网上对这部分的知识点相对较少,研究半天的框架最终输出结果 此文主要以记录总结的方式展示如何使用数据库以及接口方式 需要明白柱状图的返回数据格式: #柱状图数据格式 {"categories": ["苹…

组织是什么,为什么需要组织,为什么需要公司

垂直组织 组织架构设计,曾经咱们多个章节进行沟通,今天再回到组织本身。不妨可以思考一个这样的问题,或者随访身边的老板或者朋友,让他们绘制一个组织架构图,或者绘制一个本组织一个视图,得到以下图的示意…

[Redis]Set类型

集合类型也是保存多个字符串类型的元素的,但和列表类型不同的是,集合中 1)元素之间是无序的 2)元素不允许重复 一个集合中最多可以存储2^32-1个元素。 Redis 除了支持集合内的增删查改操作,同时还支持多个集合取交…

盲盒小程序库存管理的关键策略

随着盲盒经济的兴起,越来越多的商家开始投入盲盒小程序的开发与运营。然而,在享受市场红利的同时,库存管理的问题也随之而来。合理的库存管理不仅能够满足用户需求,还能有效优化库存周转率,提升商家的盈利能力。本文将…

有光摄影分享网站系统的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,基础数据管理,论坛管理,足球资讯管理,球队管理 前台账户功能包括:系统首页,个人中心,活动,论坛…

HCIA--OSPF实验(复习)

实验拓扑&#xff1a; 实验思路&#xff1a; 1.规划IP&#xff0c;配置环回&#xff0c;接口IP 2.把R1&#xff0c;R2优先级改为0&#xff0c;让R1、R2放弃选举&#xff0c; [r1]interface g0/0/0 [r1-GigabitEthernet0/0/0]ospf dr-priority 0 <r1>reset ospf…