在语义上聚类词组

时间:2013-12-10 19:27:14

标签: hierarchical-clustering

我有一个问题,根据它们的相似性将单词聚类成多个组/簇。 相似性实际上是使用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中的工具包所以可以直接使用?教程?任何帮助都是真诚的赞赏..

2 个答案:

答案 0 :(得分:1)

有各种各样的层次聚类技术,其中大多数可能适合您的问题。两种主要类型是自下而上(凝聚)和自上而下(分裂)。通常,自下而上更容易实现,因此更频繁地使用,而自上而下可以更有效的方式实现。除非速度对你来说是一个主要问题,否则你最好不要自下而上,特别是因为你是新手。在某些情况下,一种方法可能会胜过另一种方法,但这往往很大程度上取决于您的确切数据。

区分不同算法的主要其他功能是如何计算群集之间的距离。请注意,大多数聚类算法使用距离,而您具有相似度值。距离和相似度基本上是彼此相反的,因此you can get distance with 1/(similarity+1)或者,因为您的相似度都小于或等于1,您可以将距离计算为1 - similarity。计算簇之间距离的最常用技术是:

  • “平均链接” - 两个群集的中心之间的距离。这可以通过取两组中每对成员之间的距离的平均值来计算。
  • “单一链接” - 两个群集中两个最接近成员之间的距离
  • “完整链接” - 两个群集中两个最远的成员之间的距离。

UPGMA是这种算法的一个典型例子,如果你搜索谷歌有各种各样的java实现(我不能评论哪个好或坏,因为我不是真的知道Java)。 MultidendrogramsHAC都是更一般的分层凝聚聚类的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']

我希望这有帮助!