Machine learning 伯特多类情绪分析的准确率低?

Machine learning 伯特多类情绪分析的准确率低?,machine-learning,nlp,sentiment-analysis,bert-language-model,ktrain,Machine Learning,Nlp,Sentiment Analysis,Bert Language Model,Ktrain,我正在处理一个小型数据集,该数据集: 包含1500篇新闻文章 所有这些文章都是由人类根据他们的情绪/积极程度在5分尺度上进行排名的 清除拼写错误。在导入分析之前,我使用google sheet检查拼写。仍有一些字符编码不正确,但数量不多 平均长度大于512个字 稍微不平衡的数据集 我认为这是一个多类分类问题,我想用这个数据集对BERT进行微调。为了做到这一点,我使用了Ktrain包,基本上遵循了教程。下面是我的代码: (x_train, y_train), (x_test, y_t

我正在处理一个小型数据集,该数据集:

  • 包含1500篇新闻文章

  • 所有这些文章都是由人类根据他们的情绪/积极程度在5分尺度上进行排名的

  • 清除拼写错误。在导入分析之前,我使用google sheet检查拼写。仍有一些字符编码不正确,但数量不多

  • 平均长度大于512个字

  • 稍微不平衡的数据集

我认为这是一个多类分类问题,我想用这个数据集对BERT进行微调。为了做到这一点,我使用了
Ktrain
包,基本上遵循了教程。下面是我的代码:

(x_train, y_train), (x_test, y_test), preproc = text.texts_from_array(
                                                                    x_train=x_train, 
                                                                    y_train=y_train,
                                                                    x_test=x_test, 
                                                                    y_test=y_test,
                                                                    class_names=categories,
                                                                    preprocess_mode='bert',
                                                                    maxlen= 510,
                                                                    max_features=35000)

model = text.text_classifier('bert', train_data=(x_train, y_train), preproc=preproc)
learner = ktrain.get_learner(model, train_data=(x_train, y_train), batch_size=6)
learner.fit_onecycle(2e-5, 4)
然而,我得到的验证准确率只有25%左右,这太低了

          precision-recall f1-score support

   1       0.33      0.40      0.36        75
   2       0.27      0.36      0.31        84
   3       0.23      0.24      0.23        58
   4       0.18      0.09      0.12        54
   5       0.33      0.04      0.07        24
我还尝试了head+tail截断策略,因为有些文章相当长,但是性能保持不变

谁能给我一些建议吗

多谢各位

最好的

=========================更新7.21=================

按照卡蒂基的建议,我尝试了“寻找”。下面是结果。似乎2e^-5是一个合理的学习率

simulating training for different learning rates... this may take a few 
moments...
Train on 1182 samples
Epoch 1/2
1182/1182 [==============================] - 223s 188ms/sample - loss: 1.6878 
- accuracy: 0.2487
Epoch 2/2
432/1182 [=========>....................] - ETA: 2:12 - loss: 3.4780 - 
accuracy: 0.2639
done.
Visually inspect loss plot and select learning rate associated with falling 
loss

我只是试着用一些权重来运行它:

{0: 0,
 1: 0.8294736842105264,
 2: 0.6715909090909091,
 3: 1.0844036697247708,
 4: 1.1311004784688996,
 5: 2.0033898305084747}
结果如下。变化不大

          precision    recall  f1-score   support

       1       0.43      0.27      0.33        88
       2       0.22      0.46      0.30        69
       3       0.19      0.09      0.13        64
       4       0.13      0.13      0.13        47
       5       0.16      0.11      0.13        28

accuracy                            0.24       296
macro avg       0.23      0.21      0.20       296
weighted avg    0.26      0.24      0.23       296

array([[24, 41,  9,  8,  6],
       [13, 32,  6, 12,  6],
       [ 9, 33,  6, 14,  2],
       [ 4, 25, 10,  6,  2],
       [ 6, 14,  0,  5,  3]])
================更新7.22=============

为了得到一些基线结果,我将5点尺度上的分类问题分解为二元问题,即预测正或负。这一次,准确率提高到55%左右。以下是我的策略的详细说明:

training data: 956 samples (excluding those classified as neutural)
truncation strategy: use the first 128 and last 128 tokens
(x_train,  y_train), (x_test, y_test), preproc_l1 = 
                     text.texts_from_array(x_train=x_train, y_train=y_train,    
                     x_test=x_test, y_test=y_test                      
                     class_names=categories_1,                      
                     preprocess_mode='bert',                                                          
                     maxlen=  256,                                                                  
                     max_features=35000)
Results:
              precision    recall  f1-score   support

       1       0.65      0.80      0.72       151
       2       0.45      0.28      0.35        89

accuracy                               0.61       240
macro avg          0.55      0.54      0.53       240
weighted avg       0.58      0.61      0.58       240

array([[121,  30],
       [ 64,  25]])
然而,我认为55%仍然不是一个令人满意的准确率,略好于随机猜测

=============更新7.26============

根据Marcos Lima的建议,我在我的程序中又采取了几个步骤:

  • 在Ktrain pkg进行预处理之前,删除所有数字、标点符号和冗余空格。(我原以为Ktrain pkg能帮我做到这一点,但不确定)

  • 我使用示例中任何文本的前384个和后128个标记。这就是我所说的“头+尾”策略

  • 任务仍然是二进制分类(正与负)

  • 这是学习曲线图。它和我之前发布的一样。而且它看起来仍然与Marcos Lima发布的非常不同:

    下面是我的结果,这可能是我得到的最好的结果

    begin training using onecycle policy with max lr of 1e-05...
    Train on 1405 samples
    Epoch 1/4
    1405/1405 [==============================] - 186s 133ms/sample - loss: 0.7220 
    - accuracy: 0.5431
    Epoch 2/4
    1405/1405 [==============================] - 167s 119ms/sample - loss: 0.6866 
    - accuracy: 0.5843
    Epoch 3/4
    1405/1405 [==============================] - 166s 118ms/sample - loss: 0.6565 
    - accuracy: 0.6335
    Epoch 4/4
    1405/1405 [==============================] - 166s 118ms/sample - loss: 0.5321 
    - accuracy: 0.7587
    
                 precision    recall  f1-score   support
    
           1       0.77      0.69      0.73       241
           2       0.46      0.56      0.50       111
    
    accuracy                           0.65       352
    macro avg       0.61      0.63      0.62       352
    weighted avg       0.67      0.65      0.66       352
    
    array([[167,  74],
           [ 49,  62]])
    

    注:我认为pkg很难很好地完成我的任务的原因可能是这个任务类似于分类和情绪分析的结合。新闻文章的经典分类任务是对新闻所属的类别进行分类,例如生物学、经济学、体育。在不同类别中使用的词是相当不同的。另一方面,情绪分类的经典例子是分析Yelp或IMDB评论。我的猜测是,这些文本在表达他们的情绪方面非常直截了当,而我的样本《经济新闻》中的文本在出版前经过了精心润色和精心组织,因此情绪可能总是以某种伯特可能无法察觉的隐含方式出现。

    试着将问题视为文本回归任务,如,使用ktrain

    尝试超参数优化对其进行训练

    在进行
    学习之前,调整一个周期(2e-5,4)
    。尝试:
    learner.lr\u find(show\u plot=True,max\u epochs=2)

    所有的班级都有大约20%的权重吗? 也许可以试试这种款式:

    MODEL_NAME = 'bert'
    t = text.Transformer(MODEL_NAME, maxlen=500, class_names=train_b.target_names)
    
    .....
    .....
    
    # the one we got most wrong
    learner.view_top_losses(n=1, preproc=t)
    
    对于以上级别,增加权重


    验证集是分层抽样还是随机抽样?

    学习曲线的形式不是预期的

    我的曲线(上图)显示TR应该在1e-5左右,但你的曲线是平的

    尝试预处理您的数据:

    • 删除数字和表情符号
    • 重新检查数据是否有错误(通常在y_列中)
    • 如果不是英语,请使用您的语言模型或多种语言
    你说:

    平均长度大于512个字


    尝试将每个文本分成512个标记,因为当BERT模型截断它时,您可能会丢失很多分类信息。

    谢谢您的建议。我试着将其作为文本回归运行。我最终得到了1.1左右的MAE,考虑到这是1~5的范围,1.1的MAE似乎相当大。我说的对吗?谢谢你的评论。我刚刚更新了我的帖子。根据你的建议,我没有看到明显的改善。验证集具有随机抽样。此时,我建议您尝试使用基本的
    RNN
    模型来获得基线概念。我在一家类似的公司工作过。希望能有所帮助。非常感谢您的评论。我已经根据你的建议更新了我的帖子。他们更好了,但仍然没有达到我的期望。我目前正在使用头+尾策略来处理超过512篇的文章。这就是你的建议吗?或者你的意思是我把每篇文章分成不同的部分,然后以某种方式将它们聚合起来?你可以将每篇文章转换成几个样本。例如,如果您有一个2000标记长的文本,您可以使用随机选择的句子生成四个大约500长的样本。这只是一次尝试,但可能会奏效。我用NBSVM分类得到更快更好的结果。尝试比较它们。建议的bert批处理大小为16,32,尝试使用它。下面是一篇关于使用BERT进行多类文本分类的文章,可能会有所帮助:另外,我建议增加批量,而不是减少基于本文的学习,这篇文章来自Google:arxiv.org/abs/1711.00489
    MODEL_NAME = 'bert'
    t = text.Transformer(MODEL_NAME, maxlen=500, class_names=train_b.target_names)
    
    .....
    .....
    
    # the one we got most wrong
    learner.view_top_losses(n=1, preproc=t)