改进 sklearn 中的预测

improving prediction in sklearn

我正在寻找一些指导。我是 NLP 的新手。我可以找到自己的出路 python ok 并编码了一些特征提取器。我想做的是能够使用 sklearn 预测情绪类型,例如快乐、悲伤等。为此,我创建了一个特征提取器,它提取了几个特征,比如开始 POS、结束 POS、标点符号的数量、WH__ 单词的数量等。它创建了这些特征的数组,我试图找到一种方法来使用这些数据用于监督学习。我已经遍历了所有 800 多个句子,并且有目标来回答这些句子。然后我将前 750 个数组和答案数组提供给 sklearn,然后尝试预测最后 50 个。sklearn 预测但预测真的很差。

肯定是我的问题而不是sklearn。我正在寻找一些指导来帮助我完成可能正确的功能建议、关于规范化数据的建议,以及一般的任何指导。下面我会举例说明。

文本文件每行包含一个句子,特征提取器加载每个句子并给出一个特征列表作为数组。 此时数据看起来像

特征数组数组:

    setx=[[1, 0, 5, 12, 5, 13, .... -1, 0, 0, -1, 0, -1, 0, -1, 17, 11, 0],..... many more arrays like this]

目标数组: sety=[0, 0, 0, 0, 0, 0, 0, ..... 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1]

那么我正在使用:

    clf=svm.SVC(gamma=0.001,C=10)
    clf.fit(setx,sety)

下面的tstx和tsty是总特征数组和目标数组的最后50个

    count=0
    for n in tstx:
            print clf.predict(n),',',tsty[count]
            count=count+1
            print "-----"

任何改进预测的建议!我很确定我在某处遗漏了得克萨斯州大小的洞:-)

非常感谢

您的系统的性能可能取决于多种不同的因素,但您使用的功能和您尝试预测的 classes ("targets") 的数量起着根本性的作用.您应该问自己的一些问题是:

  • 你有多少 classes? 学习区分 5 个不同的 classes 比学习 50 个更容易,如果 classes 增加你可能需要更多的例子。
  • class 分布是否平衡? 一般来说,最好的办法是每个 class 都有相同数量的例子(遗憾的是,快乐等...),没有 class 代表过多或不足。

尽管如此,我相信您的问题出在功能上。您在答案中列出的那些似乎对情绪分析不是很有用。句子的起始 POS 并不表示句子中表达的是哪种感觉,我认为也不是 Wh- 词的数量或标点符号的数量。 我真的不能给你一个具体的答案,但我建议你阅读一些关于情感分析的有用特性的东西,这个领域很广阔,你可以采用多种方法。简单搜索 Google 学术搜索,您会发现很多 material 可以从中汲取灵感。例如,您可以先查看 SentiWordNet,它是 WordNet 的情感注释版本,并尝试将其中包含的信息用作模型的特征。

编辑 我认为可能对情绪预测有用的唯一特征是正面和负面词的数量,但我可能是错误的,因为我不是该领域的专家。其他的,比如开始 POS、结束 POS、Wh-words 的数量可能对疑问句和陈述句的预测有用。如果您的代码没有做错任何事情并且结果不好,那么您必须尝试使用​​ more/different 功能。此外,不要为每项任务使用所有功能:您应该为您尝试预测的每件事设计一个特定的功能集,作为对情绪有用的功能 分析可能对其他预测没有用,反之亦然,而且它们实际上可能会使 classifier 感到困惑。有很多方法可以查看某个特征是否对目标具有预测价值,例如参见 [​​=11=],但我从未使用过它们,因此我无法就此提供实际反馈。也许你应该看看 sklearn 中是否已经实现了你可以使用的东西。

阅读@The Coding Monk 对答案的评论,这可能不是一个完整的解决方案,但它可能适用于情绪分析。

  1. 尝试使用 sklearn 的 TfIdfVectorizer,而不是显式提取特征。 TfIdfVectorizer 将根据 TF-IDF 分数

  2. 从你的句子中挑选单词
  3. 因为你已经有了一个分类句子列表,即情感值从 0-6 的句子,你可以很容易地结合 TfIdfVectorizer

  4. 训练分类器
  5. 您可以使用 sklearn Pipeline

  6. 合并这两个步骤

这是它的样子

from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model.logistic import LogisticRegression

pipeline=Pipeline([
    ('vect', TfidfVectorizer(stop_words='english',sublinear_tf=True)),
    ('clf', LogisticRegression())
    ])

from sklearn.grid_search import GridSearchCV
parameters={}#for simplicity, keep this blank for now

gridSearchClassifier = GridSearchCV(pipeline, parameters, n_jobs=3, verbose=1, scoring='accuracy')

一旦我们设置了管道,我们就可以引入我们的训练数据

import pandas as pd
traindf = pd.read_csv('path to your data')
# Create learning matrix
X, y = traindf['sentenceColumn'], traindf['sentimentColumn'].as_matrix()
# Split into Training and Validation Sets

from sklearn.cross_validation import train_test_split
Xtrain, Xvalidate, ytrain, yValidate = train_test_split(X, y, train_size=0.7)

最后,要进行训练,您只需

gridSearchClassifier.fit(Xtrain, ytrain)

现在您可以评估您在验证集上的表现

# Evaluate performance of gridSearchClassifier on Validation Set
    predictions = gridSearchClassifier.predict(Xvalidate)
    print ('Accuracy:', accuracy_score(yValidate, predictions))
    print ('Confusion Matrix:', confusion_matrix(yValidate, predictions))
    print ('Classification Report:', classification_report(yValidate, predictions))

如果您满意,请将您的最后 50 个句子作为您的测试集

testdf = pd.read_csv("path to test data") 
# Predict Sentiment on Test Set
predictions=gridSearchClassifier.predict(testdf['sentenceColumn'])
# Create new column in Test dataframe
testdf['predictedSentiment'] = predictions
# Save the dataframe with the new column
testdf.to_csv("result.csv",index=False)