¿Una solución viable para dividir palabras en jemer?

Estoy trabajando en una solución para dividir las líneas largas de jemer (el idioma camboyano) en palabras individuales (en UTF-8). Khmer no usa espacios entre palabras. Existen algunas soluciones, pero están lejos de ser adecuadas ( aquí y aquí ), y esos proyectos se han quedado en el camino.

Aquí hay una línea de muestra de Khmer que necesita ser dividida (pueden ser más largas que esto):

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

El objective de crear una solución viable que divida las palabras en jemer es doble: alentará a aquellos que usaron fonts heredadas (no Unicode) en jemer para que se conviertan a Unicode (lo que tiene muchos beneficios), y permitirá que se importen las fonts en jemer heredadas. en Unicode para usar con un corrector ortográfico rápidamente (en lugar de leer y dividir manualmente las palabras que, con un documento grande, puede llevar mucho tiempo).

No necesito 100% de precisión, pero la velocidad es importante (especialmente porque la línea que debe dividirse en palabras en jemer puede ser bastante larga). Estoy abierto a sugerencias, pero en la actualidad tengo un gran corpus de palabras jemer que están correctamente divididas (con un espacio de no ruptura), y he creado un archivo de diccionario de probabilidad de palabras (frequency.csv) para usar como diccionario para el separador de palabras

    Encontré este código de Python aquí que usa el algoritmo Viterbi y supuestamente se ejecuta rápido.

    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('[az]+', 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())) 

    También intenté usar el código fuente de Java del autor de esta página: Segmentación de texto: división de palabras basada en el diccionario, pero fue demasiado lento para ser de alguna utilidad (porque mi diccionario de probabilidad de palabras tiene más de 100k términos …).

    Y aquí hay otra opción en python desde Detectar las palabras más probables del texto sin espacios / palabras combinadas :

     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']) 

    Soy un newbee cuando se trata de python y soy realmente nuevo en toda la progtwigción real (fuera de los sitios web), así que por favor, tengan paciencia conmigo. ¿Alguien tiene alguna opción que crea que funcione bien?

    La biblioteca de ICU (que tiene enlaces de Python y Java) tiene una clase DictionaryBasedBreakIterator que se puede usar para esto.

    El python con ejemplo filesaveas parece filesaveas a través de toda la cadena de entrada ( for i in xrange(1, len(text) + 1) ), rellenando los mejores resultados en el cache en el camino; en cada palabra potencial, luego comienza a mirar la siguiente palabra (que a su vez mirará la palabra después de eso, y así sucesivamente), y si esa segunda palabra no se ve muy bien, no salvará esa palabra en particular . Se siente como el tiempo de ejecución O (N!), Donde N es la longitud de la cadena de entrada.

    Súper inteligente, pero probablemente horrible para cualquier cosa que no sean tareas simples. ¿Cuál es la palabra jemer más larga que tienes? Espero <20 caracteres.

    Tal vez si ingresa datos de entrada en ese ejemplo, 20 caracteres a la vez, puede mantener el tiempo de ejecución en un valor razonable. Ingrese los primeros 20 caracteres, succione la primera palabra y luego ingrese la entrada restante. Si reutiliza el caché, podría hacer algo estúpido como almacenar palabras parciales en el camino.

    En una estrategia completamente diferente, ¿cuántas palabras en jemer se forman concatenando dos o más palabras en jemer legales? (similar a ‘razor’ o ‘baloncesto’) Si no son demasiados, podría tener sentido crear un conjunto de diccionarios, segregados por la longitud de la palabra, mapeando de la palabra a la probabilidad de uso.

    Digamos, la palabra jemer más larga tiene 14 caracteres de largo; introduzca 14 caracteres de entrada en el diccionario len14 , almacene la probabilidad. Alimenta 13 caracteres en len13 , almacena la probabilidad. Alimente en 12 caracteres … hasta 1 en len1 . Luego elija la interpretación con la mayor probabilidad, guarde la palabra, elimine esa cantidad de caracteres e intente nuevamente.

    Así que no fallará mal para entradas como “I” vs “Imagen”, ¿tal vez las entradas más largas deberían tener probabilidades infladas automáticamente?

    Gracias por la divertida pregunta;) No conocía ningún idioma como este, muy bien.

    Creo que esta es una buena idea, ya que es.

    Le sugiero que, cuando tenga alguna experiencia con él, agregue algunas reglas, que pueden ser muy específicas, por ejemplo, dependiendo de la palabra anterior, dependiendo de la palabra siguiente, dependiendo de las palabras circundantes, dependiendo de una secuencia de palabras antes de la stream Palabra, sólo para enumerar las más frecuentes. Puede encontrar un conjunto de reglas en el proyecto gposttl.sf.net, que es un proyecto de etiquetado pos, en el archivo datos / contextualrulefile.

    Las reglas deben usarse DESPUÉS de que finalice la evaluación de las estadísticas, hacen algunos ajustes y pueden mejorar notablemente la precisión.