2016-01-30 17 views
12
import nltk 
from nltk.parse import ViterbiParser 

def pcfg_chartparser(grammarfile): 
    f=open(grammarfile) 
    grammar=f.read() 
    f.close() 
    return nltk.PCFG.fromstring(grammar) 

grammarp = pcfg_chartparser("wsjp.cfg") 

VP = ViterbiParser(grammarp) 
print VP 
for w in sent: 
    for tree in VP.parse(nltk.word_tokenize(w)): 
     print tree 

Khi tôi chạy đoạn mã trên, nó tạo ra đầu ra sau đây cho câu, "tắt đèn" -NLTK ViterbiParser thất bại trong phân tích từng từ mà không phải là trong quy tắc PCFG

(S (VP (VB turn) (PRT (RP off)) (NP (DT the) (NNS lights)))) (p=2.53851e-14)

Tuy nhiên , nó làm tăng lỗi sau cho câu, "vui lòng tắt đèn" -

ValueError: Grammar does not cover some of the input words: u"'please'"

Tôi đang xây dựng ViterbiParser bằng cách cung cấp ngữ cảnh xác suất ngữ pháp miễn phí. Nó hoạt động tốt trong việc phân tích các câu có các từ đã có trong các quy tắc của ngữ pháp. Nó không phân tích cú pháp các câu trong đó Trình phân tích cú pháp đã không nhìn thấy từ trong các quy tắc ngữ pháp. Làm thế nào để vượt qua giới hạn này?
Tôi đang đề cập đến điều này assignment.

+0

Không có cách nào để làm mịn xác suất của bạn? – L3viathan

Trả lời

7

Thứ nhất, cố gắng sử dụng (i) không gian tên và (ii) tên biến rõ ràng, ví dụ:

>>> from nltk import PCFG 
>>> from nltk.parse import ViterbiParser 
>>> import urllib.request 
>>> response = urllib.request.urlopen('https://raw.githubusercontent.com/salmanahmad/6.863/master/Labs/Assignment5/Code/wsjp.cfg') 
>>> wsjp = response.read().decode('utf8') 
>>> grammar = PCFG.fromstring(wsjp) 
>>> parser = ViterbiParser(grammar) 
>>> list(parser.parse('turn off the lights'.split())) 
[ProbabilisticTree('S', [ProbabilisticTree('VP', [ProbabilisticTree('VB', ['turn']) (p=0.002082678), ProbabilisticTree('PRT', [ProbabilisticTree('RP', ['off']) (p=0.1089101771)]) (p=0.10768769667270556), ProbabilisticTree('NP', [ProbabilisticTree('DT', ['the']) (p=0.7396712852), ProbabilisticTree('NNS', ['lights']) (p=4.61672e-05)]) (p=4.4236397464693323e-07)]) (p=1.0999324002161311e-13)]) (p=2.5385077255727538e-14)] 

Nếu chúng ta nhìn vào ngữ pháp:

>>> grammar.check_coverage('please turn off the lights'.split()) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python3.4/dist-packages/nltk/grammar.py", line 631, in check_coverage 
    "input words: %r." % missing) 
ValueError: Grammar does not cover some of the input words: "'please'". 

Để giải quyết từ lạ vấn đề, có một số tùy chọn:

  • Sử dụng các nút không phải là thiết bị đầu cuối wildcard để thay thế các từ chưa biết. Tìm một số cách để thay thế những từ mà ngữ pháp không bao gồm từ check_coverage() với wildcard, sau đó phân tích các câu với các ký tự đại diện

    • này thường sẽ giảm độ chính xác của phân tích cú pháp, trừ khi bạn đã đặc biệt đào tạo các PCFG với một ngữ pháp xử lý các từ không rõ và ký tự đại diện là một siêu của các từ chưa biết.
  • Quay trở lại tập sản xuất ngữ pháp mà bạn có trước khi tạo học PCFG với learn_pcfg.pythêm tất cả các từ có thể trong sản xuất thiết bị đầu cuối.

  • Thêm từ chưa biết vào ngữ pháp pcfg bạn và sau đó renormalize trọng, do một trong hai trọng lượng rất nhỏ đến từ chưa biết (bạn cũng có thể thử các kỹ thuật làm mịn/nội suy thông minh hơn)

Vì đây là một câu hỏi về bài tập về nhà, tôi sẽ không trả lời bằng mã đầy đủ. Nhưng các gợi ý ở trên là đủ để giải quyết vấn đề.

+0

Ngoài ra, kênh thích hợp để đặt câu hỏi sẽ trực tiếp trong Stackoverflow hoặc trên https://groups.google.com/forum/?hl=vi#!forum/nltk-danh sách người dùng. – alvas

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