我正在尝试使用k-means聚类来对文本文档进行分类。是否可以对一组文档进行tfidf向量化,然后进行计算,再添加更多的文档进行分类?
这是我目前的进展
true_k = 4vectorizer = TfidfVectorizer(stop_words='english')X = vectorizer.fit_transform(documents)model = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)model.fit(X)
我该如何向X中添加更多的文档?因为我想将X进行pickle处理并保存。
回答:
实际上这非常简单(与被接受的答案相反,那答案认为这很复杂 – 其实不然)。只需拼接你的数据,并重复使用相同的向量化器(如果你创建一个新的,或者如被接受的答案所建议的那样重新拟合旧的,它会改变其估计,因此你会得到不同的特征空间),因此你也需要对其进行pickle处理。
true_k = 4vectorizer = TfidfVectorizer(stop_words='english')X = vectorizer.fit_transform(documents)model = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)model.fit(X)
现在你获得了新的数据,documents2,只需执行以下操作
X2 = vectorizer.transform(documents2)X = np.vstack((X, X2))model.fit(X) # 最佳情况下,你会从之前的解决方案开始,但sklearn目前还不支持
然而,请记住,这假设你的第一批文档已经代表了整个数据集。换句话说,你将自己限制在第一批文档中的词汇上,并且idf归一化也不会重新拟合。你实际上可以消除这两个限制,但你需要实现自己的 – 在线tfidf向量化器,它可以更新其估计。这并不难做到,但你需要(在每批新文档之后)也更新之前的文档(因为idf部分会发生变化)。更简单的解决方案是只保留countvectorizer并更新它,然后独立计算“idf”部分并在kmeans之前应用它。