Вопрос

Я работаю над решением разделения длинных линий кхмеров (камбоджийский язык) на отдельные слова (в UTF-8). Кхмер не использует пространства между словами. Есть несколько решений, но они далеки от адекватных (здесь а также здесь), и эти проекты упали на обочине.

Вот образец линии кхмеров, которую нужно разделить (они могут быть длиннее этого):

ចូរសរសើរដល់ទ្រង់ដែលទ្រង់បានប្រទានការទាំងអស់នោះមកដល់រូបអ្នកដោយព្រោះអង្គព្រះយេស៊ូវ ហើយដែលអ្នកមិនអាចរកការទាំងអស់នោះដោយសារការប្រព្រឹត្តរបស់អ្នកឡើយ។

Цель создания жизнеспособного решения, которое расщепляет кхмерские слова,-два раза: оно поощряет тех, кто использовал шрифты наследия кхмерского наследия (не Unicode) для преобразования в Unicode (который имеет много преимуществ), и это позволит импортировать унаследованные кхмерские шрифты в Unicode для быстрого использования с помощью проверки орфографии (а не вручную проходить и разделить слова, которые с большим документом могут занять очень много времени).

Мне не нужна 100% точность, но скорость важна (особенно потому, что линия, которую необходимо разделить на кхмерские слова, может быть довольно длинной). Я открыт для предложений, но в настоящее время у меня есть большой корпус кхмерских слов, которые правильно разделены (с неразрывным пространством), и я создал файл словесного слова (частота.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, и я действительно новичок во всех реальных программировании (вне веб -сайтов), поэтому, пожалуйста, терпите меня. У кого -нибудь есть какие -либо варианты, которые, по его мнению, будут работать хорошо?

Это было полезно?

Решение

Библиотека ICU (в которой Питон и Java -привязки) имеет Словарий на основе взрыва класс, который можно использовать для этого.

Другие советы

Питон с примером filesaveas Похоже, что выходит через всю входную строку (for i in xrange(1, len(text) + 1)), вбивая лучшие результаты в cache по пути; При каждом потенциальном словом это тогда начинает смотреть на следующий Слово (которое, в свою очередь, посмотрите на слово после этого, и так далее), и если это второе слово не выглядит очень хорошо, оно не сохранит это конкретное. Это чувствует себя как O (N!) Средство выполнения, где n - длина входной строки.

Супер умный, но, вероятно, ужасен для чего -либо, кроме простых задач. Какое самое длинное кхмерское слово у вас есть? Я надеюсь <20 персонажей.

Возможно, если вы подаете ввод в этот пример 20 символов за раз, вы сможете сдержать время выполнения до чего -то разумного. Поправьте в первых 20 Chars, отсоедините первое слово, а затем подайте на оставшемся входе. Если вы повторно используете кэш, он может сделать что-то глупое, например, частичные слова магазина.

На совершенно ином примере, сколько кхмерских слов сформировано путем объединения двух или более законных кхмерских слов? (Подобно «Penknife» или «Basketball»), если не слишком много, может иметь смысл создать набор словарей, отделенных по длине слова, отображения от слова к вероятности использования.

Скажем, самое длинное кхмерское слово - 14 чар; подавать 14 символов ввода в len14 Словарь, храните вероятность. Подавать в 13 символов в len13, хранить вероятность. Подавать в 12 символов ... вплоть до 1 в len1. Анкет Затем выберите интерпретацию с самой высокой вероятностью, сохраните слово, разделите столько символов и попробуйте еще раз.

Таким образом, это не удастся плохо для входов, таких как «i» против изображения », может быть, более длительные входы должны иметь автоматически надувные вероятности?

Спасибо за забавный вопрос;) Я не знал ни о каких таких языках, довольно круто.

Я думаю, что это хорошая идея, как есть.

Я предлагаю вам, когда у вас есть какой -то опыт с ним, вы добавляете несколько правил, которые могут быть очень конкретными, например, в зависимости от слова, в зависимости от слова после, в зависимости от окружающих слов, в зависимости от последовательности слов перед текущим Слово, просто чтобы перечислить самые частые. Вы можете найти набор правил в проекте gposttl.sf.net, который представляет собой проект по тегам POS, в файловых данных/contextRuleFile.

Правила должны использоваться после того, как оценка статистики завершена, они делают некоторую тонкую настройку и могут удивительно повысить точность.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top