3

我需要找到一組5000個樣本中多個單詞相互關聯的方式。一套單詞中的模式並將它們組合

樣品: -

  1. 芒果,番石榴,荔枝,蘋果
  2. 芒果,番石榴,荔枝,橘子
  3. 芒果,番石榴,菠蘿,葡萄
  4. 鋼筆,鉛筆,本子,複製,筆記本
  5. 鋼筆,鉛筆,書本,複製,規模

我們看到,1和2彼此非常接近。 3幾乎接近1和2.我們也有4和5彼此非常接近。

我們可以使用什麼方法和技術來檢查這種相關性?

在此先感謝!

修訂版:在分組時也需要幫助,例如組A包含1,2,3行和包含4和5的組B.

+0

也許每行的單詞在別人中出現? –

+0

問題是定義*關閉* - 作爲一個人,我們很容易將水果從電子設備中分離出來,但是您需要將這些東西教給機器。 – Jan

回答

3

以下是解決此問題的一種方法。我使用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') 
1

另一種方法,或者一個新的開始的,也許換個思路來解決你的問題:

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'] 
+1

非常感謝,你能不能幫助像A組一樣將它們分組,包括1,2,3行,B組包含4和5。 – Vikas

+1

@Vikas更新。看一看 –

+1

完美!謝謝Chiheb .. – Vikas

相關問題