2015-06-14 16 views
5

Tôi có một hai danh sách và tôi muốn kiểm tra sự tương đồng giữa mỗi từ trong danh sách hai và tìm ra similarity.Here tối đa là mã của tôi,Kiểm tra sự giống nhau giữa hai từ với NLTK với Python

from nltk.corpus import wordnet 

list1 = ['Compare', 'require'] 
list2 = ['choose', 'copy', 'define', 'duplicate', 'find', 'how', 'identify', 'label', 'list', 'listen', 'locate', 'match', 'memorise', 'name', 'observe', 'omit', 'quote', 'read', 'recall', 'recite', 'recognise', 'record', 'relate', 'remember', 'repeat', 'reproduce', 'retell', 'select', 'show', 'spell', 'state', 'tell', 'trace', 'write'] 
list = [] 

for word1 in list1: 
    for word2 in list2: 
     wordFromList1 = wordnet.synsets(word1)[0] 
     wordFromList2 = wordnet.synsets(word2)[0] 
     s = wordFromList1.wup_similarity(wordFromList2) 
     list.append(s) 

print(max(list)) 

Nhưng điều này sẽ dẫn đến lỗi:

wordFromList2 = wordnet.synsets(word2)[0] 
     IndexError: list index out of range 

Hãy giúp tôi khắc phục lỗi này.
Cám ơn bạn

+0

FWIW đây là một liên kết đến doc cho '.synsets': http://www.nltk.org/api/nltk.corpus.reader.html#nltk.corpus.reader.wordnet.WordNetCorpusReader.synsets – abathur

+0

hãy xem https://github.com/alvations/pywsd/blob/master/pywsd/similarity.py#L76 – alvas

Trả lời

6

Hãy thử kiểm tra xem các danh sách này là trống trước khi bạn sử dụng thì:

from nltk.corpus import wordnet 

list1 = ['Compare', 'require'] 
list2 = ['choose', 'copy', 'define', 'duplicate', 'find', 'how', 'identify', 'label', 'list', 'listen', 'locate', 'match', 'memorise', 'name', 'observe', 'omit', 'quote', 'read', 'recall', 'recite', 'recognise', 'record', 'relate', 'remember', 'repeat', 'reproduce', 'retell', 'select', 'show', 'spell', 'state', 'tell', 'trace', 'write'] 
list = [] 

for word1 in list1: 
    for word2 in list2: 
     wordFromList1 = wordnet.synsets(word1) 
     wordFromList2 = wordnet.synsets(word2) 
     if wordFromList1 and wordFromList2: #Thanks to @alexis' note 
      s = wordFromList1[0].wup_similarity(wordFromList2[0]) 
      list.append(s) 

print(max(list)) 
+0

@Punuth Tính năng này có hoạt động theo cách này không? – omerbp

+0

Khá chắc chắn dòng 'if len ...' sẽ là một lỗi cú pháp. Cũng có thể chỉ kiểm tra 'nếu len (blah1) và len (blah2):' vì anh ta chỉ cần biết chúng không trống rỗng. Nếu một trở về trống từ .synsets là rất hiếm, những người khác có lẽ sẽ đề nghị chỉ cần bắt IndexError. – abathur

+0

@abathur Cảm ơn, tôi đã sửa nó. Về khối catch - Tôi đồng ý, nhưng tôi nghĩ rằng một từ 'blah' không có từ đồng nghĩa bên trong một danh sách thứ hai là rất phổ biến, do đó tôi sử dụng nếu khối – omerbp

9

Bạn đang nhận được một lỗi nếu một danh sách synset là trống rỗng, và bạn cố gắng để có được những yếu tố tại (không - tồn tại) chỉ số bằng không. Nhưng tại sao chỉ kiểm tra yếu tố zero'th? Nếu bạn muốn kiểm tra mọi thứ, hãy thử tất cả các cặp của các phần tử trong các syns đã trả về. Bạn có thể sử dụng itertools.product() để tiết kiệm cho mình hai cho-vòng:

from itertools import product 
sims = [] 

for word1, word2 in product(list1, list2): 
    syns1 = wordnet.synsets(word1) 
    syns2 = wordnet.synsets(word2) 
    for sense1, sense2 in product(syns1, syns2): 
     d = wordnet.wup_similarity(sense1, sense2) 
     sims.append((d, syns1, syns2)) 

này là không hiệu quả vì synsets cùng được nhìn lên một lần nữa và một lần nữa, nhưng nó là gần nhất với logic của mã của bạn. Nếu bạn có đủ dữ liệu để cải thiện tốc độ, bạn có thể tăng tốc độ bằng cách thu thập các synset cho tất cả các từ trong list1list2sau khi và lấy sản phẩm của các bộ đồng bộ.

>>> allsyns1 = set(ss for word in list1 for ss in wordnet.synsets(word)) 
>>> allsyns2 = set(ss for word in list2 for ss in wordnet.synsets(word)) 
>>> best = max((wordnet.wup_similarity(s1, s2) or 0, s1, s2) for s1, s2 in 
     product(allsyns1, allsyns2)) 
>>> print(best) 
(0.9411764705882353, Synset('command.v.02'), Synset('order.v.01')) 
+0

Đoạn mã thứ hai thật tuyệt vời! Bạn có thể vui lòng cho tôi biết cách so sánh các tập hợp của danh sách đầu tiên với cùng các từ của danh sách thứ hai, không có đồng bộ không? Tôi đã cố gắng để sửa đổi allsyns2 nhưng tôi cảm thấy, tôi khá mới để python và xin lỗi này một dòng mã với hai vòng là khó hiểu đối với tôi! – Hussein

+1

Tôi sợ tôi không thể nói ý của bạn là gì. Hãy mở rộng câu hỏi này thành một câu hỏi thích hợp, bao gồm đầu vào ví dụ và đầu ra mong muốn (và bất kỳ mã nào bạn có thể quản lý, tất nhiên). – alexis

+0

Ý tôi là một trong hai danh sách là cố định và được biết đến, như thế này: list1 = ['word.n.01', 'word2.v.01']. Tôi bị mắc kẹt bởi vì tôi không biết rằng có hai chức năng: 'wordnet.synsets (word)' và 'wordnet.synset (word)'. Tôi loại bỏ 's' như thế này: set (wordnet.synset (word) cho từ trong list1) và nó cuối cùng đã làm việc – Hussein

Các vấn đề liên quan