angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Politician Translator met Spacy en Negate.

Zoek uit wat politici echt bedoelen door hun tekst in het tegenovergestelde te veranderen.

11 januari 2023
post main image
https://www.pexels.com/nl-nl/@pixabay

Dit is een kort bericht. De hele tijd horen we politici praten, maar meestal bedoelen ze het tegenovergestelde. Bijvoorbeeld, als een politicus zegt dat hij de belastingen zal verlagen, dan gaan de belastingen omhoog. Als een politicus zegt dat hij geen relatie heeft met die vrouw, dan... Etc.

Dus ik dacht, waarom geen Politician Translator maken in Python? In deze post begin ik met de resultaten. De code staat aan het eind.

De Politician Translator in actie

Joe Biden op 9 januari 2023 (Twitter):

De eerste twee jaar van mijn presidentschap waren de twee sterkste jaren van banengroei ooit.
Deze historische banen- en werkloosheidsgroei geeft werknemers meer macht en Amerikaanse gezinnen meer ademruimte.

Politician Translator:

De eerste twee jaar van mijn presidentschap waren niet de twee sterkste jaren van banengroei ooit.
Deze historische banen- en werkloosheidsgroei geeft werknemers niet meer macht en Amerikaanse gezinnen niet meer ademruimte.

Bill Clinton 15 jaar geleden:

Ik had geen seksuele relaties met die vrouw, juffrouw Lewinsky.

Politician Translator:

Ik had seksuele relaties met die vrouw, Miss Lewinsky.

Joe Biden op 6 januari 2023 (Twitter):

Mijn economisch plan is altijd geweest om onze economie te laten groeien van onder naar boven en het midden naar buiten.
Vandaag leerden we dat de werkloosheid op het laagste punt in 50 jaar is na de twee sterkste jaren van banengroei ooit.
We creëren banen. We verlagen de kosten. Ons plan werkt.

Politician Translator:

Mijn economisch plan is niet altijd geweest om onze economie van onder naar boven en van midden naar buiten te laten groeien.
Vandaag hebben we niet geleerd dat de werkloosheid niet op een 50 - jaar laag is na de twee sterkste jaren van banengroei ooit.
We creëren geen banen. We verlagen de kosten niet. Ons plan werkt niet.

Vind je het niet geweldig!

De Politician Translator kan ook gebruikt worden om politici te trainen.

Ze moeten bijvoorbeeld zeggen:

Ik hou van pindakaas en eet het elke dag.

Terwijl ze eigenlijk bedoelen:

Ik hou niet van pindakaas en eet het niet elke dag.

Een andere. Ze moeten zeggen:

Mijn eerste verjaardag was geweldig. Mijn 2. was nog beter.

Als ze bedoelen:

Mijn eerste verjaardag was niet geweldig. Mijn 2. was niet eens beter.

Enkele detail's over de code

Ik kreeg dit idee en keek eerst naar het gebruik van antonymes. Te complex voor een kort project, misschien in een volgende versie. Toen vond ik het pakket Python . Heel mooi, maar het kan niet overweg met samengestelde zinnen.

Dus zocht ik naar een manier om de zinnen in delen te breken. Daarvoor gebruiken we de POS-tags van een zin. Hoewel erg primitief, zal het in veel gevallen werken.

Zodra we de delen van een zin hebben, draaien we 'Negate' erop, en plakken ze weer aan elkaar. Dan wat opknappen, en klaar.

Politician Translator: De code

# your text
text = """The first two years of my presidency were the two strongest years of job growth on record. 
These historic jobs and unemployment gains are giving workers more power and American families more breathing room.
"""

text = """I did not have sexual relations with that woman, Miss Lewinsky."""

#text = """I like peanut butter and eat it every day."""

#text = """My first birthday was great. My 2. was even better."""


import re
from negate import Negator
import spacy
from spacy.lang.en import English


class TextToSentences:
    def __init__(self):
        self.nlp = spacy.load('en_core_web_sm')
        self.nlp.add_pipe('sentencizer')
    
    def get_sentences(self, text):
        doc = self.nlp(text)
        return [sent.text.strip() for sent in doc.sents]

class SentenceToParts:
    def __init__(self):
        self.nlp = spacy.load('en_core_web_sm')

    def get_parts(self, sentence):
        doc = self.nlp(sentence)
        parts, words = [], []
        for token in doc:
            if token.pos_ in ['CCONJ', 'SCONJ']:
                parts.append(' '.join(words))
                words = []
            words.append(token.text)
        if len(words) > 0:
            parts.append(' '.join(words))
        return parts

class NegateParts:
    def __init__(self):
        self.negator = Negator(use_transformers=True)

    def get_negated_parts(self, parts):
        negated_parts = []
        for part in parts:
            negated_parts.append(self.negator.negate_sentence(part, prefer_contractions=False))
        return negated_parts

class StitchParts:
    def __init__(self):
        self.nlp = spacy.load('en_core_web_sm')

    def get_stitched_parts(self, parts):
        stitched_parts_items = []
        for i, part in enumerate(parts):
            # first word to lowercase if not PROPN
            doc = self.nlp(part)
            words = []
            for j, token in enumerate(doc):
                word = token.text
                if i > 0 and j == 0 and token.pos not in ['PROPN']:
                    word = word.lower()
                words.append(word)
            stitched_parts_items.append(' '.join(words))
        return ' '.join(stitched_parts_items)
                
class FixUpSentence:
    def __init__(self):
        pass

    def get_fixedup_sentence(self, sentence):
        # trim
        sentence = sentence.strip()
        # fix: end of line ' .'
        sentence = re.sub(r'\s\.$', '.', sentence)
        # fix: ' ’s'
        sentence = sentence.replace(' ’s', '\'s')
        # fix: ' , '
        sentence = sentence.replace(' , ', ', ')
        return sentence
       
tts = TextToSentences()
stp = SentenceToParts()
np = NegateParts()
sp = StitchParts()
fus = FixUpSentence()

# step 1: split text into sentences
sentences = tts.get_sentences(text)
    
ftext_items = []
for sentence in sentences:
    # step 2.1: split sentence into sub-sentences
    parts = stp.get_parts(sentence)
    # step 2.2: negate sub-sentences
    nparts = np.get_negated_parts(parts)
    # step 2.3: create sentences from sub-sentences
    nsentence = sp.get_stitched_parts(nparts)
    #print('nsentence = {}'.format(nsentence))
    fsentence = fus.get_fixedup_sentence(nsentence)
    # step 2.4: Remove spaces etc.
    ftext_items.append(fsentence)

# step 3: join sentences
ftext = ' '.join(ftext_items)

print('what they say = \n{}'.format(text))
print('what they mean = \n{}'.format(ftext))

Samenvatting

Ik zou kunnen zeggen dat ik dit korte project niet leuk vond, maar dan zou je de Politician Translator gebruiken en weten wat ik echt bedoel ... ;-)

Links / credits

How to break up document by sentences with Spacy
https://stackoverflow.com/questions/46290313/how-to-break-up-document-by-sentences-with-spacy

Negate
https://pypi.org/project/negate

Tutorial on Spacy Part of Speech (POS) Tagging
https://machinelearningknowledge.ai/tutorial-on-spacy-part-of-speech-pos-tagging

Laat een reactie achter

Reageer anoniem of log in om commentaar te geven.

Opmerkingen

Laat een antwoord achter

Antwoord anoniem of log in om te antwoorden.