【问题标题】:Feature Selection and Reduction for Text Classification文本分类的特征选择和减少
【发布时间】:2012-11-16 05:36:46
【问题描述】:

我目前正在开发一个简单的情绪分析器项目,以便在单独的案例中有2个和3个类。我正在使用一个 corpus,它在 unique words 方面非常丰富(大约 200.000)。我使用 bag-of-words 方法进行 特征选择 并减少 独特特征 的数量,由于 发生频率的>阈值最终的特征集包括大约 20.000 个特征,实际上减少了 90%,但对于预期的准确性不够强>的测试预测。我依次使用 LibSVMSVM-light 进行训练和预测(linearRBF kernel)和以及一般的 PythonBash

目前观察到的最高准确度约为 75%,我需要至少 90%二元分类就是这种情况。对于多类训练,准确率下降到~60%。我在这两种情况下都需要至少 90%,但不知道如何提高它:通过优化训练参数通过优化特征选择

我看过关于文本分类中特征选择的文章,发现使用了三种不同的方法,实际上它们之间有明显的相关性。这些方法如下:

  • 词袋(BOW)的频率方法
  • 信息增益 (IG)
  • X^2 统计量 (CHI)

第一种方法我已经在用了,但是我用的很简单,需要指导才能更好的使用,以获得足够高的精度。我也缺乏关于 IGCHI 的实际实施的知识,并寻求任何帮助来指导我。

非常感谢,如果您需要任何其他信息以寻求帮助,请告诉我。


  • @larsmans:频率阈值:我正在寻找示例中唯一单词的出现次数,这样如果一个单词在不同示例中出现的频率足够高,它就会包含在特征中设置为一个独特的功能。

  • @TheManWithNoName:首先感谢您为解释文档分类的一般问题所做的努力。我检查并试验了你提出的所有方法和其他方法。我发现 Proportional Difference (PD) 方法最适合特征选择,其中特征是 uni-gram,Term Presence (TP) 用于加权(我不明白为什么您将 Term-Frequency-Inverse-Document-Frequency (TF-IDF) 标记为索引方法,我宁愿将其视为 特征加权 方法)。正如您所提到的,预处理也是此任务的一个重要方面。我使用某些类型的字符串消除来优化数据以及形态解析词干。另请注意,我正在研究土耳其语,与英语相比,它具有不同的特征。最后,我设法在 二元 分类和 ~84% 中达到 ~88% 的准确度(f-measure)multi-class 。这些值是我使用的模型成功的有力证明。这是我到目前为止所做的。现在致力于聚类和归约模型,尝试过 LDALSI 并继续研究 moVMF 可能还有 球形模型 (LDA + moVMF),这似乎更适用于具有客观性质的语料库,如新闻语料库。如果您对这些问题有任何信息和指导,我将不胜感激。我特别需要信息来设置特征空间降维方法(LDA、LSI、moVMF等)和聚类方法(k -手段,分层等)。

【问题讨论】:

  • 你用的是什么频率阈值?
  • 只是一个疯狂的猜测。你的减少已经删除了必要的信息。 SVM 在处理大量维度方面非常出色。你尝试过更大的功能集吗?您在训练中使用的样本量是多少?如果您无法训练更多特征,请尝试训练第二频繁的 20.000 以验证那里没有留下任何信息。和第三常见的词。
  • @clancularius,如果可能的话,您能否更详细地解释一下您用于特征提取和特征选择的技术。我也在研究一个文本分类问题,我的准确率不会超过 61%。

标签: python nlp svm sentiment-analysis feature-extraction


【解决方案1】:

线性支持向量机推荐用于高维特征。根据我的经验,SVM 准确性的最终限制取决于正面和负面的“特征”。您可以进行网格搜索(或者在线性 svm 的情况下,您可以只搜索最佳成本值)以找到最大精度的最佳参数,但最终您会受到特征集可分离性的限制。您没有得到 90% 的事实意味着您仍有一些工作要做,以找到更好的功能来描述您的类成员。

【讨论】:

  • @larsmans 这已经是我的要求了。正如我上面解释的,我正在寻找一种更好的“特征选择”方法,你建议我这样做。在训练我的数据集之前,我已经使用网格函数进行参数选择,但是参数值迭代以参数值结束,这些不会让我的预测准确度高于 ~70-75%。是的,我需要选择我的特征以获得更好的准确度结果,但是如何?你知道如何使用 IG 和 CHI 特征选择方法吗?你知道如何优化词频法的实现吗?
【解决方案2】:

