Frage

Ich arbeite an einer Lösung, um lange Zeilen von Khmer (der kambodschanischen Sprache) in einzelne Wörter (in UTF-8) aufzuteilen. Khmer verwendet keine Leerzeichen zwischen Wörtern. Es gibt ein paar Lösungen da draußen, aber sie sind alles andere als angemessen (hier und hier), und diese Projekte sind auf der Strecke geblieben.

Hier ist eine Beispiellinie von Khmer, die geteilt werden muss (sie können länger sein):

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

Das Ziel, eine praktikable Lösung zu schaffen, die Khmer-Wörter aufteilt in Unicode, um schnell mit einem Rechtschreibprüfung verwendet zu werden (anstatt manuell durchzugehen und Wörter aufzuteilen, die mit einem großen Dokument sehr lange dauern können).

Ich brauche keine 100% ige Genauigkeit, aber die Geschwindigkeit ist wichtig (zumal die Linie, die in Khmer -Wörter aufgeteilt werden muss, ziemlich lang sein kann). Ich bin offen für Vorschläge, aber derzeit habe ich einen großen Korpus von Khmer-Wörtern, die korrekt aufgeteilt sind (mit einem nicht brechen Wortsplitter.

Ich habe diesen Python -Code gefunden hier das benutzt das Viterbi -Algorithmus Und es läuft angeblich schnell.

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()))

Ich habe auch versucht, den Quell -Java -Code des Autors dieser Seite zu verwenden: Textsegmentierung: Wörterbuch-basierte Wortaufteilung Aber es lief zu langsam, um zu nutzen (weil mein Wortwahrscheinlichkeitswörterbuch über 100.000 Begriffe hat ...).

Und hier ist eine weitere Option in Python von Erkennen Sie höchstwahrscheinlich Wörter aus Text ohne Leerzeichen / kombinierte Wörter:

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

Ich bin ein Neubee, wenn es um Python geht und ich bin wirklich neu in allen echten Programmen (außerhalb von Websites), also bitte tragen Sie es mit mir. Hat jemand irgendwelche Optionen, von denen er glaubt, dass sie gut funktionieren würden?

War es hilfreich?

Lösung

Die Intensivbibliothek (das hat Python und Java -Bindungen) hat a Dictionarybased Breakiterator Klasse, die dafür verwendet werden kann.

Andere Tipps

Die Python mit Beispiel filesaveas scheint die gesamte Eingangszeichenfolge durchzusetzen (for i in xrange(1, len(text) + 1)), füllen die besten Ergebnisse in die cache nach dem Weg; Bei jedem potenziellen Wort es dann beginnt sich das anzusehen nächste Das Wort (was wiederum das Wort danach und so weiter betrachtet wird), und wenn dieses zweite Wort nicht sehr gut aussieht, wird es nicht das bestimmte retten. Es fühlt sich Wie O (n!) Laufzeit, wo n die Länge der Eingangszeichenfolge ist.

Super klug, aber wahrscheinlich schrecklich für alles andere als einfache Aufgaben. Was ist das längste Khmer -Wort, das Sie haben? Ich hoffe <20 Charaktere.

Wenn Sie die Eingabe in dieses Beispiel 20 Zeichen zu einem Zeitpunkt einfügen, können Sie die Laufzeit bis zu etwas nähern, das vernünftig ist. In den ersten 20 Zeichen füttern, das erste Wort absaugen und dann die verbleibende Eingabe einfügen. Wenn Sie den Cache wiederverwenden, kann dies etwas Dummes tun, wie Teilwörter auf dem Weg zu speichern.

Wie viele Khmer -Wörter werden auf einer völlig anderen Tackung gebildet, indem zwei oder mehr legale Khmer -Wörter verkettet werden? (Ähnlich wie "Penknife" oder "Basketball") Wenn nicht zu viele, ist es sinnvoll, eine Reihe von Wörterbüchern zu erstellen, die durch die Länge des Wortes getrennt sind und vom Wort bis zur Verwendung der Wahrscheinlichkeit der Verwendung zugeordnet werden.

Sagen Sie, das längste Khmer -Wort ist 14 Zeichen lang; Eingabe in 14 Zeichen Eingabe in die len14 Wörterbuch, speichern Sie die Wahrscheinlichkeit. In 13 Zeichen einspeisen in len13, speichern die Wahrscheinlichkeit. In 12 Zeichen füttern ... bis zu 1 in len1. Wählen Sie dann die Interpretation mit höchster Wahrscheinlichkeit, speichern Sie das Wort, streichen Sie so viele Zeichen ab und versuchen Sie es erneut.

Es wird also bei Eingaben wie "I" vs "Bild" nicht schlecht gescheitert, vielleicht sollten längere Eingaben automatisch aufgeblasene Wahrscheinlichkeiten aufgeblasen haben?

Danke für die lustige Frage;) Ich wusste keine solchen Sprachen, ziemlich cool.

Ich denke, das ist eine gute Idee, wie es ist.

Ich schlage Ihnen vor, dass Sie einige Regeln hinzufügen, die beispielsweise je nach Word danach einige Regeln hinzufügen, die beispielsweise je nach Wörtern je nach Wörtern je nach Wörtern vor dem Strom sind, sehr spezifisch sein kann. Wort, nur um die häufigsten aufzählen. Sie finden im GPOSTTL.SF.NET -Projekt, das ein POS -Tagging -Projekt ist, in der Dateidaten/contextualRuleFile.

Die Regeln sollten nach Abschluss der Statistikbewertung verwendet werden, sie machen eine Feinabstimmung und können die Genauigkeit bemerkenswert verbessern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top