我正在使用 nltk 和 sklearn 构建一个基本的 NLP 程序。我在数据库中有一个大型数据集,我想知道训练分类器的最佳方法是什么。
以 block 的形式下载训练数据并将每个 block 传递给分类器是否可取?这甚至可能吗,或者我会覆盖从前一个 block 中学到的东西吗?
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
这通常是如何完成的?我想避免数据库连接打开的时间过长。
请您参考如下方法:
当您每次创建新的 SklearnClassifier 对象时,您现在的做法实际上只会覆盖训练数据中每个 block 的分类器。您需要做的是在进入训练循环之前实例化 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() 分类器,该分类器已针对每个数据 block 进行了训练。
通常,如果整个数据集都适合内存,那么只下载整个数据集并调用一次 fit 会更高效(在这种情况下,您实际上可以使用 nltk SklearnClassifier)。请参阅有关 partial_fit 方法的说明 here .但是,如果您无法将整个集合放入内存中,那么通常的做法是对数据 block 进行训练。为此,您可以多次调用数据库,或者从数据库中提取所有信息,将其以 CSV 格式放在硬盘上,然后从那里读取其中的数据 block 。
注意事项
如果您与其他用户使用共享数据库,DBA 可能更喜欢您一次提取所有数据库,因为与对数据库进行多次单独的较小调用相比,这(可能)占用的数据库资源更少会的。