我会推荐降维而不是特征选择。考虑singular value decompositionprincipal component analysis,或者考虑到它是为词袋表示量身定制的,甚至更好,Latent Dirichlet Allocation。这将允许您在概念上保留包含所有单词的表示,但通过利用它们之间的相似性(甚至是同义词类型)关系将它们折叠到更少的维度。

所有这些方法都有相当标准的实现,您可以访问并运行它们——如果您让我们知道您使用的是哪种语言,我或其他人将能够为您指明正确的方向。

【讨论】:

  • 首先感谢您的回复。我正在使用 python 和 bash 脚本。我快速搜索了奇异值分解、主成分分析,特别是 LDA,但我需要时间来了解如何使用它们。我同意你的看法,降维似乎是我的任务的有效选择,但是我不清楚是否需要根据这些方法的理论基础生成自己的降维算法,或者使用已经存在的实施(我不知道)?
  • 使用现有的实现已经绰绰有余了。如果您使用的是 Python,则有用于 LDA 的 gensim(radimrehurek.com/gensim),或者 maplotlib.mlab 具有 SVD/PCA 的实现:matplotlib.org/api/mlab_api.html#matplotlib.mlab.PCA。应该有一些简单的例子,这样你就可以看到它们是如何工作的。
  • 非常感谢,我会看看并通知您改进情况。
【解决方案3】:

这可能有点晚了,但是...

正如 Bee 指出的并且您已经意识到,如果您在分类之前的阶段已经丢失了信息,那么将 SVM 用作分类器是一种浪费。然而,文本分类的过程需要的不仅仅是几个阶段,而且每个阶段都会对结果产生重大影响。因此,在研究更复杂的特征选择措施之前,有许多更简单的可能性,通常需要更低的资源消耗。

在将标记化/表示为词袋格式之前,您是否对文档进行预处理?简单地删除停用词或标点符号可能会大大提高准确性。

您是否考虑过改变您的词袋表示以使用例如词对或 n-gram 来代替?您可能会发现一开始就有更多维度,但它们会进一步压缩并包含更多有用的信息。

同样值得注意的是,降维特征选择/特征提取。不同之处在于特征选择以单变量方式减少维度,即它在不改变当前出现的情况下逐个删除术语,而特征提取(我认为 Ben Allison 指的是)是多变量的,结合一个或多个单个术语一起生成更高的正交术语,(希望)包含更多信息并减少特征空间。

关于您对文档频率的使用,您是仅使用包含词条的文档的概率/百分比,还是使用在文档中找到的词条密度?如果类别一只有 10 个文档,并且每个文档包含一个术语,那么类别一确实与文档相关联。但是,如果类别二只有 10 个文档,每个文档都包含相同的词一百次,那么显然类别二与该词的关系比类别一高得多。如果不考虑术语密度,则此信息将丢失,并且您拥有的类别越少,此损失的影响就越大。同样,只保留高频词并不总是谨慎的,因为它们实际上可能没有提供任何有用的信息。例如,如果一个术语在每个文档中出现一百次,那么它就被认为是一个噪声术语,虽然它看起来很重要,但将它保留在您的功能集中没有实际价值。

另外你如何索引数据,你是使用带有简单布尔索引的向量空间模型还是更复杂的度量,例如 TF-IDF?考虑到您的场景中的类别数量较少,更复杂的度量将是有益的,因为它们可以说明每个类别相对于其在整个数据集中的重要性的术语重要性。

我个人会先尝试上述一些可能性,然后如果您需要额外的性能提升,则考虑使用(或组合)复杂方程来调整特征选择/提取。


附加

根据新信息,听起来您似乎走在了正确的轨道上,并且 84% 以上的准确率(F1 或 BEP - 基于多类问题的准确率和召回率)通常被认为对于大多数数据集来说非常好。可能是您已经成功地从数据中获取了所有信息丰富的特征,或者还有一些仍在修剪中。

话虽如此,可以用作预测特定数据集的积极降维效果的指标是“离群值计数”分析,它使用离群特征中信息增益的下降来确定它的可能性有多大该信息将在特征选择期间丢失。您可以在原始和/或处理后的数据上使用它来估计您应该多积极地修剪特征(或视情况取消修剪它们)。可以在此处找到描述它的论文:

Paper with Outlier Count information

关于将 TF-IDF 描述为一种索引方法,您是正确的,因为它是一种特征加权度量,但我认为它主要用作索引过程的一部分(尽管它也可以用于降维)。这样做的原因是,一些措施更好地针对特征选择/提取,而另一些措施更适合专门在您的文档向量(即索引数据)中进行特征加权。这通常是因为降维措施是基于每个类别确定的,而索引加权措施往往更面向文档,以提供更好的向量表示。

