2013-06-01 3 views
5

Próbuję porównać terminy/wyrażenia, które byłyby (lub nie) semantycznie powiązane - nie są to pełne zdania, a niekoniecznie pojedyncze słowa; na przykład -Porównaj podobieństwo terminów/wyrażeń używając NLTK?

"Serwisy społecznościowe" i "Serwisy społecznościowe" są wyraźnie powiązane, ale jak je określić za pomocą nltk?

Wyraźnie brakuje mi czegoś tak nawet kodu:

w1 = wordnet.synsets('social network') 

zwraca pustą listę.

Wszelkie porady dotyczące rozwiązania tego problemu?

+0

spróbować https://github.com/alvations/pywsd – alvas

Odpowiedz

3

Istnieją pewne miary powiązań semantycznych lub podobieństwa, ale są one lepiej zdefiniowane dla pojedynczych słów lub pojedynczych wyrażeń w słowniku słownika WordNet - nie w odniesieniu do związków leksykalnych haseł WordNet, o ile wiem.

Jest to miłe realizacja web środków wordnet opartej wiele podobieństw

Niektóre dalszego czytania na interpretowania związków używając wordnet podobieństwo (choć nie oceniając podobieństwo związków), jeśli was "Zainteresowany:

+1

Chciałbym również spojrzeć na wysiłki może jak VerbOcean lub ConecptNet: http: //conceptnet5.media.mit.edu/web/c/en/social_network – arturomp

2

Oto rozwiązanie, którego można użyć.

 w1 = wordnet.synsets('social') 
    w2 = wordnet.synsets('network') 

w1 i w2 będą miały tablicę synchronizacji. Znajdź podobieństwo między każdym synsetem w1 a w2. Ten z maksymalnym podobieństwem daje połączony synset (którego właśnie szukasz).

Oto pełny kod

from nltk.corpus import wordnet 
x = 'social' 
y = 'network' 
xsyn = wordnet.synsets(x) 
# xsyn 
#[Synset('sociable.n.01'), Synset('social.a.01'), Synset('social.a.02'), 
#Synset('social.a.03'), Synset('social.s.04'), Synset('social.s.05'), 
#Synset('social.s.06')] 

ysyn = wordnet.synsets(y) 
#ysyn 
#[Synset('network.n.01'), Synset('network.n.02'), Synset('net.n.06'), 
#Synset('network.n.04'), Synset('network.n.05'), Synset('network.v.01')] 

xlen = len(xsyn) 
ylen = len(ysyn) 

import numpy 
simindex = numpy.zeros((xlen,ylen)) 

def relative_matrix(asyn,bsyn,simindex): # find similarity between asyn & bsyn 

    I = -1 
    J = -1 

    for asyn_element in asyn: 
     I += 1 

     cb = wordnet.synset(asyn_element.name) 
     J = -1 
     for bsyn_element in bsyn: 
      J += 1 
      ib = wordnet.synset(bsyn_element.name) 
      if not cb.pos == ib.pos: # compare nn , vv not nv or an 
       continue 
      score = cb.wup_similarity(ib) 
      r = cb.path_similarity(ib) 
      if simindex [I,J] < score: 
       simindex [I,J] = score 

relative_matrix(xsyn,ysyn,simindex) 
print simindex 
''' 
array([[ 0.46153846, 0.125  , 0.13333333, 0.125  , 0.125  , 
    0.  ], 
    [ 0.  , 0.  , 0.  , 0.  , 0.  , 
    0.  ], 
    [ 0.  , 0.  , 0.  , 0.  , 0.  , 
    0.  ], 
    [ 0.  , 0.  , 0.  , 0.  , 0.  , 
    0.  ], 
    [ 0.  , 0.  , 0.  , 0.  , 0.  , 
    0.  ], 
    [ 0.  , 0.  , 0.  , 0.  , 0.  , 
    0.  ], 
    [ 0.  , 0.  , 0.  , 0.  , 0.  , 
    0.  ]]) 
''' 
#xsyn[0].definition 
#'a party of people assembled to promote sociability and communal activity' 
#ysyn[0].definition 
#'an interconnected system of things or people' 

Jeśli widzisz simindex [0,0] jest wartością max 0,46153846 tak xsyn [0] i ysyn [0] wydaje się być najlepiej opisać w1 = wordnet.synsets('social network') które można zobaczyć z definicją.

1
import difflib 

sm = difflib.SequenceMatcher(None) 

sm.set_seq2('Social network') 
#SequenceMatcher computes and caches detailed information 
#about the second sequence, so if you want to compare one 
#sequence against many sequences, use set_seq2() to set 
#the commonly used sequence once and call set_seq1() 
#repeatedly, once for each of the other sequences. 
# (the doc) 

for x in ('Social networking service', 
      'Social working service', 
      'Social ocean', 
      'Atlantic ocean', 
      'Atlantic and arctic oceans'): 
    sm.set_seq1(x) 
    print x,sm.ratio() 

wynik

Social networking service 0.717948717949 
Social working service 0.611111111111 
Social ocean 0.615384615385 
Atlantic ocean 0.214285714286 
Atlantic and arctic oceans 0.15 
+1

difflib mierzy podobieństwo ciągów, ale pytanie wymaga sposobu obliczenia semantycznego podobieństwa – duhaime

1

Prawdopodobnie będzie trzeba, że ​​moduł WSD zwróci obiekt wordnet Synset z NLTK.Jeśli tak, można spojrzeć na to: https://github.com/alvations/pywsd

$ wget https://github.com/alvations/pywsd/archive/master.zip 
$ unzip master.zip 
$ cd pywsd/ 
$ ls 
baseline.py cosine.py lesk.py README.md similarity.py test_wsd.py 
$ python 
>>> from similarity import max_similarity 
>>> sent = 'I went to the bank to deposit my money' 
>>> sim_choice = "lin" # Using Lin's (1998) similarity measure. 
>>> print "Context:", sent 
>>> print "Similarity:", sim_choice 
>>> answer = max_similarity(sent, 'bank', sim_choice) 
>>> print "Sense:", answer 
>>> print "Definition", answer.definition 

[out]:

Context: I went to the bank to deposit my money 
Similarity: lch 
Sense: Synset('bank.n.09') 
Definition a building in which the business of banking transacted