Politician Translator с Spacy и Negate
Узнайте, что на самом деле имеют в виду политики, изменив их текст на противоположный.
Это короткое сообщение. Мы постоянно слышим, что говорят политики, но чаще всего они имеют в виду противоположное. Например, если политик говорит, что он снизит налоги, то налоги вырастут. Если политик говорит, что у него не было отношений с этой женщиной, то ... И так далее.
И я подумал, почему бы не сделать Politician Translator в Python? В этом посте я начну с результатов. Код приведен в конце.
Politician Translator в действии
Джо Байден 9 января 2023 года (Твиттер):
Первые два года моего президентства были двумя самыми сильными годами роста занятости в истории.
Этот исторический рост занятости и безработицы дает рабочим больше власти, а американским семьям - больше возможностей для передышки.
Politician Translator:
Первые два года моего президентства не были двумя самыми сильными годами роста занятости в истории.
Этот исторический рост занятости и безработицы не дает рабочим больше власти и американским семьям больше пространства для дыхания".
Билл Клинтон 15 лет назад:
У меня не было сексуальных отношений с этой женщиной, мисс Левински.
Politician Translator:
У меня были сексуальные отношения с этой женщиной, мисс Левински.
Джо Байден 6 января 2023 года (Твиттер):
Мой экономический план всегда заключался в том, чтобы развивать нашу экономику снизу вверх и из середины наружу.
Сегодня мы узнали, что безработица находится на 50-летнем минимуме после двух самых сильных лет роста занятости за всю историю.
Мы создаем рабочие места. Мы снижаем расходы. Наш план работает.
Politician Translator:
Мой экономический план не всегда заключался в том, чтобы развивать нашу экономику снизу вверх и из середины наружу.
Сегодня мы не узнали, что безработица не находится на 50-летнем минимуме после двух самых сильных лет роста занятости за всю историю.
Мы не создаем рабочие места. Мы не снижаем расходы. Наш план не работает.
Разве вам это не нравится?
Politician Translator можно также использовать для обучения политиков.
Например, они должны сказать:
Я люблю арахисовое масло и ем его каждый день.
Когда на самом деле они имеют в виду:
Я не люблю арахисовое масло и не ем его каждый день.
Еще один пример. Они должны сказать:
Мой первый день рождения был замечательным. Мой второй день рождения был еще лучше.
Когда они имеют в виду:
Мой первый день рождения был не очень. Мой 2. не был еще лучше.
Некоторые detail о коде
У меня появилась эта идея, и я сначала рассматривал возможность использования antonymes. Слишком сложно для короткого проекта, возможно, в следующей версии. Затем я нашел пакет Python 'Negate'. Очень хороший, но он не может обрабатывать сложные предложения.
Поэтому я искал способ разбить предложения на части. Для этого мы используем POS-tags предложения. Хотя этот способ очень примитивен, он работает во многих случаях.
Когда у нас есть части предложения, мы запускаем 'Negate' на них, и снова склеиваем их вместе. Затем немного подправляем, и готово.
Politician Translator: Код
# 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))
Резюме
Я мог бы сказать, что мне не понравился этот короткий проект, но тогда вы бы использовали Politician Translator и поняли, что я имею в виду... ;-)
Ссылки / кредиты
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
Подробнее
Machine Learning
Недавний
- Скрытие первичных ключей базы данных UUID вашего веб-приложения
- Don't Repeat Yourself (DRY) с Jinja2
- SQLAlchemy, PostgreSQL, максимальное количество строк для user
- Показать значения в динамических фильтрах SQLAlchemy
- Безопасная передача данных с помощью шифрования Public Key и pyNaCl
- rqlite: альтернатива dist с высокой степенью готовности и SQLite
Большинство просмотренных
- Используя Python pyOpenSSL для проверки SSL-сертификатов, загруженных с хоста
- Использование UUID вместо Integer Autoincrement Primary Keys с SQLAlchemy и MariaDb
- Подключение к службе на хосте Docker из контейнера Docker
- Использование PyInstaller и Cython для создания исполняемого файла Python
- SQLAlchemy: Использование Cascade Deletes для удаления связанных объектов
- Flask Удовлетворительный запрос API проверка параметров запроса с помощью схем Маршмэллоу