NLTK:调整LinearSVC分类器的准确度? - 寻找更好的方法/建议

时间:2015-09-03 11:24:54

标签: python machine-learning nlp scikit-learn nltk

问题/主要目标/ TLDR:训练一个分类器,然后给它一个随机评论并获得相应的预测评论评级(星数从1到5) - 只有60%的准确率! :(

我有一个大型数据集,有大约48000个技术产品评论(来自许多不同的作者和来自不同的产品 - 这里不是那么重要(?))和相应的评级(1到5星) 我在每个班级中随机选择了一些评论:

  • 1星级:173条评论(因为有173条不能选1000)
  • 2星级:1000条评论
  • 3星级:1000条评论
  • 4星级:1000条评论
  • 5星级:1000条评论

总共:4173评论 - 此数据以元组格式组织在一个文件(all_reviews_labeled.txt)中,一行评论和评级:

  • ('review text','x star')
  • ('review text','x star')
  • ('review text','x star')
  • ('review text','x star')
  • ...

我的第一个“dummie”方法是:

  1. Tokenize评论文字
  2. POS标记
  3. 获取最常见的双字符串,其中包含一些POS标记规则 最常见的三卦(我已经看过这个规则 - 使用这个POS “文字评论自动生成星级评分”中的模式 - 第7页 - 来自Chong-U Lim,Pablo Ortiz和Sang-Woo Jun的论文:

    for (w1,t1), (w2,t2), (w3,t3) in nltk.trigrams(text):
        if (t1 == 'JJ' or t1 == 'JJS' or t1 == 'JJR') and (t2 == 'NN' or t2 == 'NNS'):
            bi = unicode(w1 + ' ' + w2).encode('utf-8')
            bigrams.append(bi)
        elif (t1 == 'RB' or t1 == 'RBR' or t1 == 'RBS') and (t2 == 'JJ' or t2 == 'JJS' or t2 == 'JJR') and (t3 != 'NN' or t3 != 'NNS'):
            bi = unicode(w1 + ' ' + w2).encode('utf-8')
            bigrams.append(bi)
        elif (t1 == 'JJ' or t1 == 'JJS' or t1 == 'JJR') and (t2 == 'JJ' or t2 == 'JJS' or t2 == 'JJRS') and (t3 != 'NN' or t3 != 'NNS'):
            bi = unicode(w1 + ' ' + w2).encode('utf-8')
            bigrams.append(bi)
        elif (t1 == 'NN' or t1 == 'NNS') and (t2 == 'JJ' or t2 == 'JJS' or t2 == 'JJRS') and (t3 != 'NN' or t3 != 'NNS'):
            bi = unicode(w1 + ' ' + w2).encode('utf-8')
            bigrams.append(bi)
        elif (t1 == 'RB' or t1 == 'RBR' or t1 == 'RBS') and (t2 == 'VB' or t2 == 'VBD' or t2 == 'VBN' or t2 == 'VBG'):
            bi = unicode(w1 + ' ' + w2).encode('utf-8')
            bigrams.append(bi)
        elif (t1 == 'DT') and (t2 == 'JJ' or t2 == 'JJS' or t2 == 'JJRS'):
            bi = unicode(w1 + ' ' + w2).encode('utf-8')
            bigrams.append(bi)
        elif (t1 == 'VBZ') and (t2 == 'JJ' or t2 == 'JJS' or t2 == 'JJRS'):
            bi = unicode(w1 + ' ' + w2).encode('utf-8')
            bigrams.append(bi)
        else:
            continue
    
  4. 提取功能(这里是我有更多疑问的地方 - 我应该这样做 只看这两个功能?):

    features={}
    for bigram,freq in word_features:
        features['contains(%s)' % unicode(bigram).encode('utf-8')] = True
        features["count({})".format(unicode(bigram).encode('utf-8'))] = freq
    return features
    

    featuresets = [(review_features(review),rating)for(review,rating)in tuples_labeled_reviews]

  5. 将训练数据拆分为训练大小和测试大小 (90%的培训 - 10%的测试):

    numtrain = int(len(tuples_labeled_reviews) * 90 / 100)
    train_set, test_set = featuresets[:numtrain], featuresets[numtrain:]
    
  6. 培训SVMc:

    classifier = nltk.classify.SklearnClassifier(LinearSVC())
    classifier.train(train_set)
    
  7. 评估分类器:

    errors = 0
    correct = 0
    for review, rating in test_set:
        tagged_rating = classifier.classify(review)
        if tagged_rating == rating:
            correct += 1
            print("Correct")
            print "Guess: ", tagged_rating
            print "Correct: ", rating
        else:
            errors += 1
    
  8. 到目前为止,我只有60%的准确率...... 我该怎么做才能改善我的预测结果?以前是什么东西,一些文本/评论预处理(如删除停用词/标点符号?)缺少?你能建议我一些其他方法吗?如果真的是分类问题或回归问题,我仍然有点困惑......:/

    请简单解释,或者给我一个“机器学习傻瓜”的链接,或者做我的导师,我保证快速学习! 我在机器学习/语言处理/数据挖掘方面的背景很轻,我用weka(Java)玩过几次,但现在我需要坚持使用Python(nltk + scikit-learn)!

    修改

    1. 现在我也提取unigrams作为功能,unigrams POS标记为'JJ','NN','VB'和'RB'。它将准确度提高到65%。
    2. 我在POS标记之前也应用了文本中的词干和词形还原。它将准确度提高到+ 70%。
    3. 编辑2:

      1. 我已经为我的所有评论提供了分类,48000,分为90%的培训和10%的测试,准确率为91%。

      2. 现在我有32000个新的评论(也标注了)并将它们全部用于测试,平均准确度为62%...我的混淆矩阵如下图所示(除以+1的相等误差) / -1星点,+ 2 / -2,+ 3 / -3 - 因为它只是一个例子):

      3. enter image description here 怎么了?为什么准确度在3星和5星下降得那么多?

1 个答案:

答案 0 :(得分:3)

考虑添加更多功能。对于我的任务,为了找到四位作者之间的文本作者,我使用了以下功能:

  • 句子功能

    • 平均句子长度
    • 音节中的平均句子长度
    • 字符平均句子长度
    • 长句百分比
  • 词汇功能

    • 字数
    • Hapaxes(只见过一次)
    • Dislegomena(单词只见过两次)
    • Dislegomena与Hapaxes的比率
    • 平均字长
    • 词汇多样性
    • YuleK
    • HeransC
    • GuiraudsR
    • 乌伯
    • 相对熵
    • 1lw .. 14lw(包含一个字符,两个字符,包含14个字符的单词的频率)
  • 角色特征
    • 字符a的百分比,
    • 字符b的百分比
    • ...
    • 语料库中50个最常用单词的百分比

对于每个文本,上面构建了它的特征向量。我在SPSS中使用了判别分析。当然,您可以使用SVM或其他分类器。