首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一组单词中的模式并将它们分组

一组单词中的模式并将它们分组
EN

Stack Overflow用户
提问于 2017-06-18 05:24:49
回答 2查看 188关注 0票数 3

我需要找到多个单词是如何相互关联的,在一套5000的样本。

样本:-

  1. 芒果,番石榴,荔枝,苹果
  2. 芒果,番石榴,荔枝,橘子
  3. 芒果,番石榴,菠萝,葡萄
  4. 钢笔,铅笔,书,拷贝,笔记本
  5. 钢笔,铅笔,书,拷贝,刻度

我们看到1和2非常接近。3几乎接近1和2。我们还有4和5非常接近彼此。

我们可以使用什么方法和技术来检查这种相关性?

提前谢谢!

修订:也需要帮助分组,如A组,包括第1,2,3和B组包含4和5。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-18 05:53:38

这里有一个解决这个问题的方法。我将每个列表转换为文档-术语矩阵,使用scikit-learn。然后利用scipy.spacial.distance计算各行间的余弦相似度矩阵。

代码语言:javascript
复制
from sklearn.feature_extraction.text import CountVectorizer
from scipy.spatial import distance

count_vect = CountVectorizer(tokenizer=lambda x: x.split(', '))

ls = ['mango, guava, litchi, apple', 
      'mango, guava, litchi, orange',
      'mango, guava, pineapple, grape',
      'pen, pencil, book, copy, notebook',
      'pen, pencil, book, copy, scale']

X = count_vect.fit_transform(ls).toarray()
D = distance.cdist(X, X, metric='cosine')

输出是每一行之间的距离矩阵。看上去如下:

代码语言:javascript
复制
[[ 0.  ,  0.25,  0.5 ,  1.  ,  1.  ],
 [ 0.25,  0.  ,  0.5 ,  1.  ,  1.  ],
 [ 0.5 ,  0.5 ,  0.  ,  1.  ,  1.  ],
 [ 1.  ,  1.  ,  1.  ,  0.  ,  0.2 ],
 [ 1.  ,  1.  ,  1.  ,  0.2 ,  0.  ]])

例如,D[0, 1]意味着第1行接近第2行,因为两行之间的距离很小。另外,您可以看到D[3, 4]很小,这意味着第4行接近第5行。

注意,,您也可以考虑使用distance.pdist(X, metric='cosine'),因为下对角线和上对角线相等,才能给出矩阵的下对角线。

分组文档

更别出心裁的是,您可以使用分层聚类将每一行与计算的距离矩阵结合在一起。

代码语言:javascript
复制
from scipy.cluster import hierarchy

D = distance.pdist(X, metric='cosine')
Z = hierarchy.linkage(D, metric='euclidean')
partition = hcluster.fcluster(Z, t=0.8, criterion='distance') # [2, 2, 2, 1, 1] 

这意味着文档1,2,3被分组在第2组,4,5被分组在第1组。

代码语言:javascript
复制
from scipy.cluster.hierarchy import dendrogram
import matplotlib.pyplot as plt

hierarchy.dendrogram(Z, above_threshold_color='#bcbddc',
                     orientation='top')
票数 3
EN

Stack Overflow用户

发布于 2017-06-18 06:28:32

另一种方法,或者另一个解决你问题的新开始的想法:

代码语言:javascript
复制
import re
from itertools import chain

a = ['mango, guava, litchi, apple', 
      'mango, guava, litchi, orange',
      'mango, guava, pineapple, grape',
      'pen, pencil, book, copy, notebook',
      'pen, pencil, book, copy, scale']

def get_words(lst):
    return [re.findall(r'[\w]+', k) for k in a]

def get_percent(lst):
    groupped_valid_dict = {}
    for k in range(len(lst)):
        sub = []
        for j in range(k+1, len(lst)):
            s = sum([1 if m == n else 0 for m, n in zip(lst[k], lst[j])])
            #percent = (1 - float(len(lst[k]) - s)/len(lst[k])) * 100
            #fmt = '%.2f%%' % percent
            #print 'Words of lines: %d and %d are %s close' %(k+1, j+1, fmt)
            if s > 0:
                sub.append("Line{}".format(j+1))
        if sub:
            groupped_valid_dict["Line{}".format(k+1)] = sub
    return groupped_valid_dict


lst = get_words(a)
lines  = get_percent(lst)
groups = [[k] + lines[k] for k in lines if k not in chain.from_iterable(lines.values())]
groups.sort(key=lambda x: x[0])

for k, v in enumerate(groups, 1):
    print "Group%d" %k, v

输出:

代码语言:javascript
复制
Group1 ['Line1', 'Line2', 'Line3']
Group2 ['Line4', 'Line5']
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44611986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档