我在Postgres数据库中存储了约30万个文档,这些文档用主题类别标记(总共约有150个类别)。我还有另外15万个尚未分类的文档。我正在尝试找到以编程方式对它们进行分类的最佳方法。
我一直在探索NLTK及其朴素贝叶斯分类器。似乎是一个很好的起点(如果您可以为此任务提出更好的分类算法,我将不胜枚举)。
我的问题是我没有足够的RAM来一次对所有150个类别/ 300k文档进行NaiveBayesClassifier训练(对使用8GB的5个类别进行训练)。此外,分类器的准确性似乎随着我对更多类别的训练而下降(2个类别的准确度为90%,5个类别的准确度为81%,10个类别的准确度为61%)。
我是否应该一次对5个类别的分类器进行训练,然后通过分类器运行所有150k文档以查看是否存在匹配项?看起来这是可行的,除了会出现很多误报,因为实际上分类匹配是最好的,否则那些与分类没有真正匹配的文档会被分类器误入歧途。一种方法,使分类器具有“以上皆非”选项,以防文档不适合任何类别?
这是我的测试课http://gist.github.com/451880
您应该首先将文档转换为TF-log(1 + IDF)向量:词频是稀疏的,因此您应该使用以term为键的python dict并作为值计数,然后除以总计数即可得出全局频率。
另一种解决方案是将abs(hash(term))用作正整数键。然后使用scipy.sparse向量,它比python dict更方便,更有效地执行线性代数运算。
还可以通过平均属于同一类别的所有带标签文档的频率来构建150个频率向量。然后,对于要标记的新文档,您可以计算 文档向量和每个类别向量之间的余弦相似度,然后选择最相似的类别作为文档的标签。
如果这还不够好,那么您应该尝试使用L1罚分来训练逻辑回归模型,如scikit- learn的示例中所述(这是liblinear的包装器,如@ephes所述)。用于训练逻辑回归模型的向量应该是先前引入的TD- log(1 + IDF)向量,以获得良好的性能(精度和召回率)。scikit learning lib提供了一个sklearn.metrics模块,该模块具有用于计算给定模型和给定数据集的分数的例程。
对于较大的数据集:您应该尝试使用vowpal wabbit,它可能是解决大规模文档分类问题的最快兔子(但不容易使用python包装器AFAIK)。