#python #text #split #nltk #sentence
#python #текст #разделить #nltk #предложение
Вопрос:
У меня есть функция, которая оценивает слова. У меня много текста из предложений в документы на несколько страниц. Я застрял на том, как выделить слова и вернуть текст в исходное состояние.
Вот пример предложения:
"My body lies over the ocean, my body lies over the sea."
Что я хочу создать, так это следующее:
"My body (2) lies over the ocean (3), my body (2) lies over the sea."
Ниже приведена фиктивная версия моего алгоритма подсчета очков. Я выяснил, как взять текст, разорвать его на части и записать.
Тем не менее, я застрял на том, как собрать его обратно в формат, в котором он мне нужен.
Вот фиктивная версия моей функции:
def word_score(text):
words_to_work_with = []
words_to_return = []
passed_text = TextBlob(passed_text)
for word in words_to_work_with:
word = word.singularize().lower()
word = str(word)
e_word_lemma = lemmatizer.lemmatize(word)
words_to_work_with.append(e_word_lemma)
for word in words to work with:
if word == 'body':
score = 2
if word == 'ocean':
score = 3
else:
score = None
words_to_return.append((word,score))
return words_to_return
Я относительный новичок, поэтому у меня есть два вопроса:
- Как я могу снова соединить текст и
- Должна ли эта логика быть помещена в функцию или вне ее?
Мне бы очень хотелось иметь возможность загружать целые сегменты (т. Е. Предложения, документы) в функцию и заставлять ее возвращать их.
Спасибо, что помогли мне!
Комментарии:
1. Вы уверены, что этот код работает?
def word_score(text)
не хватает завершающего двоеточия иpassed_text = TextBlob(passed_text)
, скорее всего, вызовет ошибку2. @MaximGi, реальная функция сложна, поэтому я попытался придумать упрощенный пример, пересмотрел его в соответствии с вашим ответом и попытался сделать его более упрощенным примером. Спасибо.
Ответ №1:
Итак, по сути, вы хотите присвоить оценку каждому слову. Предоставляемая вами функция может быть улучшена с использованием словаря вместо нескольких if
операторов. Также вы должны вернуть все оценки, а не только оценку первого word
в words_to_work_with
, которая является текущим поведением функции, поскольку она вернет целое число на первой итерации. Итак, новая функция будет :
def word_score(text)
words_to_work_with = []
passed_text = TextBlob(text)
for word in words_to_work_with:
word = word.singularize().lower()
word = str(word) # Is this line really useful ?
e_word_lemma = lemmatizer.lemmatize(word)
words_to_work_with.append(e_word_lemma)
dict_scores = {'body' : 2, 'ocean' : 3, etc ...}
return [dict_scores.get(word, None)] # if word is not recognized, score is None
Для второй части, которая реконструирует строку, я бы фактически сделал это в той же функции (так что это отвечает на ваш второй вопрос) :
def word_score_and_reconstruct(text):
words_to_work_with = []
passed_text = TextBlob(text)
reconstructed_text = ''
for word in words_to_work_with:
word = word.singularize().lower()
word = str(word) # Is this line really useful ?
e_word_lemma = lemmatizer.lemmatize(word)
words_to_work_with.append(e_word_lemma)
dict_scores = {'body': 2, 'ocean': 3}
dict_strings = {'body': ' (2)', 'ocean': ' (3)'}
word_scores = []
for word in words_to_work_with:
word_scores.append(dict_scores.get(word, None)) # we still construct the scores list here
# we add 'word' '(word's score)', only if the word has a score
# if not, we add the default value '' meaning we don't add anything
reconstructed_text = word dict_strings.get(word, '')
return reconstructed_text, word_scores
Я не гарантирую, что этот код сработает с первой попытки, я не могу его протестировать, но он даст вам основную идею
Комментарии:
1. Похоже на действительное потенциальное решение, попытаюсь изменить мой реальный код на код для тестирования и приму ответ, как только он заработает. Спасибо!
2. Небольшое предложение для
dict_strings
: Предполагая, что у вас будет много таких на практике, вы можете создать этот словарь с пониманием dict:{word: ' (' str(score) ')' for word, score in dict_scores.items()}
Ответ №2:
Надеюсь, это поможет. Судя по вашему вопросу, у меня это сработало.
с наилучшими пожеланиями!!
"""
Python 3.7.2
Input:
Saved text in the file named as "original_text.txt"
My body lies over the ocean, my body lies over the sea.
"""
input_file = open('original_text.txt', 'r') #Reading text from file
output_file = open('processed_text.txt', 'w') #saving output text in file
output_text = []
for line in input_file:
words = line.split()
for word in words:
if word == 'body':
output_text.append('body (2)')
output_file.write('body (2) ')
elif word == 'body,':
output_text.append('body (2),')
output_file.write('body (2), ')
elif word == 'ocean':
output_text.append('ocean (3)')
output_file.write('ocean (3) ')
elif word == 'ocean,':
output_text.append('ocean (3),')
output_file.write('ocean (3), ')
else:
output_text.append(word)
output_file.write(word ' ')
print (output_text)
input_file.close()
output_file.close()
Ответ №3:
Вот рабочая реализация. Функция сначала анализирует входной текст в виде списка, таким образом, что каждый элемент списка представляет собой слово или комбинацию знаков препинания (например. запятая, за которой следует пробел.) Как только слова в списке обработаны, он объединяет список обратно в строку и возвращает его.
def word_score(text):
words_to_work_with = re.findall(r"bw |bW ",text)
for i,word in enumerate(words_to_work_with):
if word.isalpha():
words_to_work_with[i] = inflection.singularize(word).lower()
words_to_work_with[i] = lemmatizer.lemmatize(word)
if word == 'body':
words_to_work_with[i] = 'body (2)'
elif word == 'ocean':
words_to_work_with[i] = 'ocean (3)'
return ''.join(words_to_work_with)
txt = "My body lies over the ocean, my body lies over the sea."
output = word_score(txt)
print(output)
Вывод:
My body (2) lie over the ocean (3), my body (2) lie over the sea.
Если у вас есть более 2 слов, которые вы хотите оценить, использование словаря вместо if
условий действительно хорошая идея.