2013-05-06 40 views
6

Tôi có một số câu hỏi về các chức năng của cây NLTK. Tôi đang cố gắng trích ra một từ nhất định từ cấu trúc cây như hình bên dưới.Trích xuất giá trị lá cụ thể từ cấu trúc cây nltk bằng Python

test = Tree.parse('(ROOT(SBARQ(WHADVP(WRB How))(SQ(VBP do)(NP (PRP you))(VP(VB ask)(NP(DT a)(JJ total)(NN stranger))(PRT (RP out))(PP (IN on)(NP (DT a)(NN date)))))))') 

print "Input tree: ", test 
print test.leaves() 

(SBARQ 
    (WHADVP (WRB How)) 
    (SQ 
     (VBP do) 
     (NP (PRP you)) 
     (VP 
     (VB ask) 
     (NP (DT a) (JJ total) (NN stranger)) 
     (PRT (RP out)) 
     (PP (IN on) (NP (DT a) (NN date))))))) 

['How', 'do', 'you', 'ask', 'a', 'total', 'stranger', 'out', 'on', 'a', 'date'] 

Tôi có thể tìm danh sách tất cả các từ sử dụng hàm leaves(). Có cách nào để lấy một chiếc lá cụ thể không? Ví dụ: Tôi muốn nhận danh từ đầu tiên/cuối cùng chỉ trong cụm từ NP? Câu trả lời sẽ là 'người lạ' cho danh từ đầu tiên và 'ngày' làm danh từ cuối cùng.

Trả lời

10

Mặc dù cụm từ danh từ có thể được lồng vào bên trong các loại cụm từ khác, tôi tin rằng hầu hết các ngữ pháp luôn có danh từ trong các cụm từ danh từ. Vì vậy, câu hỏi của bạn có thể được lặp lại như sau: Làm thế nào để bạn tìm thấy danh từ đầu tiên và cuối cùng?

Bạn chỉ có thể nhận được tất cả tuple s các từ và thẻ POS và lọc như thế này,

>>> [word for word,pos in test.pos() if pos=='NN'] 
['stranger', 'date'] 

nào trong trường hợp này là chỉ có hai vì vậy bạn đã hoàn tất. Nếu bạn có nhiều danh từ hơn, bạn chỉ cần lập chỉ mục danh sách tại [0][-1].


Nếu bạn đang tìm kiếm một POS có thể được sử dụng trong các cụm từ khác nhau nhưng bạn chỉ muốn sử dụng nó bên trong một đặc biệt một hoặc nếu bạn đã có một ngữ pháp lạ mà cho phép danh từ bên ngoài của NP, bạn có thể làm như sau ...

Bạn có thể tìm subtrees của 'NP' bằng cách thực hiện,

>>> NPs = list(test.subtrees(filter=lambda x: x.node=='NP')) 
>>> NPs 
[Tree('NP', [Tree('PRP', ['you'])]), Tree('NP', [Tree('DT', ['a']), Tree('JJ', ['total']), Tree('NN', ['stranger'])]), Tree('NP', [Tree('DT', ['a']), Tree('NN', ['date'])])] 

Tiếp tục thu hẹp subtrees, chúng ta có thể sử dụng kết quả này để tìm kiếm 'NN' từ,

>>> NNs_inside_NPs = map(lambda x: list(x.subtrees(filter=lambda x: x.node=='NN')), NPs) 
>>> NNs_inside_NPs 
[[], [Tree('NN', ['stranger'])], [Tree('NN', ['date'])]] 

Vì vậy, đây là một list của list s của tất cả các 'NN' s bên trong mỗi 'NP' cụm từ. Trong trường hợp này chỉ xảy ra là 0 hoặc một danh từ trong mỗi cụm từ.

Bây giờ chúng ta chỉ cần đi qua các 'NP' s và nhận được tất cả các leaves của danh từ riêng (mà thực sự có nghĩa là chúng tôi chỉ muốn truy cập vào 'stranger' phần của Tree('NN', ['stranger'])).

>>> [noun.leaves()[0] for nouns in NNs_inside_NPs for noun in nouns] 
['stranger', 'date'] 
+0

Cảm ơn nó hoạt động. Bây giờ tôi chỉ cần lấy vật phẩm đầu tiên trong danh sách. – Cryssie

+1

Sử dụng Python 3.4.1 và NLTK 3.2.1, sử dụng 'x.label()' thay vì 'x.node' để tìm kết quả, nếu không bạn sẽ nhận được' NotImplementedError ("Use label() để truy cập nhãn nút . ")' ngoại lệ. I.e: 't = list (r.subtrees (bộ lọc = lambda x: x.label() == 'NP'))' – InfectedPacket

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