我正在使用nltk
和sklearn
构建基本的NLP计划。我在数据库中有一个大型数据集,我想知道训练分类器的最佳方法是什么。
建议以块的形式下载训练数据并将每个块传递给分类器吗?这是可能的,还是我会覆盖从前一个块中学到的东西?
from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.naive_bayes import MultinomialNB
while True:
training_set, proceed = download_chunk() # pseudo
trained = SklearnClassifier(MultinomialNB()).train(training_set)
if not proceed:
break
这通常是怎么做的?我想避免长时间保持数据库连接打开。
答案 0 :(得分:7)
当你每次创建一个新的SklearnClassifier对象时,你现在这样做的方式实际上只会覆盖训练数据中每个块的分类器。您需要做的是在进入训练循环之前实例化SklearnClassifier。但是,查看代码here,似乎NLTK SklearnClassifier使用底层Sklearn模型的fit
方法。这意味着一旦训练模型,您就无法实际更新模型。您需要做的是直接实例化Sklearn模型并使用partial_fit
方法。这样的事情应该有效:
from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB() # must instantiate classifier outside of the loop or it will just get overwritten
while True:
training_set, proceed = download_chunk() # pseudo
clf.partial_fit(training_set)
if not proceed:
break
最后,您将拥有一个MultinomialNB()分类器,该分类器已针对您的每个数据块进行过培训。
通常情况下,如果整个数据集适合内存,只需下载整个内容并调用fit
一次就更有效(在这种情况下,您实际上可以使用nltk SklearnClassifier)。请参阅有关partial_fit
方法here的说明。但是,如果您无法将整个集合放入内存中,那么通常的做法是训练数据块。您可以通过多次调用数据库或从数据库中提取所有信息,将其放在硬盘驱动器上的CSV中,然后从那里读取数据块来完成此操作。
如果您正在与其他用户一起使用共享数据库,那么DBA可能希望您一次性提取所有这些数据库,因为这会(可能)占用更少的数据库资源,而不是对数据库进行多次单独的较小调用将。