doc2vec 如何聚类 DocvecsArray
doc2vec How to cluster DocvecsArray
我根据在网上找到的示例修补了以下代码:
# gensim modules
from gensim import utils
from gensim.models.doc2vec import LabeledSentence
from gensim.models import Doc2Vec
from sklearn.cluster import KMeans
# random
from random import shuffle
# classifier
class LabeledLineSentence(object):
def __init__(self, sources):
self.sources = sources
flipped = {}
# make sure that keys are unique
for key, value in sources.items():
if value not in flipped:
flipped[value] = [key]
else:
raise Exception('Non-unique prefix encountered')
def __iter__(self):
for source, prefix in self.sources.items():
with utils.smart_open(source) as fin:
for item_no, line in enumerate(fin):
yield LabeledSentence(utils.to_unicode(line).split(), [prefix + '_%s' % item_no])
def to_array(self):
self.sentences = []
for source, prefix in self.sources.items():
with utils.smart_open(source) as fin:
for item_no, line in enumerate(fin):
self.sentences.append(LabeledSentence(utils.to_unicode(line).split(), [prefix + '_%s' % item_no]))
return self.sentences
def sentences_perm(self):
shuffle(self.sentences)
return self.sentences
sources = {'test.txt' : 'DOCS'}
sentences = LabeledLineSentence(sources)
model = Doc2Vec(min_count=1, window=10, size=100, sample=1e-4, negative=5, workers=8)
model.build_vocab(sentences.to_array())
for epoch in range(10):
model.train(sentences.sentences_perm())
print(model.docvecs)
我的 test.txt 文件每行包含一个段落。
代码运行良好并为每一行文本生成 DocvecsArray
我的目标是得到这样的输出:
集群 1:[DOC_5,DOC_100,...DOC_N]
集群 2:[DOC_0,DOC_1,...DOC_N]
我找到了 ,但输出是:
第 1 组:[单词,单词...单词]
集群 2:[单词,单词...单词]
如何更改代码并获取文档簇?
看起来你快到了。
您正在输出一组向量。对于 sklearn 包,您必须将它们放入一个 numpy 数组中 - 使用 numpy.toarray() 函数可能是最好的。 The documentation KMeans 非常出色,甚至在整个库中都很好。
请注意,与 KMeans 相比,我在 DBSCAN 方面的运气要好得多,它们都包含在同一个 sklearn 库中。 DBSCAN 不要求您指定要在输出中包含多少个聚类。
两个链接中都有注释完善的代码示例。
在我的例子中,我使用了:
for doc in docs:
doc_vecs = model.infer_vector(doc.split())
# creating a matrix from list of vectors
mat = np.stack(doc_vecs)
# Clustering Kmeans
km_model = KMeans(n_clusters=5)
km_model.fit(mat)
# Get cluster assignment labels
labels = km_model.labels_
# Clustering DBScan
dbscan_model = DBSCAN()
labels = dbscan_model.fit_predict(mat)
其中model为预训练的Doc2Vec模型。在我的例子中,我不需要将相同的训练文档聚类,而是将新文档保存在 docs
列表
中
我根据在网上找到的示例修补了以下代码:
# gensim modules
from gensim import utils
from gensim.models.doc2vec import LabeledSentence
from gensim.models import Doc2Vec
from sklearn.cluster import KMeans
# random
from random import shuffle
# classifier
class LabeledLineSentence(object):
def __init__(self, sources):
self.sources = sources
flipped = {}
# make sure that keys are unique
for key, value in sources.items():
if value not in flipped:
flipped[value] = [key]
else:
raise Exception('Non-unique prefix encountered')
def __iter__(self):
for source, prefix in self.sources.items():
with utils.smart_open(source) as fin:
for item_no, line in enumerate(fin):
yield LabeledSentence(utils.to_unicode(line).split(), [prefix + '_%s' % item_no])
def to_array(self):
self.sentences = []
for source, prefix in self.sources.items():
with utils.smart_open(source) as fin:
for item_no, line in enumerate(fin):
self.sentences.append(LabeledSentence(utils.to_unicode(line).split(), [prefix + '_%s' % item_no]))
return self.sentences
def sentences_perm(self):
shuffle(self.sentences)
return self.sentences
sources = {'test.txt' : 'DOCS'}
sentences = LabeledLineSentence(sources)
model = Doc2Vec(min_count=1, window=10, size=100, sample=1e-4, negative=5, workers=8)
model.build_vocab(sentences.to_array())
for epoch in range(10):
model.train(sentences.sentences_perm())
print(model.docvecs)
我的 test.txt 文件每行包含一个段落。
代码运行良好并为每一行文本生成 DocvecsArray
我的目标是得到这样的输出:
集群 1:[DOC_5,DOC_100,...DOC_N]
集群 2:[DOC_0,DOC_1,...DOC_N]
我找到了
第 1 组:[单词,单词...单词]
集群 2:[单词,单词...单词]
如何更改代码并获取文档簇?
看起来你快到了。
您正在输出一组向量。对于 sklearn 包,您必须将它们放入一个 numpy 数组中 - 使用 numpy.toarray() 函数可能是最好的。 The documentation KMeans 非常出色,甚至在整个库中都很好。
请注意,与 KMeans 相比,我在 DBSCAN 方面的运气要好得多,它们都包含在同一个 sklearn 库中。 DBSCAN 不要求您指定要在输出中包含多少个聚类。
两个链接中都有注释完善的代码示例。
在我的例子中,我使用了:
for doc in docs:
doc_vecs = model.infer_vector(doc.split())
# creating a matrix from list of vectors
mat = np.stack(doc_vecs)
# Clustering Kmeans
km_model = KMeans(n_clusters=5)
km_model.fit(mat)
# Get cluster assignment labels
labels = km_model.labels_
# Clustering DBScan
dbscan_model = DBSCAN()
labels = dbscan_model.fit_predict(mat)
其中model为预训练的Doc2Vec模型。在我的例子中,我不需要将相同的训练文档聚类,而是将新文档保存在 docs
列表