1

전처리 및 변환 (BOW, TF-IDF) 데이터 후 데이터 집합의 각 요소와 코사인 유사성을 계산해야합니다. 현재, I이 수행 예를 들어,이 예에서 tr_title 각 입력 변수scikit-learn을 사용하여 코사인 유사성을 효율적으로 계산하십시오.

cs_title = [cosine_similarity(a, b) for a in tr_title for b in tr_title] 
cs_abstract = [cosine_similarity(a, b) for a in tr_abstract for b in tr_abstract] 
cs_mesh = [cosine_similarity(a, b) for a in pre_mesh for b in pre_mesh] 
cs_pt = [cosine_similarity(a, b) for a in pre_pt for b in pre_pt] 

을하는 SciPy 희소 행렬이다. 그러나이 코드는 을 매우 천천히 실행합니다.. 더 빨리 실행되도록 코드를 최적화하려면 어떻게해야합니까?

답변

3

성능을 향상 시키려면 목록 내장을 벡터화 된 코드로 대체해야합니다.

import numpy as np 
from sklearn.feature_extraction.text import CountVectorizer 
from scipy.spatial.distance import pdist, squareform 

titles = [ 
    'A New Hope', 
    'The Empire Strikes Back', 
    'Return of the Jedi', 
    'The Phantom Menace', 
    'Attack of the Clones', 
    'Revenge of the Sith', 
    'The Force Awakens', 
    'A Star Wars Story', 
    'The Last Jedi', 
    ] 

vectorizer = CountVectorizer() 
X = vectorizer.fit_transform(titles) 
cs_title = squareform(pdist(X.toarray(), 'cosine')) 

데모 : 아래의 코드에서와 같이이 쉽게 NumPy와의 pdistsquareform을 통해 구현 될 수

In [87]: X 
Out[87]: 
<9x21 sparse matrix of type '<type 'numpy.int64'>' 
    with 30 stored elements in Compressed Sparse Row format> 

In [88]: X.toarray()   
Out[88]: 
array([[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], 
     [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0], 
     [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0], 
     [0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1], 
     [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]], dtype=int64) 

In [89]: vectorizer.get_feature_names() 
Out[89]: 
[u'attack', 
u'awakens', 
u'back', 
u'clones', 
u'empire', 
u'force', 
u'hope', 
u'jedi', 
u'last', 
u'menace', 
u'new', 
u'of', 
u'phantom', 
u'return', 
u'revenge', 
u'sith', 
u'star', 
u'story', 
u'strikes', 
u'the', 
u'wars'] 

In [90]: np.set_printoptions(precision=2) 

In [91]: print(cs_title) 
[[ 0. 1. 1. 1. 1. 1. 1. 1. 1. ] 
[ 1. 0. 0.75 0.71 0.75 0.75 0.71 1. 0.71] 
[ 1. 0.75 0. 0.71 0.5 0.5 0.71 1. 0.42] 
[ 1. 0.71 0.71 0. 0.71 0.71 0.67 1. 0.67] 
[ 1. 0.75 0.5 0.71 0. 0.5 0.71 1. 0.71] 
[ 1. 0.75 0.5 0.71 0.5 0. 0.71 1. 0.71] 
[ 1. 0.71 0.71 0.67 0.71 0.71 0. 1. 0.67] 
[ 1. 1. 1. 1. 1. 1. 1. 0. 1. ] 
[ 1. 0.71 0.42 0.67 0.71 0.71 0.67 1. 0. ]] 

공지 사항 X.toarray().shape(9L, 21L)를 얻을 수 있기 때문에 장난감 위의 예에서 9 제목이있다 및 21 개의 다른 단어 들인 반면, cs_title9 by 9 어레이이다.

1

당신은 계정에 두 벡터의 코사인 유사성의 두 가지 특징을 고려하여 절반 이상에 의해 계산 각각에 대한 노력을 줄일 수 있습니다 자체

  1. 벡터의 코사인 유사성은 하나입니다.
  2. 벡터 X와 Y벡터의 코사인 유사도와 동일 Y 벡터 벡터 X의 코사인 유사도.

따라서 대각선 위 또는 아래에있는 요소를 계산하십시오.

편집 : 여기 어떻게 계산할 수 있습니다. 특히 cs은 유사도 계수의 실제 계산을 대신하는 더미 함수입니다.

title1 = 'A four word title' 
title2 = 'A five word title' 
title3 = 'A six word title' 
title4 = 'A seven word title' 

titles = [title1, title2, title3, title4] 
N = len(titles) 

import numpy as np 

similarity_matrix = np.array(N**2*[0],np.float).reshape(N,N) 

cs = lambda a,b: 10*a+b # just a 'pretend' calculation of the coefficient 

for m in range(N): 
    similarity_matrix [m,m] = 1 
    for n in range(m+1,N): 
     similarity_matrix [m,n] = cs(m,n) 
     similarity_matrix [n,m] = similarity_matrix [m,n] 

print (similarity_matrix) 

결과는 다음과 같습니다.

[[ 1. 1. 2. 3.] 
[ 1. 1. 12. 13.] 
[ 2. 12. 1. 23.] 
[ 3. 13. 23. 1.]] 
+0

필자는이 방법을 고려했지만 동등한 결과물을 제품에 구현하는 방법을 확신하지 못했습니다. – user7347576

+0

예를 들어,'cs_pt = [pre_pt in pre_pt in a pre_pt에 대한 코사인 _ 유사도 (a, b)] '와 같이 질문에 포함 된 코드는 벡터를 생성합니다. 하지만 코사인 유사점 모음마다 매트릭스를 원하지 않으시겠습니까? –

+0

그래, 그게 원하는 출력 ... – user7347576