yzhangcs / parser

:rocket: State-of-the-art parsers for natural language.
https://parser.yzhang.site/
MIT License
827 stars 139 forks source link

How to use pos tags as inputs? #58

Closed zerogerc closed 3 years ago

zerogerc commented 3 years ago

Hi, thanks for the great library.

I wonder if there are any models which use pos tags as additional inputs for predictions? I've tried biaffine-dep-en with no result:

model = Parser.load('biaffine-dep-en')

print(model.predict([[
    ('Time', 'NOUN'), ('flies', 'VERB'), ('like', 'ADP'), ('an', 'DET'), ('arrow', 'NOUN'), ('.', 'PUNCT')
]]).sentences[0])

> 1       Time    _       NOUN    _       _       2       nsubj   _       _
> 2       flies   _       VERB    _       _       0       root    _       _
> 3       like    _       ADP     _       _       2       prep    _       _
> 4       an      _       DET     _       _       5       det     _       _
> 5       arrow   _       NOUN    _       _       3       pobj    _       _
> 6       .       _       PUNCT   _       _       2       punct   _       _

print(model.predict([[
    ('Time', 'ADJ'), ('flies', 'NOUN'), ('like', 'VERB'), ('an', 'DET'), ('arrow', 'NOUN'), ('.', 'PUNCT')
]]).sentences[0])

> 1       Time    _       ADJ     _       _       2       nsubj   _       _
> 2       flies   _       NOUN    _       _       0       root    _       _
> 3       like    _       VERB    _       _       2       prep    _       _
> 4       an      _       DET     _       _       5       det     _       _
> 5       arrow   _       NOUN    _       _       3       pobj    _       _
> 6       .       _       PUNCT   _       _       2       punct   _       _

I expected dependency trees to be different for this cases (first case: root = flies, second: root = like).

Am I right that currently I can only retrain model with feat=tag? If is would it be possible to somehow use a combination of char-lstm and pos features?

yzhangcs commented 3 years ago

Am I right that currently I can only retrain model with feat=tag?

Yeah, there're only models without pos embeddings available right now. You have to retrain it if you do need a model with exactly the same settings as biaffine parser.

And to use pos when predicting, the only way is to parse from a .conllx file. Passing pos into predict is not supported yet. As to using a combination of char and pos, I refer you to my sdp impl.

zerogerc commented 3 years ago

Thanks for the quick reply!. I found this code in CoNLL(Transform), so I think passing pos tags to predict is supported?

def load():
        ...
        if isinstance(data, str):
            with open(data, 'r') as f:
                lines = [line.strip() for line in f]
        else:
            data = [data] if isinstance(data[0], str) else data
            lines = '\n'.join([self.toconll(i) for i in data]).split('\n')
       ...
    def toconll(cls, tokens):
        if isinstance(tokens[0], str):
            s = '\n'.join([f"{i}\t{word}\t" + '\t'.join(['_']*8)
                           for i, word in enumerate(tokens, 1)])
        else:
            s = '\n'.join([f"{i}\t{word}\t_\t{tag}\t" + '\t'.join(['_']*6)
                           for i, (word, tag) in enumerate(tokens, 1)])
        return s + '\n'

And could you explain what do you mean by sdp impl?

yzhangcs commented 3 years ago

@zerogerc

Thanks for the quick reply!. I found this code in CoNLL(Transform), so I think passing pos tags to predict is supported?

Yeah, you're right. Sorry for missing this.

And could you explain what do you mean by sdp impl?

I mean if you do need the combination of features, you can refer to my impl of semantic dependency parsing. Or if you're not in a hurry, please wait for my next release.

zerogerc commented 3 years ago

Thanks a lot!

I've used the same approach as in sdp and retrained the model with combined features. Now it works.