使用bert进行中文方面级情感识别。
scikit-learn==1.1.3
scipy==1.10.1
seqeval==1.2.2
transformers==4.27.4
pytorch-crf==0.7.2
--checkpoint:模型和配置保存位置
--model_hub:预训练模型
----chinese-bert-wwm-ext:
--------vocab.txt
--------pytorch_model.bin
--------config.json
--data:存放数据
----gdcq
--------ori_data:原始的数据
--------ner_data:处理之后的数据
------------labels.txt:标签
------------train.txt:训练数据
------------dev.txt:测试数据
--------re_data:
------------train.txt:训练数据
------------dev.txt:测试数据
--config.py:配置
--model.py:模型
--process.py:处理ori数据得到ner数据和re数据
--predict.py:加载训练好的模型进行预测
--ner_main.py:实体识别训练和测试
--re_main.py:关系识别训练和测试
使用的方法:
- 1、利用BERT-BILSTM-CRF识别出文本里面的实体,包含方面和观点。
- 2、使用QA的方式根据方面找出观点,比如:[CLS]包装怎么样[SEP]text[SEP],然后根据观点映射到情感。
这里以gdcq数据为例。
1、去https://huggingface.co/hfl/chinese-bert-wwm-ext/tree/main下载相关文件到chinese-bert-wwm-ext下。
2、在process.py里面定义将ori_data里面的数据处理得到ner_data下的数据和re_data下的数据。
ner_data下数据样本是这样的:
--labels.txt
整体
尺寸
新鲜度
价格
包装
物流
服务
功效
真伪
成分
气味
其他
使用体验
中性
负面
正面
--train.txt/dev.txt
{"id": 2970, "text": ["感", "受", "到", "了", "沉", "甸", "甸", "的", "重", "量", " ", "是", "我", "用", "过", "最", "大", "瓶", "的", "乳", "液", " ", "外", "观", "也", "很", "好", "看", "啊"], "labels": ["O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "B-包装", "I-包装", "O", "B-正面", "I-正面", "I-正面", "O"]}
一行一条样本,格式为BIO。
re_data下的数据样本是这样的:
--train.txt/dev.txt
{"id": 2943, "text": ["听", "服", "帖", ",", "自", "然", ",", "关", "键", "价", "格", "便", "宜"], "start": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], "end": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], "aspect": "价格"}
一行一条样本,start答案起始位置,end答案终止位置。
3、在config.py里面定义一些参数,比如:
--max_seq_len:句子最大长度,GPU显存不够则调小。
--epochs:训练的epoch数
--train_batch_size:训练的batchsize大小,GPU显存不够则调小。
--dev_batch_size:验证的batchsize大小,GPU显存不够则调小。
--save_step:多少step保存模型
其余的可保持不变。注意:实体识别最大长度和关系抽取最大长度要保持一致。
4、在ner_main.py里面修改data_name为数据集名称。需要注意的是名称和data下的数据集名称保持一致。最后运行:python ner_main.py
5、在re_main.py里面修改data_name为数据集名称。需要注意的是名称和data下的数据集名称保持一致。最后运行:python re_main.py
5、在predict.py修改data_name并加入预测数据,最后运行:python predict.py
实体识别:
max_seq_len=128
epochs=3
train_batch_size=64
dev_batch_size=64
关系抽取:
max_seq_len=128
epochs=10
train_batch_size=64
dev_batch_size=64
实体识别:
precision recall f1-score support
中性 0.00 0.00 0.00 7
价格 0.72 0.96 0.83 27
使用体验 0.50 0.09 0.15 11
功效 0.54 0.72 0.62 29
包装 0.88 1.00 0.94 15
尺寸 0.00 0.00 0.00 2
成分 0.00 0.00 0.00 6
服务 0.80 0.80 0.80 5
正面 0.82 0.88 0.85 475
气味 0.80 1.00 0.89 12
物流 0.82 0.93 0.87 30
负面 0.60 0.60 0.60 45
micro avg 0.78 0.83 0.81 664
macro avg 0.54 0.58 0.55 664
weighted avg 0.77 0.83 0.79 664
关系抽取:
总共:139,正确:119,准确率:0.8561151079136691
联合预测:
文本>>>>> 听服帖,自然,关键价格便宜
实体>>>>> {'正面': [('听服帖', 0, 2), ('自然', 4, 5), ('便宜', 11, 12)], '价格': [('价格', 9, 10)]}
关系>>>>> [('价格', '便宜', '正面')]
====================================================================================================
文本>>>>> 香香的,颜色正,喜欢
实体>>>>> {'正面': [('香香的', 0, 2), ('正', 6, 6), ('喜欢', 8, 9)], '功效': [('颜', 4, 4)], '使用体验': [('色', 5, 5)]}
关系>>>>> [('颜', '正', '正面'), ('色', '正', '正面')]
====================================================================================================
文本>>>>> 面膜非常不错。外观高大上,用起来也非常好。
实体>>>>> {'正面': [('非常不错', 2, 5), ('高大上', 9, 11), ('非常好', 17, 19)], '包装': [('外观', 7, 8)]}
关系>>>>> [('外观', '高大上', '正面')]
====================================================================================================
文本>>>>> 清洁度比较好吧,***的洗颜霜确实是比较赞的
实体>>>>> {'功效': [('清洁度', 0, 2)], '正面': [('比较好', 3, 5), ('比较赞', 18, 20)]}
关系>>>>> [('清洁度', '比较好', '正面')]
====================================================================================================
文本>>>>> 一直在使用的品牌、物流给力、**搞活动时很优惠
实体>>>>> {'物流': [('物流', 9, 10)], '正面': [('给力', 11, 12), ('很优惠', 20, 22)], '价格': [('活动', 17, 18)]}
关系>>>>> [('物流', '给力', '正面'), ('活动', '很优惠', '正面')]
====================================================================================================
文本>>>>> 一直在使用的品牌、物流给力、**搞活动时很优惠
实体>>>>> {'物流': [('物流', 9, 10)], '正面': [('给力', 11, 12), ('很优惠', 20, 22)], '价格': [('活动', 17, 18)]}
关系>>>>> [('物流', '给力', '正面'), ('活动', '很优惠', '正面')]
====================================================================================================
文本>>>>> 物流快,一直用的***,好评
实体>>>>> {'物流': [('物流', 0, 1)], '正面': [('快', 2, 2), ('好评', 12, 13)]}
关系>>>>> [('物流', '快', '正面')]
====================================================================================================
文本>>>>> 很好用噢,比之前买的都好用,味道也不错,用这个牌子化妆品,也选择了这个,不错
实体>>>>> {'正面': [('很好用', 0, 2), ('用', 12, 12), ('不错', 17, 18), ('不错', 36, 37)], '气味': [('味道', 14, 15)]}
关系>>>>> [('味道', '不错', '正面')]
====================================================================================================
文本>>>>> 宝贝收到了,已经是老买主了,味道闻起还不错
实体>>>>> {'气味': [('味道', 14, 15)], '正面': [('还不错', 18, 20)]}
关系>>>>> [('味道', '还不错', '正面')]
====================================================================================================
文本>>>>> 感受到了沉甸甸的重量 是我用过最大瓶的乳液 外观也很好看啊
实体>>>>> {'包装': [('外观', 22, 23)], '正面': [('很好看', 25, 27)]}
关系>>>>> [('外观', '很好看', '正面')]
====================================================================================================
['[CLS]', '很', '好', '用', ',', '价', '格', '便', '宜', ',', '实', '惠', '款', '[SEP]']
文本>>>>> 很好用,价格便宜,实惠款
实体>>>>> {'正面': [('很好用', 0, 2), ('便宜', 6, 7), ('实惠', 9, 10)], '价格': [('价格', 4, 5)]}
关系>>>>> [('价格', '便宜', '正面')]
====================================================================================================
文本>>>>> ***洗面奶收到了,是正品,已使用,洁面很干净,温和不刺激,很好用!
实体>>>>> {'正面': [('是正品', 10, 12), ('很干净', 20, 22), ('温和', 24, 25), ('不刺激', 26, 28), ('很好用', 30, 32)], '功效': [('面', 19, 19)]}
关系>>>>> []
====================================================================================================
由于这几个项目的代码结构都差不多,而且都和信息抽取相关,就一起放在这。
- BERT-BILSTM-CRF:中文实体识别
- BERT-Relation-Extraction:中文关系抽取
- BERT-ABSA:中文方面级情感分析
- BERT-Event-Extraction 中文事件抽取