我正在分析大约200万个原始单词的语料库。我使用gensim的word2vec构建模型,使用sklearn TSNE嵌入向量,并使用sklearn DBSCAN对向量进行聚类(来自word2vec,而不是TSNE)。TSNE的输出看起来很正确:单词在2D空间中的布局似乎反映了它们的语义。有一组拼写错误、衣服等
但是,我很难让DBSCAN输出有意义的结果。它似乎标记了“0”组中的几乎所有内容(图片中的浅绿色)。当我增加epsilon时,“0”组接管了一切。下面是epsilon=10和epsilon=12.5的截图。当epsilon=20时,几乎所有的东西都在同一组中。在
例如,我希望这组“衣服”单词都聚集在一起(它们是unclustered@eps=10)。我还希望在100个簇的数量级上有更多,而不是5-12个簇,并且能够使用epsilon来控制簇的大小和数量。在
那就问几个问题吧。我是否正确理解DBSCAN的使用?有没有其他的聚类算法可能是一个更好的选择?我怎么知道什么是一个好的数据聚类算法?在
假设我的模型调整得很好,考虑到TSNE看起来是对的,这是安全的吗?在
我可以使用哪些其他技术来隔离集群问题?我怎么知道这是我的word2vec模型,我对DBSCAN的使用,还是其他什么?在
下面是我用来执行DBSCAN的代码:
import sys
import gensim
import json
from optparse import OptionParser
import numpy as np
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
# snip option parsing
model = gensim.models.Word2Vec.load(options.file);
words = sorted(model.vocab.keys())
vectors = StandardScaler().fit_transform([model[w] for w in words])
db = DBSCAN(eps=options.epsilon).fit(vectors)
labels = db.labels_
core_indices = db.core_sample_indices_
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
print("Estimated {:d} clusters".format(n_clusters), file=sys.stderr)
output = [{'word': w, 'label': np.asscalar(l), 'isCore': i in core_indices} for i, (l, w) in enumerate(zip(labels, words))]
print(json.dumps(output))
我也遇到了同样的问题,我试着用这些方法,把它贴在这里,希望能对你或其他人有所帮助:
min_samples
值以适应您的问题,在我的例子中,默认值4太高了,因为有些集群也可以由2个单词组成。在也许DBSCAN不是更好的选择,我也在为这个问题接近K均值
反复创建模型也有助于我更好地理解选择哪些参数:
从word2vec的各种可视化效果来看,这些向量可能不会很好地聚集在一起。在
首先,word2vec目标中没有任何东西会鼓励集群。相反,它通过优化词与相邻词的相似度,使相邻词得到相似向量。这对于单词替换的目的是必要的。在
第二,根据这些地块,我不确定是否存在由低密度区域隔开的“密集”区域。相反,数据通常看起来更像一个大团。但当几乎所有的向量都在那个大团中时,它们几乎都在同一个簇中!在
最后,但并非最不重要的是,大多数单词可能不会聚集在一起。是的,数字可能会聚集在一起。你可以期待动词与名词的组合,但是“to bear”和“a bear”与word2vec相同,“bar”(动词和名词)等也是一样的-即使嵌入得很完美,这样的簇还是有太多的多义词无法很好地分开!在
你最好的猜测是增加未成年人和降低epsilon,直到大多数数据是噪音,你找到一些剩余的集群。在
相关问题 更多 >
编程相关推荐