我需要找到多个单词是如何相互关联的,在一套5000的样本。
样本:-
我们看到1和2非常接近。3几乎接近1和2。我们还有4和5非常接近彼此。
我们可以使用什么方法和技术来检查这种相关性?
提前谢谢!
修订:也需要帮助分组,如A组,包括第1,2,3和B组包含4和5。
发布于 2017-06-18 05:53:38
这里有一个解决这个问题的方法。我将每个列表转换为文档-术语矩阵,使用scikit-learn。然后利用scipy.spacial.distance计算各行间的余弦相似度矩阵。
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')输出是每一行之间的距离矩阵。看上去如下:
[[ 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'),因为下对角线和上对角线相等,才能给出矩阵的下对角线。
分组文档
更别出心裁的是,您可以使用分层聚类将每一行与计算的距离矩阵结合在一起。
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组。
from scipy.cluster.hierarchy import dendrogram
import matplotlib.pyplot as plt
hierarchy.dendrogram(Z, above_threshold_color='#bcbddc',
orientation='top')发布于 2017-06-18 06:28:32
另一种方法,或者另一个解决你问题的新开始的想法:
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输出:
Group1 ['Line1', 'Line2', 'Line3']
Group2 ['Line4', 'Line5']https://stackoverflow.com/questions/44611986
复制相似问题