Мой вопрос связан с пост-обработкой предложений речи с выражением части речи и синтаксического анализа. В частности, я пишу компонент постпроцессора Lisp, который принимает в качестве входных данных дерево синтаксического анализа (например, созданное Stanford Parser), извлекает из этого дерева синтаксиса правила фразовой структуры, вызываемые для генерации синтаксического анализа , а затем создает таблицу правил и счетчиков правил. Пример ввода и вывода будет следующим:Обработка (,,) и (...) и других знаков препинания при обработке дерева синтаксического разбора с помощью Lisp
(1) предложение:
John said that he knows who Mary likes
(2) выходного Parser:
(ROOT
(S
(NP (NNP John))
(VP (VBD said)
(SBAR (IN that)
(S
(NP (PRP he))
(VP (VBZ knows)
(SBAR
(WHNP (WP who))
(S
(NP (NNP Mary))
(VP (VBZ likes))))))))))
(3) My лисповской вывод программы пост-процессора для этого дерева разбора:
(S --> NP VP) 3
(NP --> NNP) 2
(VP --> VBZ) 1
(WHNP --> WP) 1
(SBAR --> WHNP S) 1
(VP --> VBZ SBAR) 1
(NP --> PRP) 1
(SBAR --> IN S) 1
(VP --> VBD SBAR) 1
(ROOT --> S) 1
Обратите внимание на отсутствие пунктуации в предложении (1). Это намеренно. У меня возникли проблемы с анализом пунктуации в Lisp - именно потому, что некоторые пунктуации (например, запятые) зарезервированы для специальных целей. Но разбор предложения без знаков препинания изменяет распределение правил синтаксического анализа, а также символы, содержащихся в этих правилах, как показано на следующем:
(4) Ввод предложение:
I said no and then I did it anyway
(5) выход Parser :
(ROOT
(S
(NP (PRP I))
(VP (VBD said)
(ADVP (RB no)
(CC and)
(RB then))
(SBAR
(S
(NP (PRP I))
(VP (VBD did)
(NP (PRP it))
(ADVP (RB anyway))))))))
(6) Входной предложение (с пунктуацией):
I said no, and then I did it anyway.
(7) Выход Parser:
(ROOT
(S
(S
(NP (PRP I))
(VP (VBD said)
(INTJ (UH no))))
(, ,)
(CC and)
(S
(ADVP (RB then))
(NP (PRP I))
(VP (VBD did)
(NP (PRP it))
(ADVP (RB anyway))))
(. .)))
Примечание как включая знаки препинания полностью перестраивает дерево разбора, а также включает в себя различные теги POS (и, таким образом, предполагает, что различные правила грамматики были призваны производить его) Так что, включая знаки препинания важно, по крайней мере, для моей заявки.
Что мне нужно, чтобы найти способ, чтобы включить знаки препинания в правилах, так что я могу производить такие правила в следующем, которые появляются бы, например, в таблице, как (3) следующим образом:
(8) Желаемое правило:
S --> S , CC S .
правило, как (8), на самом деле, требуемые для конкретного приложения я пишу.
Но я нахожу, что делать это в Lisp сложно: в (7), например, мы наблюдаем появление (,,) и (.), Обе из которых проблематичны для обработки в Lisp.
Я включил мой соответствующий код Лиспа ниже. Обратите внимание, что я неофит-хакер, но мой код не особенно хорош или эффективен. Если бы кто-то мог предположить, как я могу изменить свой ниже код, чтобы я мог проанализировать (7), чтобы создать таблицу типа (3), которая включает правило вроде (8), я был бы очень благодарен.
Вот мой Лисп код отношение к этой задаче:
(defun WRITE-RULES-AND-COUNTS-SORTED (sent)
(multiple-value-bind (rules-list counts-list)
(COUNT-RULES-OCCURRENCES sent)
(setf comblist (sort (pairlis rules-list counts-list) #'> :key #'cdr))
(format t "~%")
(do ((i 0 (incf i)))
((= i (length comblist)) NIL)
(format t "~A~26T~A~%" (car (nth i comblist)) (cdr (nth i comblist))))
(format t "~%")))
(defun COUNT-RULES-OCCURRENCES (sent)
(let* ((original-rules-list (EXTRACT-GRAMMAR sent))
(de-duplicated-list (remove-duplicates original-rules-list :test #'equalp))
(count-list nil))
(dolist (i de-duplicated-list)
(push (reduce #'+ (mapcar #'(lambda (x) (if (equalp x i) 1 0)) original-rules-list)) count-list))
(setf count-list (nreverse count-list))
(values de-duplicated-list count-list)))
(defun EXTRACT-GRAMMAR (sent &optional (rules-stack nil))
(cond ((null sent)
NIL)
((and (= (length sent) 1)
(listp (first sent))
(= (length (first sent)) 2)
(symbolp (first (first sent)))
(symbolp (second (first sent))))
NIL)
((and (symbolp (first sent))
(symbolp (second sent))
(= 2 (length sent)))
NIL)
((symbolp (first sent))
(push (EXTRACT-GRAMMAR-RULE sent) rules-stack)
(append rules-stack (EXTRACT-GRAMMAR (rest sent) )))
((listp (first sent))
(cond ((not (and (listp (first sent))
(= (length (first sent)) 2)
(symbolp (first (first sent)))
(symbolp (second (first sent)))))
(push (EXTRACT-GRAMMAR-RULE (first sent)) rules-stack)
(append rules-stack (EXTRACT-GRAMMAR (rest (first sent))) (EXTRACT-GRAMMAR (rest sent))))
(t (append rules-stack (EXTRACT-GRAMMAR (rest sent) )))))))
(defun EXTRACT-GRAMMAR-RULE (sentence-or-phrase)
(append (list (first sentence-or-phrase))
'(-->)
(mapcar #'first (rest sentence-or-phrase))))
код вызывается следующим образом (с помощью (1) в качестве входных данных, производя (3) в качестве выходного сигнала):
(WRITE-RULES-AND-COUNTS-SORTED '(ROOT
(S
(NP (NNP John))
(VP (VBD said)
(SBAR (IN that)
(S
(NP (PRP he))
(VP (VBZ knows)
(SBAR
(WHNP (WP who))
(S
(NP (NNP Mary))
(VP (VBZ likes)))))))))))