2013-10-30 7 views
13

मैंने किसी दस्तावेज़ से वाक्यों की सूची निकाली है। मैं इसे अधिक समझदार बनाने के लिए वाक्यों की इस सूची को पूर्व-प्रसंस्करण कर रहा हूं। मैं निम्नलिखित समस्याएक शब्दकोश का उपयोग कर रिक्त स्थान के साथ फिक्सिंग शब्द पायथन में दिखते हैं?

मैं ऐसे "more recen t ly the develop ment, wh ich is a po ten t "

के रूप में वाक्य है मैं एक को देखने के शब्दकोश का उपयोग कर इस तरह के वाक्य को सही करने के लिए चाहते हैं के साथ सामना कर रहा हूँ? अवांछित रिक्त स्थान को हटाने के लिए।

अंतिम आउटपुट होना चाहिए "more recently the development, which is a potent "

मुझे लगता है कि यह पूर्व प्रसंस्करण पाठ में एक सीधे आगे काम नहीं है? मुझे ऐसे दृष्टिकोण देखने के लिए कुछ पॉइंटर्स के साथ मदद चाहिए। धन्यवाद।

उत्तर

5

शब्द या टेक्स्ट segmentation पर एक नज़र डालें। समस्या शब्दों के एक समूह में एक स्ट्रिंग के सबसे संभावित विभाजन को खोजने के लिए है। उदाहरण:

thequickbrownfoxjumpsoverthelazydog 

सबसे संभावित विभाजन निश्चित रूप से होना चाहिए:

:

the quick brown fox jumps over the lazy dog 

यहाँ Google Ngram कोष का उपयोग कर समस्या के लिए प्रोटोटाइप स्रोत कोड सहित एक लेख है

के लिए कुंजी काम करने के लिए यह एल्गोरिदम दुनिया के बारे में ज्ञान तक पहुंच है, इस मामले में कुछ भाषा में शब्द आवृत्तियों।

उदाहरण उपयोग:: मैं एल्गोरिथ्म लेख यहाँ में वर्णित का एक संस्करण कार्यान्वित

$ python segmentation.py t hequi ckbrownfoxjum ped 
thequickbrownfoxjumped 
['the', 'quick', 'brown', 'fox', 'jumped'] 

डेटा का उपयोग करना, यहां तक ​​कि इस पुनर्क्रमित जा सकता है:

$ python segmentation.py lmaoro fll olwt f pwned 
lmaorofllolwtfpwned 
['lmao', 'rofl', 'lol', 'wtf', 'pwned'] 

ध्यान दें कि एल्गोरिदम काफी धीमा है - यह प्रोटोटाइपिका है एल।

एक और दृष्टिकोण NLTK का उपयोग कर:

आपकी समस्या का सवाल है, तो आप सिर्फ सभी स्ट्रिंग भागों आप एक ही स्ट्रिंग और चलाने उस पर एक विभाजन एल्गोरिथ्म प्राप्त करने के लिए जोड़ सकता है।

+3

लेकिन यह एक से अधिक क्रम में वाक्य व्यवस्थित किए जाने पर कैसे काम करता है? "पेन माइग htier था एन एन ord" – DhruvPathak

+1

सुरुचिपूर्ण दृष्टिकोण, लेकिन सभी रिक्त स्थान को छोड़कर इसे एक कठिन समस्या में बदल जाता है। ओपीएस विवरण ("अवांछित रिक्त स्थान हटाएं") बताता है कि रिक्त स्थान कभी गायब नहीं होते हैं; यदि यह सही है, तो आपको शब्द ब्रेक के लिए कभी भी एक टुकड़े के अंदर नहीं दिखना चाहिए। – alexis

+1

@alexis, आप सही हैं, मुझे लगता है कि कम से कम सभी विभाजनों के बजाय विभिन्न जोड़ों की संभावनाओं की गणना करके प्रदर्शन को कम से कम क्रम में सुधार किया जा सकता है। मैं शायद बाद में अपने जवाब को सुधारने के लिए वापस आऊंगा। – miku

2

यहाँ वास्तव में कुछ बुनियादी है:

chunks = [] 
for chunk in my_str.split(): 
    chunks.append(chunk) 
    joined = ''.join(chunks) 
    if is_word(joined): 
     print joined, 
     del chunks[:] 

# deal with left overs 
if chunks: 
    print ''.join(chunks) 

मुझे लगता है तुम कहीं वैध शब्द है कि is_word लागू करने के लिए इस्तेमाल किया जा सकता का एक सेट है। आपको यह भी सुनिश्चित करना होगा कि यह विराम चिह्न से संबंधित है।यहाँ एक तरह से करना है कि:

def is_word(wd): 
    if not wd: 
     return False 
    # Strip of trailing punctuation. There might be stuff in front 
    # that you want to strip too, such as open parentheses; this is 
    # just to give the idea, not a complete solution. 
    if wd[-1] in ',.!?;:': 
     wd = wd[:-1] 
    return wd in valid_words 
3

- समाधान 1:

