15

私は、クメール語(カンボジア語)の長い行を個々の単語(UTF-8)に分割するソリューションに取り組んでいます。クメール語は単語間にスペースを入れません。そこにはいくつかの解決策がありますが、それほど適切ではありません(hereおよびhere)。これらのプロジェクトは道端になっています。ここでクメール語を分割するための実行可能なソリューション

を分割する必要がクメールのサンプルライン(彼らはこれ以上長くすることができます)です。

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

クメール語を分割実行可能なソリューションを作成する目的は二つある:それは(多くの利点を持っている)Unicodeにオーバー変換するために、クメールレガシー(非Unicode)フォントを使用する人々を奨励し、それが有効になります従来のクメールフォントをユニコードにインポートしてスペルチェッカーですぐに使用できるようにしました(大量の文書を手作業でやりとりすることは非常に長い時間がかかります)。

私は100%正確さは必要ありませんが、速度は重要です(特に、クメール語に分割する必要がある行がかなり長くなる可能性があるため)。 私は提案はしていますが、現在は、正しく分割されているクメール語の大きなコーパスがあります(改行されていないスペースもあります)。また、辞書として使用する単語確率辞書ファイル(frequency.csv)を作成しました。単語スプリッター。

このpythonコードhereは、Viterbi algorithmを使用していて、おそらく速く実行されています。

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コードを使用してみました:(...私の言葉確率辞書は100K以上の用語を持っているので)Text segmentation: dictionary-based word splittingをが、それはどんな利用には遅すぎました。ここ

とはDetect most likely words from text without spaces/combined wordsから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に来るとき、私はnewbeeと私はすべての実プログラミング(ウェブサイトの外)には本当に新しいですので、私と一緒に負担してください。誰もがうまくいくと思うオプションはありますか?

答えて

3

ICUライブラリ(PythonとJavaバインディングを持つ)は、これに使用できるDictionaryBasedBreakIteratorクラスを持っています。

+0

@Lennartありがとうございます - ICUライブラリDictionaryBasedBreakIteratorクラスを見ましたが、プログラミングの経験が限られているため、何もできませんでした。ここにいくつかの例があります:http://source.icu-project.org/repos/icu/icu/trunk/source/samples/break/しかし、PythonとJavaの例を知っていますか?時には、十分なことがあればスクリプトを編集できます)?または、そこにいくつかの例があります。私は行方不明になっています。 – Nathan

+0

@Nathan:ICU Pythonバインディングには実際のドキュメントはありません。いいえ、私は例を知らない、申し訳ありません。あなたが辞書を持っているなら、私は何かを理解できるかどうか試してみることができます。 –

+0

ここまで私が持っている頻度辞書です。それは巨大ではありませんが、それはスタートです:http://www.sbbic.org/Khmer-Corpus-Work.zip(クメールのサンプルtxtファイルも含まれています - すべてUTF-8で)助けが素晴らしいだろう。それを調べる時間をとってくれてありがとう。 – Nathan

1

filesaveasのpythonは、入力文字列全体(for i in xrange(1, len(text) + 1))を繰り返して、最善の結果をcacheの途中に詰め込んでいるようです。すべての潜在的な単語でそれはの次の単語(それは、その後、その言葉を見て、など)を見て開始し、その2番目の単語が非常によく見えない場合、その特定のものを保存してください。 はO(N!)ランタイムのようなと感じます。ここでNは入力文字列の長さです。

非常に巧妙ですが、単純なタスク以外は恐ろしいでしょう。あなたが持っている最長のクメール語は何ですか?私は< 20文字を望んでいます。

一度に20文字ずつ入力すると、ランタイムを適切なものに近づけることができます。最初の20文字を入力し、最初の単語を吸い取り、残りの入力を入力します。キャッシュを再利用すると、途中で部分的な単語を保存するような愚かなことが起きる可能性があります。

全く異なるタックで、2つ以上の法的クメール語を連結していくつのクメール語句が形成されていますか? (「ペンナイフ」や「バスケットボール」に似ています)それほど多くない場合は、単語の長さで区切られた、単語から使用確率にマッピングされた一連の辞書を作成することが理にかなっています。

長いクメール語の長さは14文字です。 len14辞書に14文字の入力を入力し、その確率を保存します。 len13に13文字を入力し、その確率を保存します。 12文字でフィード... len1に1までのすべての方法。最も高い確率で解釈を選択し、単語を保存し、その多くの文字を取り除いてから、もう一度やり直してください。

"I"と "Image"のような入力では失敗しません。入力が長いほど、自動的に確率が高くなりますか?

楽しい質問ありがとうございました;)このような言語はわかりませんでした。

+0

あなたの意見をお寄せいただきありがとうございます。はい、クメール語にはいくつかの連結された言葉がありますが、良い点はほとんどの場合無視することができることです(両方とも正当で、表示されるスペースがないためです)。私はここで噛むこと以上に噛んでいるかもしれませんが、一度に20文字を処理することは良い考えですが、pythonの例が文字の束とうまくいかないことを知っていることは良いことです... – Nathan

1

これはいい考えです。

私はあなたにいくつかの経験があるときには、いくつかのルールを追加することをお勧めします。たとえば、前後の単語に応じて、前後の単語に応じて、現在の単語の前の単語、最も頻繁な単語を列挙する。 posタグ付けプロジェクトであるgposttl.sf.netプロジェクトでは、data/contextualrulefileファイルにルールのセットがあります。

統計評価が終了した後、ルールを使用して微調整を行い、精度を大幅に向上させることができます。

関連する問題