15

मैं व्यक्तिगत शब्दों (यूटीएफ -8 में) में खमेर (कम्बोडियन भाषा) की लंबी लाइनों को विभाजित करने के लिए एक समाधान पर काम कर रहा हूं। खमेर शब्दों के बीच रिक्त स्थान का उपयोग नहीं करता है। वहाँ कुछ समाधान हैं, लेकिन वे पर्याप्त (here और here) से बहुत दूर हैं, और उन परियोजनाओं के रास्ते से गिर गया है।वर्ड स्प्लिटिंग खमेर के लिए एक व्यवहार्य समाधान?

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

यहाँ (वे इस से अधिक समय हो सकता है) को विभाजित करने की आवश्यकता है कि खमेर का एक नमूना रेखा है।

एक व्यवहार्य समाधान विभाजन कि खमेर शब्द बनाने के लक्ष्य के दोहरा है: यह जो लोग खमेर लीगेसी (गैर-यूनिकोड) फोंट का इस्तेमाल किया यूनिकोड (जो कई फायदे हैं) के लिए खत्म हो कन्वर्ट करने के लिए प्रोत्साहित करेंगे, और यह सक्षम हो जाएगा विरासत खमेर फोंट को यूनिकोड में आयात करने के लिए जल्दी से एक वर्तनी जांचकर्ता के साथ उपयोग किया जाना चाहिए (मैन्युअल रूप से जा रहा है और शब्दों को विभाजित करने के बजाय, एक बड़े दस्तावेज़ के साथ, बहुत लंबा समय ले सकता है)।

मुझे 100% सटीकता की आवश्यकता नहीं है, लेकिन गति महत्वपूर्ण है (विशेष रूप से जब रेखा को खमेर शब्दों में विभाजित करने की आवश्यकता है तो काफी लंबा हो सकता है)। मैं सुझावों के लिए खुला हूं, लेकिन वर्तमान में मेरे पास खमेर शब्दों का एक बड़ा हिस्सा है जो सही ढंग से विभाजित होते हैं (एक गैर-ब्रेकिंग स्पेस के साथ), और मैंने एक शब्दकोष शब्दकोश फ़ाइल (आवृत्ति.csv) को एक शब्दकोश के रूप में उपयोग करने के लिए बनाया है शब्द स्प्लिटर।

मुझे यह पायथन कोड here मिला जो Viterbi algorithm का उपयोग करता है और यह माना जाता है कि यह तेजी से चलता है। (मेरे शब्द संभावना शब्दकोश ... 100k से अधिक पद हैं क्योंकि) Text segmentation: dictionary-based word splitting लेकिन यह बहुत किसी भी उपयोग की जा करने के लिए धीमी गति से भाग गया:

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

मैं भी इस पेज के लेखक की ओर से स्रोत जावा कोड का उपयोग कर की कोशिश की।

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

मैं एक newbee हूँ जब यह अजगर की बात आती है और मैं वास्तव में सभी वास्तविक प्रोग्रामिंग करने के लिए नया हूँ (वेबसाइटों के बाहर), तो मेरे साथ सहन कृपया:

और यहाँ Detect most likely words from text without spaces/combined words से अजगर में एक और विकल्प है । क्या किसी के पास कोई विकल्प है जो उन्हें लगता है कि अच्छी तरह से काम करेगा?

उत्तर

3

आईसीयू लाइब्रेरी (जिसमें Python और जावा बाइंडिंग्स) DictionaryBasedBreakIterator कक्षा है जिसका उपयोग इस के लिए किया जा सकता है।

+0

@Lennart धन्यवाद - हां, मैंने आईसीयू लाइब्रेरी शब्दकोशबेसब्रेकइटरेटर वर्ग देखा है - लेकिन क्योंकि मैं प्रोग्रामिंग अनुभव में इतना सीमित हूं क्योंकि मैं इसके साथ कुछ भी करने में असमर्थ था। मुझे लगता है कि यहां कुछ उदाहरण दिए गए हैं: http://source.icu-project.org/repos/icu/icu/trunk/source/samples/break/ लेकिन क्या आप किसी भी पायथन और जावा उदाहरणों के बारे में जानते हैं जो मुझे शुरू कर देंगे (कभी-कभी पर्याप्त होने पर मैं एक स्क्रिप्ट संपादित कर सकता हूं)? या क्या वहां कुछ उदाहरण हैं जो मुझे याद आ रही हैं ... – Nathan

+0

@ नाथन: हाँ, आईसीयू पायथन बाइंडिंग में कोई वास्तविक दस्तावेज़ नहीं है, जो शर्म की बात है। नहीं, मुझे किसी भी उदाहरण के बारे में पता नहीं है, क्षमा करें। यदि आपके पास एक शब्दकोश है तो मैं कोशिश कर सकता हूं और देख सकता हूं कि मैं कुछ समझ सकता हूं या नहीं। –

+0

