如何提高朴素贝叶斯分类器的准确性?
我使用朴素贝叶斯分类器将几千个文档分为30个不同的类别。 我已经实现了一个朴素贝叶斯分类器,并select了一些function(主要是过滤无用的单词),我已经获得了大约30%的testing精度,45%的训练精度。 这显然比随机好,但我希望它会更好。
我已经尝试过用NB实现AdaBoost,但似乎并没有给出明显的更好的结果(文献似乎分裂了这个,一些论文说AdaBoost与NB没有给出更好的结果,其他人也这么做)。 你知道任何其他扩展NB可能会提供更好的准确性吗?
非常感谢。
根据我的经验,适当训练的朴素贝叶斯分类器通常非常准确(训练速度非常快 – 比我以前使用的任何分类器构build者快得多)。
所以当你想提高分类器预测,你可以看几个地方:
-
调整分类器 (调整分类器的可调参数);
-
应用某种分类器组合技术 (例如,合奏,助推,装袋); 或者你可以
-
查看提供给分类器的数据 – 添加更多数据,改进基本分析,或者细化从数据中select的function。
w / r / t朴素贝叶斯分类器,参数整定有限; 我build议专注于您的数据 – 即您的预处理和特征select的质量。
I.数据parsing(预处理)
我假设你的原始数据是类似于每个数据点的原始文本的string,通过一系列处理步骤,您可以将每个string转换为每个数据点的结构化向量(一维数组),以便每个偏移量对应一个要素通常是一个字),该偏移量的值对应于频率。
-
干扰 :手动或通过使用干扰库? stream行的开源软件有Porter,Lancaster和Snowball。 例如,如果你有程序员,程序员,程序员,程序devise人员在一个给定的数据点,一个词干将减less他们到一个单一的词干(可能是程序 ),所以你的术语向量的数据点将有4function程序,这可能是你想要的。
-
同义词的发现 :与词干相同的概念 – 将相关的单词叠成一个单词; 所以同义词查找器可以识别开发人员,程序员,编码人员和软件工程师,并将其转换为单个术语
-
中性词汇 :跨class级具有相似频率的词使得特征变差
II。 functionselect
考虑一个NBC的原型用例:过滤垃圾邮件; 你可以很快看出它是如何失败的,而且你可以很快看到如何改进它。 例如,高于平均水平的垃圾邮件filter具有细微的特征,例如:全部大写的单词频率,标题中单词的频率以及标题中出现感叹号。 另外, 最好的特征通常不是单个单词,而是例如单词对或者更大的单词组 。
III。 特定的分类器优化
而不是30个类使用“一对多”的scheme – 换句话说,你从一个两级分类器(类A和“其他”)开始,然后在“所有其他”类中的结果被返回到分类为B类和“其他”的algorithm等。
Fisher方法 (可能是优化朴素贝叶斯分类器的最常见的方法)。对我来说,我认为费舍尔正常化 (更正确地说, 标准化 )input概率NBC使用特征概率来构build“全文档”概率。 Fisher方法计算文档的每个特征的类别概率,然后组合这些特征概率,并将该组合概率与随机特征集的概率进行比较。
我build议使用一个SGDClassifier ,并在正则化强度方面进行调整。
也尝试通过调整TFIFVectorizer的参数来调整TFIDF中的公式。
-
我经常看到,对于文本分类问题, SVM或Logistic Regressioin在进行一对一训练时performance优于NB。 正如你可以在斯坦福大学的这篇文章中看到更长的文件SVM胜过NB。 使用SVM和NB( NBSVM )组合的论文的代码就在这里 。
-
其次,调整TFIDF公式(例如,sublinear tf,smooth_idf)。
-
使用l2或l1归一化(Tfidfvectorization中的默认值)归一化您的样本,因为它补偿了不同的文档长度。
-
多层感知器通常比NB或SVM获得更好的结果,因为引入了许多文本分类问题所固有的非线性。 我已经实现了一个高度并行的使用Theano /千层面,这是易于使用和下载在这里 。
-
尝试调整你的l1 / l2 / elasticnet正则化 。 它在SGDClassifier / SVM / Logistic回归中有很大的不同。
-
尝试使用可在tfidfvectorizer中configuration的n-gram 。
-
如果您的文档具有结构(例如有标题 ),请考虑为不同部分使用不同的function。 例如,如果word1发生在文档的标题中,请将title_word1添加到文档中。
-
考虑使用文档的长度作为特征(例如单词或字符的数量)。
-
考虑使用有关文档的元信息 (例如创build时间,作者姓名,文档的URL等)。
-
最近, Facebook发布了他们的FastText分类代码 ,在许多任务中performance非常好,一定要试一试。
使用拉普拉斯校正与AdaBoost。
在AdaBoost中,首先为训练数据集中的每个数据元组分配一个权重。 初始权重是使用init_weights
方法设置的,初始化每个权重为1/d
,其中d
是训练数据集的大小。
然后,调用generate_classifiers
方法,运行k
次,创build朴素贝叶斯分类器的k
实例。 然后对这些分类器进行加权,并在每个分类器上运行testing数据。 分类器的加权“投票”的总和构成最终分类。
保持n尺寸小也使NB给出高精度的结果。 而在核心,随着n尺寸的增加其精度降低,
select它们之间相关性较小的特征。 并尝试一次使用不同的function组合。