# 评论上的情感分析:主题与情感词抽取
## 问题描述
- 针对评论网站上的用户评论进行细粒度的情感分析,区别于传统的粗粒度的情感分类(判断一句话的表达情感的正/负性),评论者在一句话中往往会提到多个角度,并在每个角度都抱有不同的观点内容与正/负极性
- 举例:金拱门快餐的食品质量一般,但是服务很周到
- 抽取结果:食品质量 → 一般;服务 → 周到,这里 “食品质量” 与 “服务” 是两个不同的角度(aspect,也叫 opinion target),前一个角度对应的情感词(opinion word)是 “一般”,极性为负(negative),后一个角度对应的情感词为 “周到”,极性为正(positive)
- 问题抽象:其实可以看作一个类似于分词问题的 “序列标注” 问题,如下图所示,给出分词后的输入序列,输出两个同等长度的 BIO 序列,一个作为角度词抽取的输出序列结果,一个作为情感词抽取的输出序列结果,这里 BIO 标记为序列标注问题的惯用标记法,“B” 即为欲标记的目标内容的开始词,“I” 为欲标记内容的中间词(或结尾词),“O” 为不标记的内容
![](https://www.writebug.com/myres/static/uploads/2021/11/19/7718a8e254b3ca722e8814e791fa1862.writebug)
- (另外,将这个问题抽象成序列标注问题还有一个很大的缺点,就是角度词和情感词的抽取是单独的,不是成对匹配的,即就算抽取出两个角度词和两个情感词,也不能将每个情感词对应到每个角度词上,万一两个情感词说的都是同一个角度呢,比如 “美国记者我不知道,但是香港记者啊最快且最吼”,这个问题暂时不知道其他的解决办法)
## 目标
- 刚从 keras 转到 tensorflow(极其智障的做法,一定要先学 tf 再学 keras),实践一下
- 实践一下序列标注这类 seq2seq 类问题的操作方式
- 探索一下文本上的细粒度情感分析
## 数据集
> SemEval 2014 ( Restaurant ) :这是一个标注数据集,看到很多论文都在用,实验使用了 Restaurant 的那一部分数据,数据内容是用户在网上对餐厅的评价
> 从数据示例看,数据集只提供了角度词(aspectTerm)的抽取结果,没有情感词的抽取结果,训练加测试数据总共 3841 条,需要人工标注情感词结果(WTF...)不过还好我拿到了别人标注过的一个结果,提供者是南洋理工大学的 Wang Wenya (感激不尽),目前 state-of-art 的 Coupled Multi-Layer Attentions for Co-Extraction of Aspect and Opinion Terms(AAAI 2017)的作者
### 还是先上结论
- 像主题词与情感词提取这种细粒度情感分析问题并不是一个简单的问题,目前是当成一个序列标注问题来处理,可是无法满足成对提取的要求,目前我还不知道什么更好的办法
- tensorflow 比 keras 强大,不能只学 keras 这种傻瓜式的高层接口,还是要学习下底层的具体的东西,能实现的东西要更灵活,对模型的理解也更深刻
### **数据预处理**
标注数据集下载下来的数据示例上面贴出来过,是 XML 格式的,提供了抽取出来的单词,需要自己把原句子序列处理成 BIO 序列的形式,数据量比较小,不到 4000 条,并且是英文的,涉及不到什么万恶的编码问题,所以没啥可说的,放一下处理好的数据结果
test_docs.txt
![](https://www.writebug.com/myres/static/uploads/2021/11/19/ec431ed84ef886a0732faa244b7d307d.writebug)
test_labels_a.txt(角度词标注结果)
这里把 BIO 序列换成了 012 序列,B 对应 0,I 对应 1,因为数字标签方便之后操作
![](https://www.writebug.com/myres/static/uploads/2021/11/19/836dcfe100b0299bbb153dbd46e31739.writebug)
test_labels_p.txt(情感词标注结果)
![](https://www.writebug.com/myres/static/uploads/2021/11/19/7fb138c6cd42d7dadf80b3e94500a844.writebug)
### **词向量模型**
训练一个 word2vec 词向量模型,这个是独立在模型外面提前做的,因为数据集提供的数据只有 4000 条很少,不使用预训练的 word embedding 模型效果就会不好。训练数据用的是“Yelp”(外国版“大众点评”)的数据,数据内容就是很多用户在它们网站上留下的对酒店的评论文本,下载地址上面有
## **模型搭建**
tensorflow 可太挑战传统编程思维了,但是很有趣。分两步
1. 先搭模型,模型相当于数据流动的管道,在管道里有各种操作(比如加减乘除等等),但是此时只是一个管道,你可以看每个管道口的数据形状(shape),但是没有任何具体数据
2. 放数据进去,让数据在管道里流,流到底就出结果了,每次放一条数据(也可以一次放多条,也就是一个 batch,因为数据量很少就没弄 batch),每条数据流完出结果计算一下 loss,优化一下参数,然后继续放
分两个代码文件说,一个是 lstm.py,负责搭建模型,包括输入,输出,loss,参数更新方式等等一切细节,另一个是 train_lstm.py,负责读入数据,数据预处理,以及调用前一个 py 进行训练等操作
**lstm.py**
先放一个模型框架,包括两个并列的 LSTM 层,两个全连接层(dense_out),最后是损失函数(loss)与优化器(optimizer),evaluate 是用来在训练过程中定期计算准确度的,方便自己看结果
![](https://www.writebug.com/myres/static/uploads/2021/11/19/5a03ac82ec8b2a04b658f8d749db5830.writebug)
首先定义输入输出,在 tf 的模型搭建过程中,输入输出用 tf.placeholder(占位符)表示,而参数用 tf.Variable 表示
```python
def build_input(self):
config = self.config
x = tf.placeholder(tf.float32, shape=(None, config.embedding_dim), name='x')
y1 = tf.placeholder(tf.int32, shape=(None,), name='y1')
y2 = tf.placeholder(tf.int32, shape=(None,), name='y2')
return x, y1, y2
```
这里输入格式是(None,config.embedding_dim),None 是指序列的长度,因为每个句子长度不一样,无法提前确定有多长,我又不想做 padding 把它们切割到同样的长度,所以就用 None 占位,而 config.embedding_dim 是每个单词的词向量的维度,也就是词向量训练的维度,即 200
然后 y1,y2 就分别是角度词与情感词的结果序列,格式是(None,),这个 None 跟 x 的 None 相等,然后第二维为空就相当于第二维为 1,因为输出的只是一个数字(0,1 或 2,对应 B,I 与 O),只有 1 维
接下来是模型,首先输入的 x 分别进入两个 LSTM 中,得到结果分别为 r_a 与 r_p,然后再分别进入两个全连接层,得到结果 logits_a 与 logits_p,最后 softmax 一下,得到最终的结果 out_a 与 out_p ,放代码:
```python
def __init__(self, config):
self.config = config
self.init_state = []
self.final_state = []
self.x, self.y1, self.y2 = self.build_input()
for i in ['a','p']:
with tf.variable_scope("rnn_"+i):
with tf.variable_scope("gru_cell"):
cell = tf.nn.rnn_cell.BasicLSTMCell(config.gru_hidden_size)
cell = tf.nn.rnn_cell.DropoutWrapper(cell, output_keep_prob=config.drop_rate)
init_state = cell.zero_state(1, tf.float32)
self.init_state.append(init_state)
r, final_state = tf.nn.dynamic_rnn(cell, tf.reshape(self.x, [1, -1, config.embedding_dim]), initial_state=init_state)
self.final_state.append(final_state)
r = tf.reshape(r, [-1, config.gru_hidden_size])
if i == 'a':
r_a = r
else:
r_p = r
with tf
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
资源包含文件:设计报告word+源码及数据 针对评论网站上的用户评论进行细粒度的情感分析,区别于传统的粗粒度的情感分类(判断一句话的表达情感的正/负性),评论者在一句话中往往会提到多个角度,并在每个角度都抱有不同的观点内容与正/负极性。实可以看作一个类似于分词问题的 “序列标注” 问题,探索一下文本上的细粒度情感分析。 像主题词与情感词提取这种细粒度情感分析问题并不是一个简单的问题,目前是当成一个序列标注问题来处理,可是无法满足成对提取的要求,目前我还不知道什么更好的办法 tensorflow 比 keras 强大,不能只学 keras 这种傻瓜式的高层接口,还是要学习下底层的具体的东西,能实现的东西要更灵活,对模型的理解也更深刻。 详细介绍参考:https://biyezuopin.blog.csdn.net/article/details/122547008?spm=1001.2014.3001.5502
资源推荐
资源详情
资源评论
收起资源包目录
基于Python的对网络评论情感分析:主题与情感词抽取.zip (28个子文件)
emotion
README.md 14KB
LSTM
pytorch
lstm.py 841B
train_lstm.py 3KB
tensorflow
lstm.py 3KB
train_lstm.py 4KB
keras
lstm.py 3KB
word_vector_lstm.py 3KB
LICENSE 1KB
设计报告.docx 90KB
CMLA
tensorflow
train_cmla.py 6KB
cmlapp.py 7KB
keras
attention.py 2KB
cmla.py 4KB
data
process.py 3KB
train_labels_a.txt 80KB
test_docs.txt 59KB
origin
Restaurants_Train_v2.xml 1.18MB
Laptop_Train_v2.xml 671KB
Restaurants_Test_Data_phaseB.xml 307KB
opinionAnnotation
test_restaurant 12KB
test_laptop 8KB
train_laptop 32KB
train_restaurant 42KB
Laptops_Test_Data_phaseB.xml 161KB
train_docs.txt 219KB
test_labels_a.txt 21KB
test_labels_p.txt 21KB
train_labels_p.txt 80KB
共 28 条
- 1
资源评论
- 川奈心2022-12-27支持这个资源,内容详细,主要是能解决当下的问题,感谢大佬分享~
- 艾欧斯_2023-05-01实在是宝藏资源、宝藏分享者!感谢大佬~
- UMU6892022-07-03资源很受用,资源主总结的很全面,内容与描述一致,解决了我当下的问题。
- 不睡觉的GISer(已黑化)2023-03-01感谢资源主分享的资源解决了我当下的问题,非常有用的资源。
shejizuopin
- 粉丝: 9014
- 资源: 1288
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功