将一长串的字符串(单词)聚类为相似性组


31

我手头有以下问题:我有很长的单词列表,可能有名称,姓氏等。我需要将此单词列表聚类,以便类似的单词(例如,具有类似编辑(Levenshtein)距离的单词)出现在同一集群。例如,“算法”和“算法”应该有很高的机会出现在同一集群中。

我很清楚模式识别文献中的经典无监督聚类方法,例如k-means聚类,EM聚类。这里的问题是这些方法对驻留在矢量空间中的点起作用。我在这里手头有弦。到目前为止,根据我的调查工作,关于如何在数值向量空间中表示字符串以及如何计算字符串簇的“均值”的问题似乎还没有得到充分回答。解决这个问题的一种简单方法是将k-Means聚类与Levenshtein距离结合起来,但问题仍然是“如何表示字符串的“均值”?”。有一个权重称为TF-IDF权重,但似乎它主要与“文本文档”聚类的区域有关,而不与单个单词的聚类有关。 http://pike.psu.edu/cleandb06/papers/CameraReady_120.pdf

我在这方面的搜索仍在进行中,但我也想从这里获得一些想法。在这种情况下,您会建议什么?有人知道解决此类问题的任何方法吗?


1
我了解到存在一个名为“ K-medoids”的k-means变体。en.wikipedia.org/wiki/K-medoids它不适用于欧氏距离L2,不需要计算均值。它使用最接近群集中其他数据点的数据点作为“ medoid”。
Ufuk Can Bicici 2014年

1
It seems that there are some special string clustering algorithms。如果您来自专门的文本挖掘字段,而不是统计/数据分析字段,则此声明是有保证的。但是,如果您直接学习聚类分支,则会发现不存在用于字符串数据的“特殊”算法。“特殊”是在将数据输入聚类分析之前对其进行预处理的方式。
ttnphns 2014年


注意亲和传播和K-Means聚类之间的差异,以及它如何影响计算时间。quora.com/…–
加布里埃尔·阿隆

Answers:


37

推荐@mican进行亲和力传播

摘自本文:L Frey,Brendan J.和Delbert Dueck。“通过在数据点之间传递消息进行集群。” 科学 315.5814(2007):972-976。

通过许多软件包,它超级易于使用。它适用于任何您可以定义成对相似性的事物。您可以通过将Levenshtein距离乘以-1来获得。

我使用您问题的第一段作为输入,整理了一个简单的示例。在Python 3中:

import numpy as np
import sklearn.cluster
import distance

words = "YOUR WORDS HERE".split(" ") #Replace this line
words = np.asarray(words) #So that indexing with a list will work
lev_similarity = -1*np.array([[distance.levenshtein(w1,w2) for w1 in words] for w2 in words])

affprop = sklearn.cluster.AffinityPropagation(affinity="precomputed", damping=0.5)
affprop.fit(lev_similarity)
for cluster_id in np.unique(affprop.labels_):
    exemplar = words[affprop.cluster_centers_indices_[cluster_id]]
    cluster = np.unique(words[np.nonzero(affprop.labels_==cluster_id)])
    cluster_str = ", ".join(cluster)
    print(" - *%s:* %s" % (exemplar, cluster_str))

输出为(示例的群集左侧的斜体示例):

  • 有:机会,编辑,手,拥有,高
  • 正在关注:正在关注
  • 问题:问题
  • I:我在清单中
  • 可能:可能
  • 集群:集群
  • 单词:长期需要,应该非常单词
  • 类似:类似
  • Levenshtein: Levenshtein
  • 距离:距离
  • 的:那个,这个,到,与
  • 相同:示例,列表,名称,相同,此类,姓
  • 算法:算法,算法
  • 出现:出现,出现

50个随机名字的列表上运行它:

  • 黛安(Diane):黛安娜(Diana),黛安(Diane),黛安(Dionne),杰拉尔德(Gerald),伊琳娜(Irina),利塞特(Lisette),明娜(Minna),尼克(Nicki),里基
  • 贾尼(Jani):克莱尔(Clair),贾尼(Jani),杰森(Jason),Jc,基米(Kimi),朗(Lang),马库斯(Marcus),马克西(Maxima),兰迪(Randi),劳尔(Raul)
  • Verline:命运,Kellye,Marylin,梅赛德斯,斯特林,Verline
  • 格伦:埃莱诺(Elenor),格伦(Glenn),格温达(Gwenda)
  • Armandina: Armandina,Augustina
  • Shiela: Ahmed,Estella,Milissa,Shiela,Thresa,Wynell
  • 劳伦(Laureen):秋天,海德(Haydee),劳伦(Laureen),劳伦(Lauren)
  • 阿尔贝托:阿尔伯塔,阿尔贝托,罗伯特
  • 知识: Ammie,Doreen,Eura,Josef,Lore,Lori,Porter

对我来说看起来很棒(这很有趣)。


仅使用sklearn是否有可能具有相同的算法?或将scipy.spatial.distance与汉明配合使用?使用levenshtein有什么好处?我想我将不得不尝试使用以下问题:stackoverflow.com/questions/4588541/…–
pierre

1
@pierre Levenshtein是我所说的“拼写检查器的距离”,它是人为拼写错误的可能的很好的代表。Damerau Levenshtein可能会更好。我不知道汉明距离是为长度不等的字符串定义的。它仅允许交换,不允许插入。确定如何最合理地填充/修剪字符串几乎与计算Levenshtein距离一样困难。您应该填补/修剪开始吗?结束?从中间有些?
Lyndon White

如果您真的想避免对距离的依赖。您可以使用Rossetta代码实现
Lyndon White

阅读en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance, 我可以看到换位是如何使打字错误产生特殊影响的,而python提供了一个全新的软件包。我可以看到如何针对单词列表使用此功能并获得“最接近的单词”,但可能不是最重要的。我必须得到我的清单并与tf-idf核对。酷谢谢你
pierre

1
@dduhaime几乎可以肯定。通常,亲和传播适用于非对称干扰,但由于这是对称的,因此请继续。我确信SciPy中的某个东西有一个三角矩阵类型,可以将ducktypes作为一个完整的矩阵。我在julia-lang地里呆了太久了,不记得在python中是如何完成的。(在julia中,您将使用Symmetric
Lyndon White

5

使用图聚类算法,例如Louvain聚类,受限邻域搜索聚类(RNSC),亲和传播聚类(APC)或Markov聚类算法(MCL)。


我发现的K-medoids方法怎么样?我需要尽快实施此解决方案,因此对我来说这是一个不错的解决方案。我知道这些基于图的方法的存在,但恐怕我花不起时间去理解和实现这些方法。
Ufuk Can Bicici 2014年

对于所有这些软件,都可以使用相当不受限制的许可协议来提供软件,例如GNU GPL。由于k参数,我不太喜欢k介质类型的算法,但这自然取决于您。如果您需要内部实施,那么我认为APC和MCL可能是最容易实施的。如果要这样做,请当然先尝试一下。
micans 2014年

2

您可以尝试将单词的n-gram作为向量空间条目来尝试向量空间模型。我认为在这种情况下,您将不得不使用余弦相似度之类的度量来代替编辑距离。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.