Does a (publicly available) dependency parser exist, that either preserves structural ambiguities in its output or that allows me to generate all possible parse trees for a given input?
I am interested in a parser for German specifically.
The top parsers like spaCy, Stanford and Google unfortunately only return one parse, although in many cases another parse is nearly equally probable.
However, the always helpful Matt from spaCy explained to me in https://github.com/explosion/spaCy/issues/238 how to get the underlying options and even the probabilities:
import numpy as np
import plac
import spacy.en
def get_scores(nlp, text, force_tag=None):
probs = []
tokens = nlp.tokenizer(text)
nlp.tagger(tokens)
if force_tag:
tags = [force_tag] + [w.tag_ for w in tokens[1:]]
nlp.tagger.tag_from_strings(tokens, tags)
with nlp.parser.step_through(tokens) as state:
while not state.is_final:
action = state.predict()
probs.append(max(state.eg.scores))
state.transition(action)
return tokens, probs
def main():
nlp = spacy.en.English()
toks, probs = get_scores(nlp, u'Communicate your ideas clearly.', force_tag='NN')
print([w.tag_ for w in toks])
print(min(probs), sum(probs))
toks, probs = get_scores(nlp, u'Communicate your ideas clearly.', force_tag='VB')
print(min(probs), sum(probs))
print([w.tag_ for w in toks])
toks, probs = get_scores(nlp, u'Communicate your ideas clearly.', force_tag='NNP')
print(min(probs))
print([w.tag_ for w in toks])
if __name__ == '__main__':
plac.call(main)
Produces:
[u'NN', u'PRP$', u'NNS', u'RB', u'.']
(231.49497985839844, 2340.7755584716797)
(334.1315612792969, 2806.1406860351562)
[u'VB', u'PRP$', u'NNS', u'RB', u'.']
252.046356201
[u'NNP', u'PRP$', u'NNS', u'RB', u'.']
This examples shows tags not dependencies, and the code has changed since then, but you should still be able to apply this basic solution.
spaCy supports German and about two dozen other languages.