Сегментация текста с использованием пакета слов Python
Folks,
Я использую библиотеку Python wordsegment
Грант Дженкс за последние пару часов. Библиотека прекрасно работает для любых неполных слов или разделения комбинированных слов, таких как e nd
==> end
а также thisisacat
==> this is a cat
,
Я работаю над текстовыми данными, которые также включают числа, и использование этой библиотеки для этих текстовых данных имеет обратный эффект. Прекрасный текст increased $55 million or 23.8% for
превращается во что-то очень странное increased 55millionor238 for
(после выполнения операции соединения в списке перенастроенных). Обратите внимание, что это происходит случайным образом (может произойти или не произойти) для любой части текста, которая включает числа.
- Кто-нибудь работал с этой библиотекой раньше?
- Если да, сталкивались ли вы с подобной ситуацией и нашли ли вы обходной путь?
- Если нет, знаете ли вы о какой-либо другой библиотеке Python, которая делает этот трюк для нас?
Спасибо.
1 ответ
В Ruby и Python есть реализации, которые помогут понять этот алгоритм Python Витерби.
Алгоритм (и эти реализации) довольно прост, и копирование и вставка может быть лучше, чем использование библиотеки, потому что (по моему опыту) эта проблема почти всегда требует некоторой настройки, чтобы соответствовать имеющимся данным (например, язык / конкретные темы / настраиваемые объекты / формат даты или валюты).
Глядя на код, segment
функция сначала запускается clean
при этом удаляются все не алфавитно-цифровые символы, затем выполняется поиск известных униграмм и биграмм в скоплении текста и производится оценка найденных слов на основе частоты их появления на английском языке.
'increased $55 million or 23.8% for'
становится
'increased55millionor238for'
При поиске подслов, он находит 'increased'
а также 'for'
, но оценка за неизвестную фразу '55millionor238'
лучше, чем оценка за то, что он по какой-то причине
Похоже, что лучше с неизвестным текстом, особенно с меньшими неизвестными текстовыми элементами. Вы можете заменить не алфавитные последовательности символов, выполнить их segment
а затем заменить обратно.
import re
from random import choices
CONS = 'bdghjklmpqvwxz'
def sub_map(s, mapping):
out = s
for k,v in mapping.items():
out = out.replace(k,v)
return out
mapping = {m.group():''.join(choices(cons, k=3)) for m
in re.finditer(r'[0-9\.,$%]+', s)}
revmap = {v:k for k,v in mapping.items()}
word_list = wordsegment.segment(sub_map(s, mapping))
word_list = [revmap.get(w,w) for w in word_list]
word_list
# returns:
['increased', '$55', 'million', 'or', '23.8%', 'for']