stefanDeveloper / inference

Quantifiers and monotonicity in reasoning tasks
1 stars 1 forks source link

Trainings- und Evaluationsdatensatz für Opposite Adjectives in Monotonicity #8

Closed niklaskorz closed 3 years ago

niklaskorz commented 3 years ago

Auf Basis von MonaLog, WordNet, Winogrande und dem Datensatz aus #2 soll ein Trainings- und Evaluationsdatensatz erstellt werden, der sich auf Opposite Adjectives, wenn möglich in Kombination mit Monotonicity, konzentriert. Welche dieser Grundlagen sich am besten für Training oder Evaluation eignet, muss noch untersucht werden. Es wäre auch möglich, einen gemeinsamen Datensatz zu erstellen und diesen in 80/70% Training und 20/30% Validation aufzuteilen. Das Format sollte sich an den bisherigen Issues orientieren.

Personen: 2 oder 3

niklaskorz commented 3 years ago

Links:

niklaskorz commented 3 years ago

FraCas Opposite Adjectives gehört noch zum Evaluationsdatensatz für dieses Problem, aber das sind nur eine Hand voll Sätze.

niklaskorz commented 3 years ago

https://github.com/clips/pattern enthält eine API für WordNet, mit der wir nach Gegensätzen zu einem Adjektiv suchen können.

niklaskorz commented 3 years ago

Mit pattern und WordNet lassen sich wie folgt die Opposite Adjectives für ein Adjektiv auslesen:

from pattern.en import wordnet

def opposite_adjectives(word):
    synsets = wordnet.synsets(word, pos=wordnet.ADJECTIVE)
    antonyms = [a for s in synsets if s.antonym is not None for a in s.antonym]
    return { syn for a in antonyms for syn in a.synonyms }

Als Alternative habe ich probiert, nicht nur die Synonyme der Antonyme zu nehmen, sondern auch die Antonyme der Synonyme:

def opposite_adjectives(word):
    synsets = wordnet.synsets(word, pos=wordnet.ADJECTIVE)
    synonyms = [wordnet.synsets(syn, pos=wordnet.ADJECTIVE) for s in synsets for syn in s.synonyms]
    synsets = [s for ss in synonyms for s in ss]
    antonyms = [a for s in synsets if s.antonym is not None for a in s.antonym]
    return { syn for a in antonyms for syn in a.synonyms }

Das führt zwar zu mehr Ergebnissen, aber leider enthalten diese dann auch viele False Positives.

niklaskorz commented 3 years ago

Mit nltk können wir die Sätze nach Adjektiven durchsuchen und auch überprüfen, ob diese Komparative / Superlative sind, um dann entsprechend mit pattern die Antonyme anzupassen.

import nltk
nltk.download('averaged_perceptron_tagger')

ADJ = "JJ"
ADJ_CMP = "JJR"
ADJ_SUP = "JJS"

def replace_adjectives(text):
    text = text.split()
    tags = nltk.pos_tag(text)
    candidates = [[]]
    for token, tag in tags:
        if tag in [ADJ, ADJ_CMP, ADJ_SUP]:
            opposites = opposite_adjectives(token)
            if tag == ADJ_CMP:
                opposites = [comparative(w) for w in opposites]
            elif tag == ADJ_SUP:
                opposites = [superlative(w) for w in opposites]
            candidates = [c + [w] for c in candidates for w in opposites]
        else:
            candidates = [c + [token] for c in candidates]
    return [" ".join(tokens) for tokens in candidates]
niklaskorz commented 3 years ago

Automatische Annotierung der Daten über MonaLog oder ccg2lambda liefert leider nur "unknown" als Ergebnisse, egal für welches Satzpaar. Stattdessen werden wir einen kleineren Datensatz anlegen und per Hand annotieren.