我需要找到一組5000個樣本中多個單詞相互關聯的方式。一套單詞中的模式並將它們組合
樣品: -
- 芒果,番石榴,荔枝,蘋果
- 芒果,番石榴,荔枝,橘子
- 芒果,番石榴,菠蘿,葡萄
- 鋼筆,鉛筆,本子,複製,筆記本
- 鋼筆,鉛筆,書本,複製,規模
我們看到,1和2彼此非常接近。 3幾乎接近1和2.我們也有4和5彼此非常接近。
我們可以使用什麼方法和技術來檢查這種相關性?
在此先感謝!
修訂版:在分組時也需要幫助,例如組A包含1,2,3行和包含4和5的組B.
我需要找到一組5000個樣本中多個單詞相互關聯的方式。一套單詞中的模式並將它們組合
樣品: -
我們看到,1和2彼此非常接近。 3幾乎接近1和2.我們也有4和5彼此非常接近。
我們可以使用什麼方法和技術來檢查這種相關性?
在此先感謝!
修訂版:在分組時也需要幫助,例如組A包含1,2,3行和包含4和5的組B.
以下是解決此問題的一種方法。我使用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')
另一種方法,或者一個新的開始的,也許換個思路來解決你的問題:
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']
也許每行的單詞在別人中出現? –
問題是定義*關閉* - 作爲一個人,我們很容易將水果從電子設備中分離出來,但是您需要將這些東西教給機器。 – Jan