यहां आवृत्ति शब्दकोश है जो अब तक है। यह बहुत बड़ा नहीं है, लेकिन यह एक शुरुआत है: http://www.sbbic.org/Khmer-Corpus-Work.zip (मैंने खमेर में नमूना txt फ़ाइल भी शामिल की - सभी यूटीएफ -8 में) किसी भी तरह से आप इच्छुक होंगे मदद भयानक होगा। इसे देखने के लिए समय लेने के लिए धन्यवाद। – Nathan

1

उदाहरण filesaveas साथ अजगर पूरे इनपुट स्ट्रिंग (for i in xrange(1, len(text) + 1)) के माध्यम से recurse करने, रास्ते cache में सबसे अच्छा परिणाम भरने प्रकट होता है; प्रत्येक संभावित शब्द पर, यह तबअगले शब्द (जो बदले में उस शब्द को देखेगा, और इसी तरह) देखें, और यदि वह दूसरा शब्द बहुत अच्छा नहीं दिखता है, तो यह नहीं होगा उस विशेष को बचाओ। यह लगता है ओ (एन!) रनटाइम की तरह, जहां एन इनपुट स्ट्रिंग की लंबाई है।

सुपर चालाक, लेकिन शायद सरल कार्यों के अलावा कुछ भी भयानक है। आपके पास सबसे लंबा खमेर शब्द क्या है? मैं < 20 पात्रों की उम्मीद कर रहा हूं।

हो सकता है कि अगर आप उस उदाहरण में इनपुट को 20 अक्षरों में फ़ीड करते हैं तो आप रनटाइम को उचित पहुंचने के लिए नीचे रख सकते हैं।पहले 20 वर्णों में फ़ीड करें, पहले शब्द को चूसो, और फिर शेष इनपुट में फ़ीड करें। यदि आप कैश का दोबारा उपयोग करते हैं तो यह कुछ आंशिक रूप से स्टोर आंशिक शब्दों की तरह मूर्खतापूर्ण कर सकता है।

एक पूरी तरह से अलग पहलू पर, दो या दो से अधिक कानूनी खमेर शब्दों को जोड़कर कितने खमेर शब्द बनते हैं? ('पेननाइफ' या 'बास्केटबाल' के समान) यदि बहुत अधिक नहीं है, तो यह शब्दकोष का एक सेट बनाने, शब्द की लंबाई से अलग, शब्द से मैपिंग के उपयोग की संभावना के लिए समझ में आता है।

कहें, सबसे लंबा खमेर शब्द 14 वर्ण लंबा है; len14 शब्दकोश में इनपुट के 14 अक्षरों में फ़ीड करें, संभावना संग्रहित करें। 13 वर्णों में len13 में फ़ीड करें, संभावना संग्रहित करें। 12 अक्षरों में फ़ीड करें ... सभी तरह से नीचे len1 में। फिर उच्चतम संभावना के साथ व्याख्या चुनें, शब्द को सहेजें, कई पात्रों को हटा दें, और पुनः प्रयास करें।

तो यह "आई" बनाम "छवि" जैसे इनपुट के लिए बुरी तरह विफल नहीं होगा, हो सकता है कि लंबे इनपुट में स्वचालित रूप से संभावनाएं बढ़ी हों?

मजेदार प्रश्न के लिए धन्यवाद;) मुझे इस तरह की किसी भी भाषा, बहुत अच्छा नहीं पता था।

+0

आपके इनपुट के लिए धन्यवाद - हाँ खमेर में कुछ संक्षिप्त शब्द हैं, लेकिन अच्छी बात यह है कि हम उन्हें अधिकांश भाग के लिए अनदेखा कर सकते हैं (क्योंकि दोनों कानूनी हैं, और कोई दृश्यमान स्थान नहीं हैं)। मैंने यहां चबाने से कहीं अधिक काट दिया होगा, लेकिन यह जानना अच्छा है कि पाइथन उदाहरण पात्रों के समूह के साथ अच्छी तरह से काम नहीं करेगा - हालांकि एक समय में 20 वर्णों को संसाधित करना एक अच्छा विचार है ... – Nathan

1

मुझे लगता है कि यह एक अच्छा विचार है, जैसा कि है।

मैं आपको सुझाव देता हूं, जब आपके पास कुछ अनुभव होता है, तो आप कुछ नियम जोड़ सकते हैं, उदाहरण के लिए, शब्द के आधार पर, शब्द के आधार पर, आसपास के शब्दों के आधार पर, अनुक्रम के आधार पर, वर्तमान शब्द से पहले शब्द, बस सबसे अधिक बार गणना करने के लिए। आप फ़ाइल डेटा/contextualrulefile में gposttl.sf.net प्रोजेक्ट में नियमों का एक सेट पा सकते हैं, जो एक पॉज़ टैगिंग प्रोजेक्ट है।

नियमों का मूल्यांकन किया जाना चाहिए आंकड़े मूल्यांकन समाप्त होने के बाद, वे कुछ बढ़िया ट्यूनिंग करते हैं, और सटीकता में सुधार कर सकते हैं।

संबंधित मुद्दे