我有一个问题,根据它们的相似性将单词聚类成多个组/簇。 相似性实际上是使用WordNet词汇数据库测量的语义相似度。在提取和计算语义相似度后,我得到了n * n对称矩阵的形式:
A B C D A 1 0.2 0.5 0.0 B 0.2 1 0.0 0.3 C 0.5 0.0 1 0.8 D 0.0 0.3 0.8 1
矩阵由从大规模数据集中提取的10万个单词构成。
我的问题是(由于我对聚类知之甚少,这很简单),可以用于此目的的适当聚类技术是什么?他们的任何java工具都是这样做的,甚至是excel中的工具包所以可以直接使用?教程?任何帮助都是真诚的赞赏..
答案 0 :(得分:1)
有各种各样的层次聚类技术,其中大多数可能适合您的问题。两种主要类型是自下而上(凝聚)和自上而下(分裂)。通常,自下而上更容易实现,因此更频繁地使用,而自上而下可以更有效的方式实现。除非速度对你来说是一个主要问题,否则你最好不要自下而上,特别是因为你是新手。在某些情况下,一种方法可能会胜过另一种方法,但这往往很大程度上取决于您的确切数据。
区分不同算法的主要其他功能是如何计算群集之间的距离。请注意,大多数聚类算法使用距离,而您具有相似度值。距离和相似度基本上是彼此相反的,因此you can get distance with 1/(similarity+1)
或者,因为您的相似度都小于或等于1,您可以将距离计算为1 - similarity
。计算簇之间距离的最常用技术是:
UPGMA是这种算法的一个典型例子,如果你搜索谷歌有各种各样的java实现(我不能评论哪个好或坏,因为我不是真的知道Java)。 Multidendrograms和HAC都是更一般的分层凝聚聚类的Java实现。
答案 1 :(得分:0)
K最近邻居为共现矩阵产生非常好的聚类,例如你在那里的聚类矩阵。我使用K均值快速blog post汇总语义相似的单词,但这里是快速代码:
from __future__ import division
from sklearn.cluster import KMeans
from numbers import Number
from pandas import DataFrame
import sys, codecs, numpy
class autovivify_list(dict):
'''Pickleable class to replicate the functionality of collections.defaultdict'''
def __missing__(self, key):
value = self[key] = []
return value
def __add__(self, x):
'''Override addition for numeric types when self is empty'''
if not self and isinstance(x, Number):
return x
raise ValueError
def __sub__(self, x):
'''Also provide subtraction method'''
if not self and isinstance(x, Number):
return -1 * x
raise ValueError
def build_word_vector_matrix(vector_file, n_words):
'''Iterate over the GloVe array read from sys.argv[1] and return its vectors and labels as arrays'''
numpy_arrays = []
labels_array = []
with codecs.open(vector_file, 'r', 'utf-8') as f:
for c, r in enumerate(f):
sr = r.split()
labels_array.append(sr[0])
numpy_arrays.append( numpy.array([float(i) for i in sr[1:]]) )
if c == n_words:
return numpy.array( numpy_arrays ), labels_array
return numpy.array( numpy_arrays ), labels_array
def find_word_clusters(labels_array, cluster_labels):
'''Read in the labels array and clusters label and return the set of words in each cluster'''
cluster_to_words = autovivify_list()
for c, i in enumerate(cluster_labels):
cluster_to_words[ i ].append( labels_array[c] )
return cluster_to_words
if __name__ == "__main__":
input_vector_file = sys.argv[1]
n_words = int(sys.argv[2])
reduction_factor = float(sys.argv[3])
clusters_to_make = int( n_words * reduction_factor )
df, labels_array = build_word_vector_matrix(input_vector_file, n_words)
kmeans_model = KMeans(init='k-means++', n_clusters=clusters_to_make, n_init=10)
kmeans_model.fit(df)
cluster_labels = kmeans_model.labels_
cluster_inertia = kmeans_model.inertia_
cluster_to_words = find_word_clusters(labels_array, cluster_labels)
for c in cluster_to_words:
print cluster_to_words[c]
如果将此脚本另存为cluster_vectors.py,则可以运行:
wget http://www-nlp.stanford.edu/data/glove.6B.300d.txt.gz
gunzip glove.6B.300d.txt.gz
python cluster_vectors.py glove.6B.300d.txt 10000 .1
读取GloVe单词向量的前10000行(从术语共现推断出的语义单词向量)并将这些单词聚类为10000 * .1 = 1000个簇。群集看起来像这样:
[u'Chicago', u'Boston', u'Houston', u'Atlanta', u'Dallas', u'Denver', u'Philadelphia', u'Baltimore', u'Cleveland', u'Pittsburgh', u'Buffalo', u'Cincinnati', u'Louisville', u'Milwaukee', u'Memphis', u'Indianapolis', u'Auburn', u'Dame']
[u'Product', u'Products', u'Shipping', u'Brand', u'Customer', u'Items', u'Retail', u'Manufacturer', u'Supply', u'Cart', u'SKU', u'Hardware', u'OEM', u'Warranty', u'Brands']
[u'home', u'house', u'homes', u'houses', u'housing', u'offices', u'household', u'acres', u'residence']
[...]
[u'Night', u'Disney', u'Magic', u'Dream', u'Ultimate', u'Fantasy', u'Theme', u'Adventure', u'Cruise', u'Potter', u'Angels', u'Adventures', u'Dreams', u'Wonder', u'Romance', u'Mystery', u'Quest', u'Sonic', u'Nights']
我希望这有帮助!