Sto lavorando a una soluzione per dividere le lunghe righe di Khmer (la lingua cambogiana) in singole parole (in UTF-8). Khmer non usa spazi tra le parole. Ci sono alcune soluzioni là fuori, ma sono tutt'altro che adeguate (here e here), e quei progetti sono caduti nel dimenticatoio.Una soluzione praticabile per la divisione di Khmer in Word?
Ecco una linea campione di Khmer che ha bisogno di essere diviso (possono essere più lungo di questo):
ចូរ សរសើរ ដល់ ទ្រង់ ដែល ទ្រង់ បាន ប្រទាន ការ ទាំងអស់ នោះ មកដល់ រូប អ្នក ដោយ ព្រោះ អង្គ ព្រះយេស៊ូវ ហើយ ដែល អ្នក មិនអាច រក ការ ទាំងអស់ នោះ ដោយសារ ការប្រព្រឹត្ត របស់ អ្នក ឡើយ.
L'obiettivo di creare una soluzione praticabile che divide le parole Khmer è duplice: essa incoraggerà quelli che hanno utilizzato legacy font Khmer (non Unicode) per la conversione verso Unicode (che ha molti benefici), e consentirà i font khmer legacy da importare in Unicode per essere utilizzati rapidamente con un correttore ortografico (piuttosto che passare manualmente e suddividere le parole che, con un documento di grandi dimensioni, può impiegare molto tempo).
Non ho bisogno di precisione al 100%, ma la velocità è importante (soprattutto perché la riga che deve essere divisa in parole Khmer può essere piuttosto lunga). Sono aperto a suggerimenti, ma attualmente ho un grande corpus di parole khmer che sono correttamente suddivise (con uno spazio non interrotto), e ho creato un file di dizionario di probabilità parola (frequency.csv) da usare come dizionario per la parola splitter.
Ho trovato questo codice python here che utilizza il Viterbi algorithm e che presumibilmente funziona veloce.
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()))
Ho anche provato ad utilizzare il codice sorgente Java da parte dell'autore di questa pagina: Text segmentation: dictionary-based word splitting ma corse troppo lento per essere di qualche utilità (perché il mio dizionario probabilità parola ha più di 100k termini ...).
E qui è un'altra opzione in python da Detect most likely words from text without spaces/combined words:
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'])
Io sono un newbee quando si tratta di pitone e sono davvero nuovo a tutto reale di programmazione (al di fuori di siti web), quindi per favore abbiate pazienza con me . Qualcuno ha qualche opzione che ritengono funzionerebbe bene?
@Lennart Grazie - Sì, ho visto la libreria ICU DictionaryBasedBreakIterator - ma poiché sono così limitato nell'esperienza di programmazione non sono riuscito a fare nulla con esso. Vedo che ci sono alcuni esempi qui: http://source.icu-project.org/repos/icu/icu/trunk/source/samples/break/ ma conosci qualche esempio di Python e Java che potrebbe farmi iniziare (A volte posso modificare uno script se ne è stato fatto abbastanza)? O ci sono alcuni esempi che mi mancano ... – Nathan
@Nathan: Sì, i binding Python ICU non hanno documenti veri, il che è un peccato. No, non conosco esempi, mi dispiace. Se hai un dizionario, potrei provare a vedere se riesco a capire qualcosa. –
Ecco il dizionario di frequenza che ho finora. Non è enorme, ma è un inizio: http://www.sbbic.org/Khmer-Corpus-Work.zip (Ho anche incluso un esempio di file txt in Khmer - tutto in UTF-8) In qualunque modo tu sia disposto a l'aiuto sarebbe fantastico. Grazie per aver dedicato del tempo per esaminarlo. – Nathan