关于LDA、LSI和moVMF,恐怕我对它们的经验太少,无法提供任何指导。不幸的是,我也没有使用过土耳其语数据集或 python 语言。

【讨论】:

  • 我在上面的问题中回答了你。请看一下。顺便说一句,谢谢您的回答。
  • 我已根据您的新信息更新了我的答案。恐怕我现在已经帮不上什么忙了,因为我的博士论文的截止日期快到了……具有讽刺意味的是,这是基于文本分类中使用的阶段的简化、接口和标准化!如果我完成它,我会尽量记住在这个问题中无私地宣传它。
  • 感谢您的努力并感谢您。我会看看你包含的论文并尝试使用它。聚类是个大问题,与分类相比更加模糊,因此我从现在开始就靠运气了=)顺便祝你论文成功,祝你有美好的一天。
  • @TheManWithNoName:很好的答案!喜欢读它。
  • @Yavar 谢谢,非常感谢。
【解决方案4】:

我敢肯定这对海报来说已经太晚了,但也许它对其他人有用。减少特征的卡方方法很容易实现。假设 BoW 二进制分类为 C1 和 C2 类,对于候选特征中的每个特征 f 计算 C1 中 f 的频率;计算总字数 C1;对 C2 重复计算;根据 p 值是否低于某个阈值(例如 p http://streamhacker.com/2010/06/16/text-classification-sentiment-analysis-eliminate-low-information-features/(如果我没记错的话,我相信作者错误地将这种技术应用于他的测试数据,这会使报告的结果产生偏差)。

【讨论】:

    【解决方案5】:

    有一个python 库用于特征选择 TextFeatureSelection。该库以分数的形式为每个单词标记、二元组、三元组等提供区分能力。

    那些了解机器学习中的特征选择方法的人,它基于过滤方法,并为 ML 工程师提供了提高其 NLP 和深度学习模型的分类准确性所需的工具。它有 4 种方法,即 卡方互信息比例差信息增益来帮助选择单词作为输入机器学习分类器之前的特征。

    from TextFeatureSelection import TextFeatureSelection
    
    #Multiclass classification problem
    input_doc_list=['i am very happy','i just had an awesome weekend','this is a very difficult terrain to trek. i wish i stayed back at home.','i just had lunch','Do you want chips?']
    target=['Positive','Positive','Negative','Neutral','Neutral']
    fsOBJ=TextFeatureSelection(target=target,input_doc_list=input_doc_list)
    result_df=fsOBJ.getScore()
    print(result_df)
    
    #Binary classification
    input_doc_list=['i am content with this location','i am having the time of my life','you cannot learn machine learning without linear algebra','i want to go to mars']
    target=[1,1,0,1]
    fsOBJ=TextFeatureSelection(target=target,input_doc_list=input_doc_list)
    result_df=fsOBJ.getScore()
    print(result_df)
    

    编辑:

    它现在也有用于特征选择的遗传算法。

    from TextFeatureSelection import TextFeatureSelectionGA
    #Input documents: doc_list
    #Input labels: label_list
    getGAobj=TextFeatureSelectionGA(percentage_of_token=60)
    best_vocabulary=getGAobj.getGeneticFeatures(doc_list=doc_list,label_list=label_list)
    

    编辑2

    现在还有一种方法TextFeatureSelectionEnsemble,在融合的同时结合了特征选择。它通过文档频率阈值对基本模型进行特征选择。在集成层,它使用遗传算法来识别基本模型的最佳组合并仅保留这些组合。

    from TextFeatureSelection import TextFeatureSelectionEnsemble 
    
    imdb_data=pd.read_csv('../input/IMDB Dataset.csv')
    le = LabelEncoder()
    imdb_data['labels'] = le.fit_transform(imdb_data['sentiment'].values)
    
    #convert raw text and labels to python list
    doc_list=imdb_data['review'].tolist()
    label_list=imdb_data['labels'].tolist()
    
    #Initialize parameter for TextFeatureSelectionEnsemble and start training
    gaObj=TextFeatureSelectionEnsemble(doc_list,label_list,n_crossvalidation=2,pickle_path='/home/user/folder/',average='micro',base_model_list=['LogisticRegression','RandomForestClassifier','ExtraTreesClassifier','KNeighborsClassifier'])
    best_columns=gaObj.doTFSE()`
    

    查看项目了解详情:https://pypi.org/project/TextFeatureSelection/

    【讨论】:

      猜你喜欢
      • 2013-10-13
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      • 2020-08-29
      • 2021-04-27
      • 2013-12-07
      • 2014-09-21
      • 2012-02-05
      相关资源
      最近更新 更多