Удаление запятых после обработки списков строк, когда '' .join (x) не работает

Итак, я ввел фрейм данных предложений для предсказания токена в BERT, и я получил в качестве вывода вместе с предсказаниями предложения, разбитые на слова. Теперь я хочу вернуть мой фрейм данных разделенных / токенизированных предложений и прогнозов обратно к исходному предложению (конечно, у меня есть исходное предложение, но мне нужно сделать этот процесс, чтобы прогнозы согласовывались с токенами предложений)

original sentence
You couldn't have done any better because if you could have, you would have.

Post processing
['[CLS]', 'You', 'couldn', "'", 't', 'have', 'done', 'any', 'better', 'because', 'if', 'you', 'could', 'have', ',', 'you', 'would', 'have', '.', '[SEP]']

Я определил три необходимых процесса. 1. Удалите кавычки 2. Удалите CLS, SEP и их лишние кавычки и запятые, 3. Удалите запятые, разделяющие слова, и объедините их.

def fix_df(row):
    sentences = row['t_words'] 
    return remove_edges(sentences)

def remove_edges(sentences):
    x = sentences[9:-9]
    return remove_qmarks(x)

def remove_qmarks(x):
    y = x.replace("'", "")
    return join(y)

def join(y):
    z = ' '.join(y)
    return z


a_df['sents'] = a_df.apply(fix_df, axis=1) 

Первые две функции в основном работали правильно, а последняя - нет. вместо этого я получил результат, который выглядел так.

Y o u , c o u l d n , " " , t , h a v e, d o n e ,...

Запятые не исчезли, а текст был искажен. Я определенно что-то упускаю. что это могло быть?


person kay fresh    schedule 27.04.2020    source источник
comment
Не могли бы вы предоставить образец row['t_words']?   -  person Anwarvic    schedule 27.04.2020
comment
Во-первых, у вас нет кода, удаляющего запятые. Во-вторых, ваша функция обработки имеет потерю информации - пробелы. Невозможно восстановить предложения, не указав, где поставить пробелы.   -  person vitalious    schedule 27.04.2020
comment
@Anwarvic. Я сделал выше. post_processing - это образец строки [t_words], original - исходное предложение   -  person kay fresh    schedule 27.04.2020
comment
@vitalolious, как я могу решить эти две проблемы?   -  person kay fresh    schedule 27.04.2020
comment
Вы уверены, что пост-обработка возвращает строку? Это действительно похоже на простой список, который где-то раньше превратился в строку. Что, к сожалению, делает все ваши усилия после этого X / Y проблемой.   -  person Jongware    schedule 27.04.2020
comment
@kayfresh, попробуйте изменить функцию remove_qmarks() на y = x.replace(",", ""). И z = ''.join(y) в join() функции.   -  person Anwarvic    schedule 27.04.2020
comment
@ usr2564301 Он начинается как фрейм данных предложений, как образец из «исходного предложения», а затем, после этого я загружаю его в pytorch BERT, он токенизируется, и каждый соответствующий токен помечается. а затем он возвращается в виде списка токенов списка, который я преобразовал обратно в фрейм данных.   -  person kay fresh    schedule 27.04.2020
comment
@Anwarvic, следуя вашим идеям, я потеряю обычные запятые, которые являются частью предложения. И я этого не хочу.   -  person kay fresh    schedule 27.04.2020
comment
@ usr2564301 Если я буду рассматривать это как своего рода проблему X / Y, проблема X приведет к тому, как работает токенизация BERT   -  person kay fresh    schedule 27.04.2020
comment
Но вы говорите, что BERT (с которым я не знаком) возвращает список (списков). Где-то ваши следующие манипуляции превратят его в строковое представление. Это действительно стоит исследовать, потому что все проблемы, с которыми вы сталкиваетесь сейчас, волшебным образом исчезнут. Вы даже можете проверить это, скопировав текущую результирующую строку, которая у вас есть как буквальный код, и проверив, что она содержит.   -  person Jongware    schedule 27.04.2020
comment
@ usr2564301 позвольте мне рассказать подробнее. BERT использует токенизацию словосочетания, которая разбивает предложение не на слова, а на подслова (например, мандарин = man # da # rin # или что-то в этом роде.). Однако, несмотря на то, что он делает то же самое со словами при подготовке их к предсказаниям, он выводит токены, соответствующие словам. По сути, классификация знаков касается слов, а не предложений.   -  person kay fresh    schedule 27.04.2020


Ответы (1)


Строка результата действительно выглядит как строковое представление в остальном совершенно нормального списка, поэтому позвольте Python безопасно преобразовать ее обратно в список за Преобразовать строковое представление списка в список:

import ast

result = """['[CLS]', 'You', 'couldn', "'", 't', 'have', 'done', 'any', 'better', 'because', 'if', 'you', 'could', 'have', ',', 'you', 'would', 'have', '.', '[SEP]']"""

result_as_list = ast.literal_eval(result)

Теперь у нас есть это

['[CLS]', 'You', 'couldn', "'", 't', 'have', 'done', 'any', 'better', 'because', 'if', 'you', 'could', 'have', ',', 'you', 'would', 'have', '.', '[SEP]']

давай еще раз пройдемся по твоим стопам. Во-первых, «убрать кавычки». Но нет никаких (устаревших) кавычек, потому что это список строк; дополнительные кавычки, которые вы видите в представлении, только потому, что так строка представлена ​​в Python.

Далее «убираем маркеры начала и конца». Поскольку это список, это всего лишь первый и последний элементы, дальнейший подсчет не требуется:

result_as_list = result_as_list[1:-1]

Далее «убираем запятые». Как и в первом шаге, нет (устаревших) запятых; они являются частью того, как Python показывает список, и их нет в реальных данных.

Итак, мы получаем

['You', 'couldn', "'", 't', 'have', 'done', 'any', 'better', 'because', 'if', 'you', 'could', 'have', ',', 'you', 'would', 'have', '.']

который можно присоединить обратно к исходной строке, используя

result_as_string = ' '.join(result_as_list)

и единственная оставшаяся проблема заключается в том, что BERT, по-видимому, рассматривает апострофы, запятые и точки как отдельные «слова»:

You couldn ' t have done any better because if you could have , you would have .

которые нужно немного заменить:

result_as_string = result_as_string.replace(' ,', ',').replace(' .','.').replace(" ' ", "'")

и тебе вернули предложение:

You couldn't have done any better because if you could have, you would have.

Единственная проблема, которую я вижу, заключается в том, что есть ведущие или закрывающие кавычки, которые не являются частью сокращения. Если это необходимо, вы можете заменить замену пробела-кавычки более сфокусированной, нацеленной на «не могу», «не могу», «нет» и т. Д.

person Jongware    schedule 28.04.2020
comment
С небольшими изменениями этот ответ работал отлично. - person kay fresh; 29.04.2020