2009-03-31 28 views
5

Giả sử tôi có một chuỗi các từ: 'a b c d e f'. Tôi muốn tạo một danh sách các thuật ngữ nhiều từ từ chuỗi này.Làm cách nào để tạo các cụm từ nhiều từ theo cách đệ quy?

Thứ tự từ quan trọng. Thuật ngữ 'f e d' không được tạo từ ví dụ trên.

Chỉnh sửa: Ngoài ra, không nên bỏ qua các từ. 'a c' hoặc 'b d f' không được tạo.

Những gì tôi có ngay bây giờ:

doc = 'a b c d e f' 
terms= [] 
one_before = None 
two_before = None 
for word in doc.split(None): 
    terms.append(word) 
    if one_before: 
     terms.append(' '.join([one_before, word])) 
    if two_before: 
     terms.append(' '.join([two_before, one_before, word])) 
    two_before = one_before 
    one_before = word 

for term in terms: 
    print term 

Prints:

a 
b 
a b 
c 
b c 
a b c 
d 
c d 
b c d 
e 
d e 
c d e 
f 
e f 
d e f 

Làm thế nào tôi có thể làm cho này một hàm đệ quy để tôi có thể vượt qua nó một số lượng tối đa biến các từ mỗi học kỳ?

Ứng dụng:

tôi sẽ sử dụng này để tạo điều kiện nhiều từ từ văn bản có thể đọc được trong tài liệu HTML. Mục tiêu tổng thể là một phân tích ngữ nghĩa tiềm ẩn của một kho văn bản lớn (khoảng hai triệu tài liệu). Đây là lý do tại sao giữ các vấn đề trật tự từ (Xử lý ngôn ngữ tự nhiên và điều gì đó).

+0

Để đơn giản, tôi đã thay thế các chữ cái đơn cho các từ. – tgray

+0

ý của bạn là "số lượng cụm từ tối đa có thể thay đổi cho mỗi từ"? bởi vì nó không có ý nghĩa với tôi ở dạng hiện tại. – SilentGhost

+0

Tôi nghĩ câu hỏi thực sự ở đây là, nó có cần phải đệ quy để thực hiện công việc không? Có yêu cầu đệ quy ở đây không? –

Trả lời

11

Đây không phải là đệ quy, nhưng tôi nghĩ nó thực hiện những gì bạn muốn.

doc = 'a b c d e f' 
words = doc.split(None) 
max = 3   


for index in xrange(len(words)):  
    for n in xrange(max): 
     if index + n < len(words):   
      print ' '.join(words[index:index+n+1]) 

Và đây là một giải pháp đệ quy:

def find_terms(words, max_words_per_term):  
    if len(words) == 0: return [] 
    return [" ".join(words[:i+1]) for i in xrange(min(len(words), max_words_per_term))] + find_terms(words[1:], max_words_per_term) 


doc = 'a b c d e f' 
words = doc.split(None) 
for term in find_terms(words, 3): 
    print term 

Đây là hàm đệ quy một lần nữa, với một số biến giải thích và bình luận.

def find_terms(words, max_words_per_term): 

    # If there are no words, you've reached the end. Stop.  
    if len(words) == 0: 
     return []  

    # What's the max term length you could generate from the remaining 
    # words? It's the lesser of max_words_per_term and how many words 
    # you have left.               
    max_term_len = min(len(words), max_words_per_term)  

    # Find all the terms that start with the first word. 
    initial_terms = [" ".join(words[:i+1]) for i in xrange(max_term_len)] 

    # Here's the recursion. Find all of the terms in the list 
    # of all but the first word. 
    other_terms = find_terms(words[1:], max_words_per_term) 

    # Now put the two lists of terms together to get the answer. 
    return initial_terms + other_terms 
+0

Có vẻ như tôi sẽ phải sử dụng giải pháp đầu tiên bạn cung cấp. Python sẽ không cho phép hàm lặp lại nhiều hơn 999 lần. Tài liệu kiểm tra của tôi có khoảng 1750 từ và nó nằm ở phía nhỏ. – tgray

+0

Điều đó có ý nghĩa. Các giải pháp đệ quy đã được vui vẻ để làm việc ra, nhưng không thực sự thực tế. –

+0

Nếu bạn thực sự muốn đệ quy sâu, bạn có thể tăng giới hạn đệ quy với sys.setrecursionlimit. Nhưng các giải pháp lặp lại có lẽ tốt hơn ở đây anyway. – Kiv

3

Tôi khuyên bạn nên làm cho chức năng của bạn trở thành một bộ tạo và sau đó tạo số lượng thuật ngữ được yêu cầu. Bạn sẽ cần phải thay đổi print thành yield (và làm cho toàn bộ chức năng chặn, rõ ràng).

Bạn cũng có thể xem mô-đun itertools, nó khá hữu ích cho loại công việc bạn làm.

3

Tại sao bạn làm điều này? Thay vào đó, bạn chỉ có thể sử dụng vòng lặp for và itertools.combinations().

+0

Đề xuất tốt, nhưng tôi cần thứ tự được giữ nguyên. Ví dụ: 'a b c' tạo ['a', 'b', 'a b', 'c', 'b c', 'a b c'], chứ không phải 'b a' hoặc 'c b a'. – tgray

+0

Nó bảo quản trật tự. –

+0

Xin lỗi vì sự nhầm lẫn, nó cũng không nên bỏ qua các từ. Tài liệu "Con cáo màu nâu nhanh chóng nhảy qua hàng rào" không nên có "hàng rào màu nâu" như một thuật ngữ. Có cách nào để sử dụng itertools để làm điều này? – tgray

1

Điều bạn đang tìm kiếm là thuật toán N-gram. Điều đó sẽ cho bạn [a, ab, b, bc, c, cd, ...].

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