Я работаю над решением разбить длинные строки кхмерского (камбоджийский язык) на отдельные слова (в UTF-8). Кхмерский не использует пробелы между словами. Есть несколько решений, но они далеко не адекватны ( здесь и здесь ), и эти проекты отошли на второй план.
Вот пример строки кхмера, которую нужно разделить (они могут быть длиннее этой):
ចូរ សរសើរ ដល់ 100 ទ្រង់ បាន ទាំងអស់ ទាំងអស់ ទាំងអស់ ទាំងអស់ រូប រូប ព្រោះ អង្គ អង្គ អង្គ 101 101 101 101 101 101 101 101 101 101 101
Цель создания жизнеспособного решения, которое разделяет кхмерские слова, двояка: это побудит тех, кто использовал кхмерские устаревшие (не-Unicode) шрифты, переходить на Unicode (что имеет много преимуществ), и это позволит использовать старые кхмерские шрифты для импорта в Unicode для быстрого использования с проверкой орфографии (вместо того, чтобы вручную проходить и разбивать слова, что при большом документе может занять очень много времени).
Мне не нужна 100% точность, но важна скорость (особенно потому, что линия, которую нужно разделить на кхмерские слова, может быть довольно длинной).
Я открыт для предложений, но в настоящее время у меня есть большой набор кхмерских слов, которые правильно разделены (с неразрывным пробелом), и я создал файл словаря вероятности слова (quency.csv) для использования в качестве словаря для разделитель слов.
Я нашел этот код Python здесь , который использует алгоритм Витерби , и он предположительно работает быстро.
import re
from itertools import groupby
def viterbi_segment(text):
probs, lasts = [1.0], [0]
for i in range(1, len(text) + 1):
prob_k, k = max((probs[j] * word_prob(text[j:i]), j)
for j in range(max(0, i - max_word_length), i))
probs.append(prob_k)
lasts.append(k)
words = []
i = len(text)
while 0 < i:
words.append(text[lasts[i]:i])
i = lasts[i]
words.reverse()
return words, probs[-1]
def word_prob(word): return dictionary.get(word, 0) / total
def words(text): return re.findall('[a-z]+', text.lower())
dictionary = dict((w, len(list(ws)))
for w, ws in groupby(sorted(words(open('big.txt').read()))))
max_word_length = max(map(len, dictionary))
total = float(sum(dictionary.values()))
Я также пытался использовать исходный код Java от автора этой страницы: Сегментация текста: разбиение слов по словарю , но оно выполнялось слишком медленно, чтобы его можно было использовать (потому что мой словарь вероятности превышен 100 тысяч терминов ...).
А вот еще один вариант в python из Определение наиболее вероятных слов из текста без пробелов / комбинированных слов :
WORD_FREQUENCIES = {
'file': 0.00123,
'files': 0.00124,
'save': 0.002,
'ave': 0.00001,
'as': 0.00555
}
def split_text(text, word_frequencies, cache):
if text in cache:
return cache[text]
if not text:
return 1, []
best_freq, best_split = 0, []
for i in xrange(1, len(text) + 1):
word, remainder = text[:i], text[i:]
freq = word_frequencies.get(word, None)
if freq:
remainder_freq, remainder = split_text(
remainder, word_frequencies, cache)
freq *= remainder_freq
if freq > best_freq:
best_freq = freq
best_split = [word] + remainder
cache[text] = (best_freq, best_split)
return cache[text]
print split_text('filesaveas', WORD_FREQUENCIES, {})
--> (1.3653e-08, ['file', 'save', 'as'])
Я новичок, когда дело доходит до Python, и я действительно новичок во всем реальном программировании (за исключением веб-сайтов), поэтому, пожалуйста, потерпите меня. У кого-нибудь есть варианты, которые, по их мнению, будут работать хорошо?