एक एबेकस पर मोती के रूप में अपने वाक्य में इन टुकड़ों का थिंक चलें, प्रत्येक एक आंशिक स्ट्रिंग से मिलकर मनका, मोती के साथ क्रमपरिवर्तन उत्पन्न करने के लिए बाएं या दाएं स्थानांतरित किया जा सकता है। प्रत्येक टुकड़े की स्थिति दो आसन्न टुकड़ों के बीच तय की जाती है। वर्तमान मामले में, मोती होगा:

क) मनके एक इकाई है, इसलिए हम "अधिक" के मनका यानी क्रमपरिवर्तन भीतर क्रमपरिवर्तन के बारे में परवाह नहीं है:

(more)(recen)(t)(ly)(the)(develop)(ment,)(wh)(ich)(is)(a)(po)(ten)(t) 

2 subproblems हल करती है संभव नहीं है

बी) मोतियों का क्रम स्थिर है, केवल उनके बीच अंतर बदलता है। यानी "अधिक" हमेशा "रिकेन" से पहले होगा और इसी तरह। कैसे अपने प्रासंगिक शब्दकोश से कई शब्दों के वे होते हैं, सबसे सही परिणाम आसानी से फ़िल्टर किया जा सकता के आधार पर फिर इन क्रमपरिवर्तन स्कोर

morerecentlythedevelopment,which is a potent 
morerecentlythedevelopment,which is a poten t 
morerecentlythedevelop ment, wh ich is a po tent 
morerecentlythedevelop ment, wh ich is a po ten t 
morerecentlythe development,whichisapotent 

:

अब, इन मोती, जो की तरह उत्पादन दे देंगे के सभी क्रमपरिवर्तन उत्पन्न बाहर। more recently the development, which is a potent स्कोर से अधिक morerecentlythedevelop ment, wh ich is a po ten t

कोड जो मोती की क्रमचय हिस्सा है:

import re 

def gen_abacus_perms(frags): 
    if len(frags) == 0: 
     return [] 
    if len(frags) == 1: 
     return [frags[0]] 

    prefix_1 = "{0}{1}".format(frags[0],frags[1]) 
    prefix_2 = "{0} {1}".format(frags[0],frags[1]) 
    if len(frags) == 2: 
     nres = [prefix_1,prefix_2] 
     return nres 

    rem_perms = gen_abacus_perms(frags[2:]) 
    res = ["{0}{1}".format(prefix_1, x) for x in rem_perms] + ["{0} {1}".format(prefix_1, x) for x in rem_perms] + \ 
["{0}{1}".format(prefix_2, x) for x in rem_perms] + ["{0} {1}".format(prefix_2 , x) for x in rem_perms] 
    return res 



broken = "more recen t ly the develop ment, wh ich is a po ten t" 
frags = re.split("\s+",broken) 
perms = gen_abacus_perms(frags) 
print("\n".join(perms)) 

डेमो: http://ideone.com/pt4PSt


- समाधान # 2 :

मैं एक वैकल्पिक दृष्टिकोण का सुझाव दूंगा जो पहले से ही समस्याओं पर काम कर रहे लोगों द्वारा विकसित टेक्स्ट विश्लेषण खुफिया का उपयोग करता है और डेटा के बड़े कॉर्पस पर काम करता है जो शब्दकोश और व्याकरण पर निर्भर करता है। खोज यन्त्र।

मुझे ऐसे सार्वजनिक/भुगतान एपिस के बारे में अच्छी जानकारी नहीं है, इसलिए मेरा उदाहरण Google परिणामों पर आधारित है।

  1. आप एक से अधिक गुजरता के लिए, Google को आपकी अमान्य शर्तों डाल रख सकते हैं, और कुछ अपने देखने शब्दकोश के आधार पर स्कोर के लिए परिणामों का मूल्यांकन रखें:

    गूगल इस्तेमाल करने की कोशिश करते हैं।

enter image description here

यह outout एक दूसरे पारित करने के लिए प्रयोग किया जाता है: यहाँ अपने पाठ का 2 गुजरता का उपयोग करके दो प्रासंगिक outputs हैं

enter image description here

जो तुम "के रूप में रूपांतरण देता है "हाल ही में विकास, जो एक शक्तिशाली है"।

रूपांतरण सत्यापित करने के लिए, आपको कुछ समानता एल्गोरिदम का उपयोग करना होगा और अमान्य/न तो अच्छे नतीजे फ़िल्टर करने के लिए स्कोरिंग करना होगा।

एक कच्ची तकनीक difflib का उपयोग कर सामान्यीकृत तारों की तुलना का उपयोग कर सकती है।

>>> import difflib 
>>> import re 
>>> input = "more recen t ly the develop ment, wh ich is a po ten t " 
>>> output = "more recently the development, which is a potent " 
>>> input_norm = re.sub(r'\W+', '', input).lower() 
>>> output_norm = re.sub(r'\W+', '', output).lower() 
>>> input_norm 
'morerecentlythedevelopmentwhichisapotent' 
>>> output_norm 
'morerecentlythedevelopmentwhichisapotent' 
>>> difflib.SequenceMatcher(None,input_norm,output_norm).ratio() 
1.0 
+1

