2017-05-13 4 views
3

팬더 데이터 프레임에서 두 단어 사이의 유사성을 찾으려고합니다. 여기 내 일상이다NLP - 유사 단어 일치 속도를 높입니다.

import pandas as pd 
from nltk.corpus import wordnet 
import itertools 

df = pd.DataFrame({'word_1':['desk', 'lamp', 'read'], 'word_2':['call','game','cook']}) 

def max_similarity(row): 
    word_1 = row['word_1'] 
    word_2 = row['word_2'] 

    ret_val = max([(wordnet.wup_similarity(syn_1, syn_2) or 0) for 
     syn_1, syn_2 in itertools.product(wordnet.synsets(word_1), wordnet.synsets(word_2))]) 

    return ret_val 

df['result'] = df.apply(lambda x: max_similarity(x), axis= 1) 

괜찮 으면 작동하지만 너무 느립니다. 속도를 높이는 방법을 찾고 있습니다. wordnet 대부분의 시간이 소요됩니까? Cython? spacy과 같은 다른 패키지를 사용하고 있습니다.

+2

는 lolz ... 코드의 조각은 익숙; P – alvas

+0

@alvas는, 엡, 나는 경우 다른 포스트에서 stackoverflow.com ;-)에서 차용. 나는 네 것이라고 생각해. – user1700890

답변

2

는 간단한 벤치 마크를 고려할 수 있습니다. 갈색 뉴스 코퍼스를 사용하여 임의의 단어 쌍을 절반으로 나누어 만듭니다.

from nltk.corpus import brown 

brown_corpus = list(brown.words(categories='news')) 
brown_df = pd.DataFrame({ 
    'word_1':brown_corpus[:len(brown_corpus)//2], 
    'word_2': brown_corpus[len(brown_corpus)//2:] 
}) 

len(brown_df) 
50277 

개의 토큰 코사인 유사도/문서는 Doc.similarity 방법으로 계산 될 수있다.

import spacy 
nlp = spacy.load('en') 

def spacy_max_similarity(row): 
    word_1 = nlp(row['word_1']) 
    word_2 = nlp(row['word_2']) 

    return word_1.similarity(word_2) 

마지막으로, 데이터 프레임에 두 가지 방법을 적용

nltk_similarity = %timeit -o brown_df.apply(nltk_max_similarity, axis=1) 
1 loop, best of 3: 59 s per loop 

spacy_similarity = %timeit -o brown_df.apply(spacy_max_similarity, axis=1) 
1 loop, best of 3: 8.88 s per loop 

는 NLTK 및 적응 사용하는 다른 기술은 유사성 측정에 있어서는 있습니다. spacy는 word2vec 알고리즘으로 사전 계산 된 단어 벡터를 사용합니다. docs에서 :

사용하여 단어 벡터와 의미 론적 유사성

[...]

기본 영어 모델이 300 차원 벡터를 사용하여 100 만 개 어휘 항목에 대해 벡터를 설치합니다 GloVe 알고리즘을 사용하여 Common Crawl 코퍼스에 대해 교육했습니다. GloVe 공통 크롤링 벡터는 이 실제 NLP의 사실상 표준이됩니다.

nltk word similarity vs. spacy

+1

흥미 롭습니다! 'spacy'의 단어 유사성과'nltk'의 Synset 유사성은 이론적으로 매우 다릅니다 =) – alvas

1

단어 쌍 유사성을 저장하는 것이 더 빠른 방법 중 하나는 단어 쌍 유사성을 저장하는 것입니다. 그런 다음 반복 할 경우 루프에서 검색 기능을 실행하지 마십시오. 당신은 당신이 NLP 라이브러리로 spacy를 사용하여 열려 말했다 때문에

import pandas as pd 
from nltk.corpus import wordnet 
import itertools 

df = pd.DataFrame({'word_1':['desk', 'lamp', 'read'], 'word_2':['call','game','cook']}) 

word_similarities = dict() 
def max_similarity(row): 
    word_1 = row['word_1'] 
    word_2 = row['word_2'] 

    key = tuple(sorted([word_1, word_2])) # symmetric measure :) 

    if key not in word_similarities: 
     word_similarities[key] = max([ 
      (wordnet.wup_similarity(syn_1, syn_2) or 0) 
      for syn_1, syn_2 in itertools.product(wordnet.synsets(word_1), wordnet.synsets(word_2)) 
     ]) 

    return word_similarities[key] 

df['result'] = df.apply(lambda x: max_similarity(x), axis= 1) 
관련 문제