我正在使用朴素贝叶斯分类器将数千个文档分类为 30 个不同的类别。我已经实现了一个朴素贝叶斯分类器,并且通过一些特征选择(主要是过滤无用的词),我得到了大约 30% 的测试准确率和 45% 的训练准确率。这比随机要好得多,但我希望它更好。
我已经尝试用 NB 实现 AdaBoost,但它似乎并没有给出明显更好的结果(文献似乎对此有分歧,一些论文说 AdaBoost 和 NB 并没有给出更好的结果,其他的则有)。您是否知道任何其他可能提供更好准确性的 NB 扩展?
我正在使用朴素贝叶斯分类器将数千个文档分类为 30 个不同的类别。我已经实现了一个朴素贝叶斯分类器,并且通过一些特征选择(主要是过滤无用的词),我得到了大约 30% 的测试准确率和 45% 的训练准确率。这比随机要好得多,但我希望它更好。
我已经尝试用 NB 实现 AdaBoost,但它似乎并没有给出明显更好的结果(文献似乎对此有分歧,一些论文说 AdaBoost 和 NB 并没有给出更好的结果,其他的则有)。您是否知道任何其他可能提供更好准确性的 NB 扩展?
根据我的经验,经过适当训练的朴素贝叶斯分类器通常非常准确(而且训练速度非常快——明显快于我曾经使用过的任何分类器构建器)。
所以当你想改进分类器预测时,你可以看几个地方:
调整分类器(调整分类器的可调参数);
应用某种分类器组合技术(例如,集成、提升、装袋);或者你可以
查看提供给分类器的数据——添加更多数据、改进基本解析或优化从数据中选择的特征。
w/r/t 朴素贝叶斯分类器,参数调整是有限的;我建议关注你的数据——即你的预处理质量和特征选择。
一、数据解析(预处理)
我假设您的原始数据类似于每个数据点的原始文本字符串,通过一系列处理步骤,您将每个字符串转换为每个数据点的结构化向量(一维数组),使得每个偏移量对应一个特征(通常是一个词)并且该偏移量中的值对应于频率。
词干:手动还是使用词干库?流行的开源软件是 Porter、Lancaster 和 Snowball。因此,例如,如果您在给定的数据点中有术语程序员、程序、编程、编程,那么词干分析器会将它们简化为单个词干(可能是program),因此该数据点的词向量的值为 4功能程序,这可能是您想要的。
同义词查找:与词干提取相同的想法——将相关词折叠成一个词;因此同义词查找器可以识别开发人员、程序员、编码员和软件工程师,并将它们整合到一个术语中
中性词:在不同类别中频率相似的词的特征很差
二、特征选择
考虑 NBC 的一个典型用例:过滤垃圾邮件;您可以很快看到它是如何失败的,也可以很快看到如何改进它。例如,高于平均水平的垃圾邮件过滤器具有细微的特征,例如:全部大写单词的频率、标题中单词的频率以及标题中感叹号的出现。此外,最好的特征通常不是单个词,而是例如词对或更大的词组。
三、特定分类器优化
不是 30 个类使用“一对多”方案——换句话说,您从一个二类分类器(A 类和“所有其他”)开始,然后将“所有其他”类中的结果返回到分类为 B 类和“所有其他”等的算法。
Fisher 方法(可能是优化朴素贝叶斯分类器的最常用方法。)对我来说,我认为 Fisher 是对输入概率进行归一化(更准确地说是标准化)NBC 使用特征概率来构建“整个文档”概率. Fisher 方法计算文档每个特征的类别概率,然后组合这些特征概率,并将组合概率与一组随机特征的概率进行比较。
我建议使用SGDClassifier并根据正则化强度对其进行调整。
还尝试通过调整TFIFVectorizer的参数来调整您正在使用的 TFIDF 中的公式。
我通常会看到,对于文本分类问题,SVM 或 Logistic Regressioin在训练一对一时优于 NB。正如你在斯坦福人的这篇关于更长文档的好文章中看到的那样, SVM 的性能优于 NB。使用 SVM 和 NB ( NBSVM )组合的论文的代码在这里。
其次,调整您的 TFIDF 公式(例如次线性 tf、smooth_idf)。
使用 l2 或 l1归一化(Tfidfvectorization 中的默认值)对样本进行归一化,因为它可以补偿不同的文档长度。
多层感知器通常比 NB 或 SVM 获得更好的结果,因为引入了许多文本分类问题所固有的非线性。我已经使用 Theano/Lasagne 实现了一个高度并行的,它易于使用并可在此处下载。
尝试调整您的 l1/l2/elasticnet 正则化。它对 SGDClassifier/SVM/Logistic 回归产生了巨大的影响。
尝试使用可在 tfidfvectorizer 中配置的n-gram 。
如果您的文档有结构(例如有标题),请考虑对不同部分使用不同的功能。例如,如果 word1 出现在文档的标题中,则将 title_word1 添加到您的文档中。
考虑使用文档的长度作为特征(例如单词或字符的数量)。
考虑使用有关文档的元信息(例如创建时间、作者姓名、文档的 url 等)。
最近Facebook发布了他们的FastText 分类代码,该代码在许多任务中表现得非常好,一定要尝试一下。
使用拉普拉斯校正和 AdaBoost。
在 AdaBoost 中,首先为训练数据集中的每个数据元组分配一个权重。使用该init_weights
方法设置初始权重,该方法将每个权重初始化为1/d
,其中d
是训练数据集的大小。
然后,generate_classifiers
调用一个运行k
时间的方法,创建k
朴素贝叶斯分类器的实例。然后对这些分类器进行加权,并在每个分类器上运行测试数据。分类器的加权“投票”之和构成最终分类。
我们将概率空间更改为对数概率空间,因为我们通过乘以概率来计算概率,结果会非常小。当我们更改为对数概率特征时,我们可以解决欠载问题。
当我们在特征之间存在相关性时,Naive Byes 的工作基于独立性假设,这意味着一个特征依赖于其他特征,那么我们的假设将失败。更多关于相关性的信息可以在这里找到
朴素贝叶斯比逻辑回归需要更少的数据,因为它只需要数据来理解每个属性与输出变量的概率关系,而不是交互。
如果测试数据集有零频率问题,应用平滑技术“拉普拉斯校正”来预测测试数据集的类别。
更多内容在以下帖子中得到了很好的描述,请参阅下面的帖子。
保持 n 尺寸小也使 NB 给出高精度结果。在核心,随着 n 尺寸的增加,其精度会降低,
选择它们之间相关性较小的特征。并尝试一次使用不同的功能组合。