बाधाएं अधिकतम 100 प्रश्नों को मुफ्त Google api =) – alvas

4

आपका लक्ष्य पाठ को बेहतर बनाना है, इसे सही बनाने के लिए जरूरी नहीं है; तो आपके दृष्टिकोण की रूपरेखा मेरी राय में समझ में आता है। मैं इसे सरल रखूंगा और "लालची" दृष्टिकोण का उपयोग करूंगा: पहले खंड के साथ शुरू करें और जब तक परिणाम डिक्शनरी में न हो तब तक चिपके रहें; यदि परिणाम नहीं है, तो अब तक जो कुछ भी है, उसे थूकें और अगले खंड के साथ शुरू करें। हां, कभी-कभी आप the me thod जैसे मामलों के साथ गलती करेंगे, इसलिए यदि आप इसका बहुत उपयोग करेंगे, तो आप कुछ और परिष्कृत खोज सकते हैं। हालांकि, यह शायद काफी अच्छा है।

मुख्य रूप से आपको जो चाहिए वह एक बड़ा शब्दकोश है। यदि आप इसका बहुत उपयोग करेंगे, तो मैं इसे "उपसर्ग पेड़" (ए.के.ए. trie) के रूप में एन्कोड करता हूं, ताकि आप तुरंत पता लगा सकें कि एक खंड वास्तविक शब्द की शुरुआत है या नहीं। एनएलटीके Trie implementation.

चूंकि इस तरह के नकली शब्द ब्रेक असंगत हैं, इसलिए मैं वर्तमान शब्द में पहले से संसाधित शब्दों के साथ अपना शब्दकोश भी बढ़ाऊंगा; आपने पहले पूरा शब्द देखा होगा, लेकिन अब यह टूट गया है।

+0

पर भेज सकती हैं, एक ट्राई यहां एक अच्छा समाधान होगा क्योंकि आप यह जांच सकते हैं कि 'रिक' के बाद 't' बच्चे नोड्स में से किसी एक में उपयोग किया जाता है (वास्तव में, यह है) और इसलिए, आप "रिक्त स्थान" और "संभावित शब्द ढूंढें" एल्गोरिदम विलय कर सकते हैं। –

3

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

dict = open("dictionary.txt",'r')        #loads a file with a list of words to break string up into 
words = raw_input("enter text to correct spaces on: ") 
words = words.strip()           #strips away spaces 
spaced = []              #this is the list of newly broken up words 
parsing = True             #this represents when the while loop can end 
while parsing: 
    if len(words) == 0:           #checks if all of the text has been broken into words, if it has been it will end the while loop 
     parsing = False 
    iterating = True 
    for iteration in range(45):         #goes through each of the possible word lengths, starting from the biggest 
     if iterating == False: 
      break 
     word = words[:45-iteration]        #each iteration, the word has one letter removed from the back, starting with the longest possible number of letters, 45 
     for line in dict: 
      line = line[:-1]          #this deletes the last character of the dictionary word, which will be a newline. delete this line of code if it is not a newline, or change it to [1:] if the newline character is at the beginning 
      if line == word:          #this finds if this is the word we are looking for 
       spaced.append(word) 
       words = words[-(len(word)):]      #takes away the word from the text list 
       iterating = False 
       break 
print ' '.join(spaced)           #prints the output 

आप इसे और भी अधिक सटीक होना चाहते हैं, तो आप एक प्राकृतिक भाषा पार्स प्रोग्राम का उपयोग की कोशिश कर सकते: यहाँ एक उदाहरण कच्चे इनपुट का उपयोग करता है पाठ में लेने के लिए सही करने के लिए और एक शब्दकोश फ़ाइल कहा जाता Dictionary.txt है , पाइथन मुफ्त ऑनलाइन के लिए कई उपलब्ध हैं।

2

आप सर्वोत्तम फिट खोजने के लिए शब्दों के शब्दकोश के माध्यम से फिर से शुरू कर सकते हैं। जब कोई मिलान नहीं मिलता है तो शब्दों को एक साथ जोड़ना।

def iterate(word,dictionary): 
    for word in dictionary: 
     if words in possibleWord: 
     finished_sentence.append(words) 
     added = True 
     else: 
     added = False 
     return [added,finished_sentence] 
sentence = "more recen t ly the develop ment, wh ich is a po ten t " 
finished_sentence = "" 
sentence = sentence.split() 
for word in sentence: 
    added,new_word = interate(word,dictionary) 
    while True: 
    if added == False: 
     word += possible[sentence.find(possibleWord)] 
     iterate(word,dictionary) 
    else: 
     break 
    finished_sentence.append(word) 

यह काम करना चाहिए। परिवर्तनीय dictionary के लिए, प्रत्येक एकल अंग्रेजी शब्द का एक txt file डाउनलोड करें, फिर इसे अपने प्रोग्राम में खोलें।

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