这个问题在此之前被问到过
What is a good strategy to group similar words?
但没有明确的答案如何“分组”项目 . 基于difflib的解决方案基本上是搜索,对于给定项目,difflib可以从列表中返回最相似的单词 . 但是如何将它用于分组呢?
我想减少
['ape', 'appel', 'apple', 'peach', 'puppy']
至
['ape', 'appel', 'peach', 'puppy']
要么
['ape', 'apple', 'peach', 'puppy']
我尝试过的一个想法是,对于每个项目,遍历列表,如果get_close_matches返回多个匹配,则使用它,如果不保持单词的原样 . 这部分工作,但它可以建议苹果的上诉,然后申请苹果,这些话只会切换位置,没有任何改变 .
我会很感激任何指针,图书馆名称等 .
注意:同样在性能方面,我们有300,000个项目的列表,get_close_matches似乎有点慢 . 有谁知道那里有基于C /的解决方案?
谢谢,
注意:进一步调查显示kmedoid是正确的算法(以及层次聚类),因为kmedoid不需要“中心”,它需要/使用数据点本身作为中心(这些点称为medoids,因此名称) . 在单词分组的情况下,medoid将是该组/集群的代表元素 .
5 回答
这是使用Affinity Propagation算法的另一个版本 .
距离必须转换为相似之处,我通过消除距离来做到这一点 . 输出是
您需要规范化组 . 在每个组中,选择一个单词或代表该组的编码 . 然后按其代表分组 .
一些可能的方法:
选择第一个遇到的单词 .
选择词典第一个单词 .
为所有单词导出模式 .
选择一个唯一索引 .
使用soundex作为模式 .
但是,对单词进行分组可能很困难 . 如果A类似于B,并且B类似于C,则A和C不一定彼此相似 . 如果B是代表,则A和C都可以包括在该组中 . 但如果A或C是代表,则另一个不能包括在内 .
通过第一个替代(第一个遇到的单词):
Example:
Output:
这是一种基于medoids的方法 . 首先安装MlPy . 在Ubuntu上
然后
输出是
更大的单词列表并使用k = 10
您必须在封闭的匹配单词中决定要使用的单词 . 可以从列表中获取get_close_matches返回的第一个元素,或者只是在该列表上使用随机函数并从闭合匹配中获取一个元素 .
必须有某种规则,因为它..
现在从初始列表中删除c,就是这样...对于c,你可以使用Levenshtein_distance
另一种方法可以是使用SVD的矩阵分解 . 首先我们创建单词距离矩阵,对于100个单词,这将是100 x 100矩阵,表示从每个单词到所有其他单词的距离 . 然后,在这个矩阵上运行SVD,得到的u,s,v中的u可以看作每个簇的隶属度 .
码
结果
对于簇数量的k的选择是重要的,例如,k = 25比k = 20给出更好的结果 .
该代码还通过选择其u [..]坐标最接近聚类质心的单词为每个聚类选择代表性单词 .