模糊分组,聚类相似词

这个问题之前在这里被问过

将相似词进行分组的有效策略是什么?

但没有明确的答案说明如何“分组”项目。基于difflib的解决方案基本上是搜索,对于给定的项目,difflib可以从列表中返回最相似的词。但是如何将其用于分组呢?

我想将

['ape', 'appel', 'apple', 'peach', 'puppy']

减少到

['ape', 'appel', 'peach', 'puppy']

或者

['ape', 'apple', 'peach', 'puppy']

我尝试的一个想法是,对于每个项目,遍历列表,如果get_close_matches返回多个匹配项,则使用它,如果没有,则保持原词不变。这部分有效,但它可能会建议apple对应appel,然后appel对应apple,这些词只是交换位置而没有任何变化。

我希望能得到任何建议、库名称等。

注意:在性能方面,我们有一个包含300,000个项目的列表,get_close_matches似乎有点慢。有人知道有基于C/++的解决方案吗?

谢谢,

注意:进一步的调查显示,kmedoid是正确的算法(以及层次聚类),因为kmedoid不需要“中心”,它使用数据点本身作为中心(这些点被称为medoids,因此得名)。在词语分组的情况下,medoid将是该组/簇的代表元素。


回答:

你需要对组进行标准化。在每个组中,选择一个词或编码来代表该组。然后根据它们的代表进行分组。

一些可能的方法:

  • 选择遇到的第一个词。
  • 选择字典顺序的第一个词。
  • 为所有词派生一个模式。
  • 选择一个唯一的索引。
  • 使用soundex作为模式。

将词进行分组可能很困难。尽管A与B相似,B与C相似,A和C不一定彼此相似。如果B是代表,A和C都可以被包含在组中。但如果A或C是代表,另一个可能无法被包含。


按照第一个替代方案(遇到的第一个词):

class Seeder:    def __init__(self):        self.seeds = set()        self.cache = dict()    def get_seed(self, word):        LIMIT = 2        seed = self.cache.get(word,None)        if seed is not None:            return seed        for seed in self.seeds:            if self.distance(seed, word) <= LIMIT:                self.cache[word] = seed                return seed        self.seeds.add(word)        self.cache[word] = word        return word    def distance(self, s1, s2):        l1 = len(s1)        l2 = len(s2)        matrix = [range(zz,zz + l1 + 1) for zz in xrange(l2 + 1)]        for zz in xrange(0,l2):            for sz in xrange(0,l1):                if s1[sz] == s2[zz]:                    matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])                else:                    matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)        return matrix[l2][l1]import itertoolsdef group_similar(words):    seeder = Seeder()    words = sorted(words, key=seeder.get_seed)    groups = itertools.groupby(words, key=seeder.get_seed)    return [list(v) for k,v in groups]

示例:

import pprintprint pprint.pprint(group_similar([    'the', 'be', 'to', 'of', 'and', 'a', 'in', 'that', 'have',    'I', 'it', 'for', 'not', 'on', 'with', 'he', 'as', 'you',    'do', 'at', 'this', 'but', 'his', 'by', 'from', 'they', 'we',    'say', 'her', 'she', 'or', 'an', 'will', 'my', 'one', 'all',    'would', 'there', 'their', 'what', 'so', 'up', 'out', 'if',    'about', 'who', 'get', 'which', 'go', 'me', 'when', 'make',    'can', 'like', 'time', 'no', 'just', 'him', 'know', 'take',    'people', 'into', 'year', 'your', 'good', 'some', 'could',    'them', 'see', 'other', 'than', 'then', 'now', 'look',    'only', 'come', 'its', 'over', 'think', 'also', 'back',    'after', 'use', 'two', 'how', 'our', 'work', 'first', 'well',    'way', 'even', 'new', 'want', 'because', 'any', 'these',    'give', 'day', 'most', 'us']), width=120)

输出:

[['after'], ['also'], ['and', 'a', 'in', 'on', 'as', 'at', 'an', 'one', 'all', 'can', 'no', 'want', 'any'], ['back'], ['because'], ['but', 'about', 'get', 'just'], ['first'], ['from'], ['good', 'look'], ['have', 'make', 'give'], ['his', 'her', 'if', 'him', 'its', 'how', 'us'], ['into'], ['know', 'new'], ['like', 'time', 'take'], ['most'], ['of', 'I', 'it', 'for', 'not', 'he', 'you', 'do', 'by', 'we', 'or', 'my', 'so', 'up', 'out', 'go', 'me', 'now'], ['only'], ['over', 'our', 'even'], ['people'], ['say', 'she', 'way', 'day'], ['some', 'see', 'come'], ['the', 'be', 'to', 'that', 'this', 'they', 'there', 'their', 'them', 'other', 'then', 'use', 'two', 'these'], ['think'], ['well'], ['what', 'who', 'when', 'than'], ['with', 'will', 'which'], ['work'], ['would', 'could'], ['year', 'your']]

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注