Politician Translator met Spacy en Negate.
Zoek uit wat politici echt bedoelen door hun tekst in het tegenovergestelde te veranderen.
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
Lees meer
Machine Learning
Recent
- Database UUID primaire sleutels van je webapplicatie verbergen
- Don't Repeat Yourself (DRY) met Jinja2
- SQLAlchemy, PostgreSQL, maximum aantal rijen per user
- Toon de waarden in SQLAlchemy dynamische filters
- Veilige gegevensoverdracht met Public Key versleuteling en pyNaCl
- rqlite: een alternatief voor SQLite met hoge beschikbaarheid en distributed
Meest bekeken
- Met behulp van Python's pyOpenSSL om SSL-certificaten die van een host zijn gedownload te controleren
- Gebruik van UUIDs in plaats van Integer Autoincrement Primary Keys met SQLAlchemy en MariaDb
- Maak verbinding met een dienst op een Docker host vanaf een Docker container
- PyInstaller en Cython gebruiken om een Python executable te maken
- SQLAlchemy: Gebruik van Cascade Deletes om verwante objecten te verwijderen
- Flask RESTful API verzoekparametervalidatie met Marshmallow-schema's