如何从word2vec向量派生出的k-means簇中找到代表每个簇含义深刻的词?

4

我使用Python中的gensim包来加载预训练好的Google word2vec数据集。然后我想使用k-means算法来找到单词向量中有意义的聚类,并为每个聚类找到代表性单词。我考虑使用对应向量最接近聚类质心的单词来代表该聚类,但是我的实验结果并不理想,不知道这是否是一个好主意。

我的示例代码如下:

import gensim
import numpy as np
import pandas as pd
from sklearn.cluster import MiniBatchKMeans
from sklearn.metrics import pairwise_distances_argmin_min

model = gensim.models.KeyedVectors.load_word2vec_format('/home/Desktop/GoogleNews-vectors-negative300.bin', binary=True)  

K=3

words = ["ship", "car", "truck", "bus", "vehicle", "bike", "tractor", "boat",
       "apple", "banana", "fruit", "pear", "orange", "pineapple", "watermelon",
       "dog", "pig", "animal", "cat", "monkey", "snake", "tiger", "rat", "duck", "rabbit", "fox"]
NumOfWords = len(words)

# construct the n-dimentional array for input data, each row is a word vector
x = np.zeros((NumOfWords, model.vector_size))
for i in range(0, NumOfWords):
    x[i,]=model[words[i]] 

# train the k-means model
classifier = MiniBatchKMeans(n_clusters=K, random_state=1, max_iter=100)
classifier.fit(x)

# check whether the words are clustered correctly
print(classifier.predict(x))

# find the index and the distance of the closest points from x to each class centroid
close = pairwise_distances_argmin_min(classifier.cluster_centers_, x, metric='euclidean')
index_closest_points = close[0]
distance_closest_points = close[1]

for i in range(0, K):
    print("The closest word to the centroid of class {0} is {1}, the distance is {2}".format(i, words[index_closest_points[i]], distance_closest_points[i]))

以下是输出结果:
[2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0]
The closest word to the centroid of class 0 is rabbit, the distance is 1.578625818679259
The closest word to the centroid of class 1 is fruit, the distance is 1.8351978219013796
The closest word to the centroid of class 2 is car, the distance is 1.6586030662247868

在代码中,我有三类单词:车辆、水果和动物。从输出结果可以看出,k-means正确地将所有3类单词聚集在了一起,但使用质心法派生的代表性单词并不是很好,因为对于类别0,我想看到“动物”,但它给出了“兔子”,而对于类别2,我希望看到“车辆”,但它返回了“汽车”。非常感谢任何寻找每个集群良好代表单词的帮助或建议。
1个回答

4
看起来你希望能够通过自动化过程找到一个词簇中的通用术语,类似于上位词,而且希望质心就是该术语。
不幸的是,我没有看到任何声称word2vec会以这种方式安排单词的说法。单词确实倾向于靠近可以替换它们的其他单词,但并没有保证所有共享类型的单词都比其他类型的单词更接近彼此,或者下义词倾向于等距离地与它们的上义词相距,等等。(鉴于word2vec在类比解决方面的成功,可能会出现上位词在类别之间以大致相似的方向偏移其下义词的情况。也就是说,也许大概是'volkswagen' + ('animal' - 'dog') ~ 'car' - 虽然我没有检查过。)
有时候会发现一个有趣的观察结果与词向量相关:对于那些意义更为分散(例如包含多个意思)的单词,它们的原始形式下的词向量往往比那些意义更为明确的单词拥有更低的大小。通常的最相似计算忽略了大小,只是比较原始方向,但搜索更通用的术语可能会偏向于较小的向量。但这只是一个猜测,我没有进行过检查。
您可以查阅有关自动上下位词发现的工作,word2vec向量可能是这种发现过程的一个因素,可以通过正常训练或添加一些新的技巧来强制实现所需的排列。(但是,这种特殊化通常不被gensim默认支持。)
通常会有一些文献来改进word2vec训练过程,使向量更适合特定目的。Facebook Research最近发表的一篇论文 "Poincaré Embeddings for Learning Hierarchical Representations" 似乎与此相关 - 它报告了更好地建模层次结构并在WordNet名词上下位图上进行了特定测试的结果。

非常感谢gojomo的回复。我会查阅关于自动发现上下位词的文档。你知道有哪些R或Python包可以进行上下位词发现吗? - Carter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接