goodmami / penman

PENMAN notation (e.g. AMR) in Python
https://penman.readthedocs.io/
MIT License
139 stars 27 forks source link

How to represent Double Negation by automatically modifying AMR? #108

Closed 14H034160212 closed 2 years ago

14H034160212 commented 2 years ago

Hi,

I got one question. Probably just some tips are appreciated. Do you know what I can do to modify AMR using the double negation rule? In this case, one way is to use an antonym argument unhappy-01 to replace happy-01 and then add a :polarity -. But it seems hard to do that automatically if I got many sentences and I did not have a dictionary library that includes the whole antonym argument in AMR. Do you know there is a antonym dictionary library in AMR? Many thanks.

The original sentence is like that.

# ::snt I am happy today.
(h / happy-01
      :ARG1 (ii / i)
      :time (t / today))

The AMR by adding a :polarity - and change the happy-01 to unhappy-01.

# ::snt I'm not unhappy today.
(h / unhappy-01
      :ARG1 (ii / i)
      :time (t / today)
      :polarity -)
goodmami commented 2 years ago

Do you know there is a antonym dictionary library in AMR?

There is none. You might try WordNet (see the NLTK or Wn for Python libraries).

14H034160212 commented 2 years ago

Thanks a lot!

14H034160212 commented 2 years ago

Do you know anyone or some existing work is working on using AMR to represent double negation?

goodmami commented 2 years ago

No, sorry, I'm not aware of any work like that.

14H034160212 commented 2 years ago

Here is my implementation by using AMR and WordNet to represent double negation.

def double_negation(graphs, sentence_list, logic_word_list):
    return_list = []
    label_list = []
    sentence_and_tag_list = []
    if graphs is None:
        return
    for index, graph in enumerate(graphs):
        if graph is None:
            continue
        g = penman.decode(graph)
        updated_g = copy.deepcopy(g)
        if ":polarity -" not in graph:  ## We only consider the case that the sentence does not have negation.
            z0 = updated_g.instances()[0].source
            updated_g.triples.append((z0, ':polarity', '-'))
            temp_graph = penman.encode(updated_g)
            start = temp_graph.index("\n")
            return_list.append(temp_graph[start+1:len(temp_graph)])
            sentence_and_tag_list.append([sentence_list[index], logic_word_list[index]])

    if len(return_list) > 0:
        gtos = amrlib.load_gtos_model("./pretrained_models/model_generate_t5wtense-v0_1_0")
        sents, _ = gtos.generate(return_list)
        punctuation_string = string.punctuation
        return_sents = []
        returned_sentence_and_tag_list = []

        for idx, sent in enumerate(sents):
            temp_sent = copy.deepcopy(sent)
            for i in punctuation_string:
                temp_sent = temp_sent.replace(i, '')
            splited_sent = temp_sent.split()
            for stem in splited_sent:
                if len(wordnet.synsets(stem)) > 0:
                    syn = wordnet.synsets(stem)[0]
                    good = wordnet.synset(syn.name())
                    antonym = good.lemmas()[0].antonyms()
                    if len(antonym) > 0:
                        if wordnet.synsets(antonym[0].name())[0].pos() == 'a':
                            sent = sent.replace(stem,antonym[0].name())
                            returned_sentence_and_tag_list.append(sentence_and_tag_list[idx])
                            return_sents.append(sent)
                            label_list.append(1)
                            break

    return return_sents, label_list, returned_sentence_and_tag_list
goodmami commented 2 years ago

Thanks for sharing!