Я пытаюсь использовать spacy для удаления стоп-слов из кадра данных panda, созданного из csv. Моя проблема в том, что я пытаюсь учесть слова, которые могут содержать сочетание слов и чисел.
Моя проблема:
Если число разделяет слово так, что оно содержит стоп-слово, он удалит эту часть слова.
Ex. With stop word at the end
Input: 'co555in'
Breaks up the word, separating it in 'co'+ 555 + 'in'
Removes 'in' because it is a stop word.
Output: 'co555'
Ex. Without stop word at the end
Input: 'co555inn'
Breaks up the word, separating it in 'co'+ 555 + 'inn'
Will not remove 'inn' because it is not a stop word.
Output: 'co555inn'
Текущая реализация:
df[col] = df[col].apply(lambda text:
"".join(token.lemma_ for token in nlp(text)
if not token.is_stop))
Итак, я хотел бы иметь возможность учитывать смешанные числа и слова без пространственной фильтрации части слова, если число разделяет строку так, чтобы она содержала стоп-слово.
ОБНОВЛЕНИЕ: По словам разработчиков, это функция, а не ошибка. Таким образом, обходной путь, такой как ответ ниже, необходим для учета этих крайних случаев.
Редактировать № 2: Упростить код. Добавлена функциональность для удаления любых слов, содержащих числовые символы, из текста с использованием библиотеки регулярных выражений Python , а затем токенизации всего остального текста. Также добавлены дополнительные меры предосторожности, гарантирующие, что пунктуация не вызовет ошибки.
Вот мой метод remove_stopwords
с включенным дополнительным кодом, который я использовал для тестирования.
import spacy
import pandas as pd
import re
nlp = spacy.load('en_core_web_sm')
def remove_stopwords(text):
"""
Removes stop words from a text source
"""
number_words = re.findall(r'\w*\d+\w*', text)
remove_numbers = re.sub(r'\w*\d+\w*', '', text)
split_text = re.split(r'\W+', remove_numbers)
remove_stop_words = [word for word in split_text if not nlp.vocab[word].is_stop]
final_words = number_words + remove_stop_words
return " ".join(final_words)
df = pd.read_csv('input_file.csv', sep='\t') # replace with your CSV file
df['text'] = df['text'].apply(remove_stopwords)
df.to_csv('output_file.csv', index=False) # replace with your desired output file name
Обновление: это, по-видимому, в токенах, но не в «токенах» во время цикла for. Я понятия не имею, как это происходит. for token in tokens: print("Tokens: ", tokens) print("Token: ", token)
Вывод: Токены: co22in Токен: co22 Токены: co22in Токен: in
Обновление: I found a similar issue: https://github.com/explosion/spaCy/discussions/7843
. К сожалению, похоже, что это фича, а не баг. Мне нужно найти обходной путь к методу по умолчанию. Может быть, создать второй список слов, содержащих слова с цифрами в середине, а затем вернуть его в исходный список после форматирования?
@Jared Джаред, я обновил код после прочтения некоторых ваших отладок. Дайте мне знать, если обновленный код работает!
Мне пришлось удалить sep='\t'
из-за форматирования CSV, который я использую, но в остальном работает отлично!
Кажется, что-то происходит во время создания token_list. "co555in" никогда не попадает в новый список. Таким образом, никогда не помечаемый как «good_token». Может ли быть оператор условия, чтобы он не разделял любое слово, которое является буквенно-цифровым? Обновлено: проблема возникает во время токенизации. токен в токенах создает два разных токена «co555» и «in». Может ли проблема быть во время процесса токенизации «nlp»?