2012-08-13 36 views
5

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

> word5 <- "hotter the doghou se would be bec ause the co lor was diffe rent" 
> abc1 <- data.frame(filler1 = 1,words1=factor(unlist(strsplit(word5, split=" ")))) 
> abc1 
    filler1 words1 
1  1 hotter 
2  1 the 
3  1 doghou 
4  1  se 
5  1 would 
6  1  be 
7  1 bec 
8  1 ause 
9  1 the 
10  1  co 
11  1 lor 
12  1 was 
13  1 diffe 
14  1 rent 

अगला मैं निम्नलिखित कोड का उपयोग कोशिश करते हैं और जाँच करें और शब्द है कि पहले या बाद में शब्द का संयोजन कर रहे हैं गठबंधन वर्तनी:

मैं एक वाक्य है कि मैं शब्दों का एक डेटा फ्रेम में बदलने के साथ शुरू उन्हें:

abc2 <- abc1 
i <- 1 
while(i < nrow(abc1)){ 
    print(abc2) 
    if(nrow(aspell(abc1$words1[i])) == 0){ 
    print(paste(i,"Words OK",sep=" | "));flush.console() 
    i <- i + 1 
    } 
else{ 
    if(nrow(aspell(abc1$words1[i])) > 0 & i != 1){ 
    preWord1 <- abc1$words1[i-1] 
    postWord1 <- abc1$words1[i+1] 
    badWord1 <- abc1$words1[i] 
    newWord1 <- factor(paste(preWord1,badWord1,sep="")) 
    newWord2 <- factor(paste(badWord1,postWord1,sep="")) 

    if(nrow(aspell(newWord1)) == 0 & nrow(aspell(newWord2)) != 0){ 
     abc2[i,"words1"] <-as.character(newWord1) 
     abc2 <- abc2[-c(i+1),] 
     print(paste(i,"word1",sep=" | "));flush.console() 
     i <- i + 1 
    } 

    if(nrow(aspell(newWord1)) != 0 & nrow(aspell(newWord2)) == 0){ 
     abc2[i ,"words1"] <-as.character(newWord2) 
     abc2 <- abc2[-c(i-1),] 
     print(paste(i,"word2",sep=" | "));flush.console() 
     i <- i + 1 
    } 

    } 
} 
} 

कुछ समय मैं निष्कर्ष है कि मैं iterator किसी प्रकार की जरूरत है, लेकिन कैसे आर में इसे लागू करने कोई सुझाव के अनिश्चित हूँ करने के लिए आ रहा हूँ के लिए इस के साथ खेलने के बाद?

+0

यह कैसे काम नहीं करता है तो आप हमें बता सकते हैं? मुझे लगता है कि आप शायद बेवकूफ, या लापरवाही कार्यों की तलाश में हैं। यदि आप अपना स्वयं का फ़ंक्शन परिभाषित करते हैं और फिर 'lapply (abc1 $ words1, yourFunctionNameHere)' करते हैं तो यह 'adc1 $ words1' के प्रत्येक तत्व पर लूप होगा और पैरामीटर के रूप में पारित उस तत्व के साथ अपना फ़ंक्शन कॉल करेगा। यदि फ़ंक्शन को पास करने के लिए अन्य पैरामीटर हैं तो आप फ़ंक्शन नाम –

उत्तर

10

नोट: मैं काफी अलग और बेहतर समाधान के साथ आया क्योंकि यह पिछले समाधान के सभी डाउनसाइड्स को सताता है। लेकिन मैं अभी भी पुराने समाधान को रखना चाहता हूं। इसलिए, मैंने इसे एक नए उत्तर के रूप में जोड़ा, कृपया मुझे सही करें अगर मैं ऐसा करने में गलत हूं।

इस दृष्टिकोण में मैं डेटासेट को थोड़ा सा सुधारता हूं। आधार वह है जिसे मैं वर्डपेयर ऑब्जेक्ट कहता हूं।उदाहरण के लिए:

> word5 
[1] "hotter the doghou se would be bec ause the col or was diffe rent" 

लगेगा जैसे:

> abc1_pairs 
    word1 word2 
1 hotter the 
2  the doghou 
3 doghou  se 
4  se would 
5 would  be 
6  be bec 
7  bec ause 
8 ause the 
9  the col 
10 col  or 
11  or was 
12 was diffe 
13 diffe rent 

अगला हम wordpairs से अधिक पुनरावृति और अगर वे वैध शब्द खुद को कर रहे हैं, रिकर्सिवली कोई वैध नए शब्दों पाए जाते हैं जब तक यह कर (ध्यान दें कि एक

# Recursively delete wordpairs which lead to a correct word 
merge_wordpairs = function(wordpairs) { 
    require(plyr) 
    merged_pairs = as.character(mlply(wordpairs, merge_word)) 
    correct_words_idxs = which(sapply(merged_pairs, word_correct)) 
    if(length(correct_words_idxs) == 0) { 
    return(wordpairs) 
    } else { 
    message(sprintf("Number of words about to be merged in this pass: %s", length(correct_words_idxs))) 
    for(idx in correct_words_idxs) { 
     wordpairs = merge_specific_pair(wordpairs, idx, delete_pair = FALSE) 
    } 
    return(merge_wordpairs(wordpairs[-correct_words_idxs,])) # recursive call 
    } 
} 

उदाहरण डाटासेट इस में परिणाम होगा लागू: कुछ अतिरिक्त कार्य इस पोस्ट के नीचे) पर सूचीबद्ध होते हैं

> word5 <- "hotter the doghou se would be bec ause the col or was diffe rent" 
> abc1 = strsplit(word5, split = " ")[[1]] 
> abc1_pairs = wordlist2wordpairs(abc1) 
> abc1_pairs 
    word1 word2 
1 hotter the 
2  the doghou 
3 doghou  se 
4  se would 
5 would  be 
6  be bec 
7  bec ause 
8 ause the 
9  the col 
10 col  or 
11  or was 
12 was diffe 
13 diffe rent 
> abc1_merged_pairs = merge_wordpairs(abc1_pairs) 
Number of words about to be merged in this pass: 4 
> merged_sentence = paste(wordpairs2wordlist(abc1_merged_pairs), collapse = " ") 
> c(word5, merged_sentence) 
[1] "hotter the doghou se would be bec ause the col or was diffe rent" 
[2] "hotter the doghouse would be because the color was different"  

अतिरिक्त कार्यों की जरूरत:

# A bunch of functions 
# Data transformation 
wordlist2wordpairs = function(word_list) { 
    require(plyr) 
    wordpairs = ldply(seq_len(length(word_list) - 1), 
        function(idx) 
         return(c(word_list[idx], 
           word_list[idx+1]))) 
    names(wordpairs) = c("word1", "word2") 
    return(wordpairs) 
} 
wordpairs2wordlist = function(wordpairs) { 
    return(c(wordpairs[[1]], wordpairs[[2]][nrow(wordpairs)])) 
} 

# Some checking functions 
# Is the word correct? 
word_correct = function(word) return(nrow(aspell(factor(word))) == 0) 
# Merge two words 
merge_word = function(word1, word2) return(paste(word1, word2, sep = "")) 

# Merge a specific pair, option to postpone deletion of pair 
merge_specific_pair = function(wordpairs, idx, delete_pair = TRUE) { 
    # merge pair into word 
    merged_word = do.call("merge_word", wordpairs[idx,]) 
    # assign the pair to the idx above 
    if(!(idx == 1)) wordpairs[idx - 1, "word2"] = merged_word 
    if(!(idx == nrow(wordpairs))) wordpairs[idx + 1, "word1"] = merged_word 
    # assign the pair to the index below (if not last one) 
    if(delete_pair) wordpairs = wordpairs[-idx,] 
    return(wordpairs) 
} 
+0

@screechOwl, यह समाधान आपके डेटासेट पर कैसे किया गया? क्या गति स्वीकार्य थी? कोई अतिरिक्त बग? –

3

आप क्या कर सकते हैं रिकर्सन का उपयोग करना है। नीचे दिया गया कोड आपके उदाहरण का थोड़ा संशोधित संस्करण लेता है। यह जांचता है कि क्या सभी शब्द सही हैं, यदि ऐसा है तो शब्दों की सूची लौटा दी गई है। यदि नहीं, तो यह शब्द को पिछले शब्द के साथ, और इसके बाद के शब्द के साथ जोड़ना चाहता है। यदि पिछले शब्द का विलय सही था, तो यह एक विलय की ओर जाता है जो paste(word_before, word, word_after) जैसा दिखता है। विलय के प्रयास के बाद, शब्दों को मर्ज करने के लिए फ़ंक्शन को नई शब्द सूची पर बुलाया जाता है। यह रिकर्सन तब तक जारी रहता है जब तक कोई गलत शब्द न छोड़े।

word5 <- "hotter the doghou se would be bec ause the col or was diffe rent" 
abc1 = strsplit(word5, split = " ")[[1]] 
combine_words(abc1) 
Current sentence: hotter the doghou se would be bec ause the col or was diffe rent 
Current sentence: hotter the doghouse would be bec ause the col or was diffe rent 
Current sentence: hotter the doghouse would be because the col or was diffe rent 
Current sentence: hotter the doghouse would be because the col or was different 

कुछ मुद्दों:

# Wrap the spell checking in a function, makes your code much more readable 
word_correct = function(word) return(nrow(aspell(factor(word))) == 0) 
# Merge two words 
merge_word = function(word1, word2) return(paste(word1, word2, sep = "")) 
# Merge two words and replace in list 
merge_words_in_list = function(word_list, idx1, idx2) { 
    word_list[idx1] = merge_word(word_list[idx1], word_list[idx2]) 
    return(word_list[-idx2]) 
} 
# Function that recursively combines words 
combine_words = function(word_list) { 
    message("Current sentence: ", paste(word_list, collapse = " ")) 
    words_ok = sapply(word_list, word_correct) 
    if(all(words_ok)) { 
    return(word_list) 
    } else { 
    first_wrong_word = which(!words_ok)[1] 
    combination_before = merge_word(word_list[first_wrong_word], 
            word_list[first_wrong_word-1]) 
    if(word_correct(combination_before)) { 
     word_list = merge_words_in_list(word_list, first_wrong_word-1, 
             first_wrong_word) 
    } 
    combination_after = merge_word(word_list[first_wrong_word], 
            word_list[first_wrong_word+1]) 
    if(word_correct(combination_after)) { 
     word_list = merge_words_in_list(word_list, first_wrong_word, 
             first_wrong_word+1) 
    } 
    return(combine_words(word_list)) # Recursive call 
    } 
} 

(एक थोड़ा संशोधित) अपने वाक्य का संस्करण के लिए काम करता है के इस सेट को लागू करने

  • अभी भी समस्या यह है कि अगर दोनों combination_before और combination_after गैर मान्य हैं, कार्यक्रम अनंत रिकर्सन में गिर जाता है। कार्यक्रम केवल तब बंद हो जाता है जब सभी शब्द मान्य होते हैं।
  • क्या होगा यदि दोनों पिछले शब्द के साथ विलय करते हैं, और अगला शब्द मान्य है, तो हमें क्या करना चाहिए?
  • कोड केवल गलत शब्दों को विलीन करता है, उदा। 'col' और 'या' aspell द्वारा अच्छे शब्दों का निर्णय लिया जाता है जबकि आप विलय करना चाहते हैं। इससे एक नई चुनौती होती है: इस मामले में विलय स्पष्ट है, लेकिन बड़े डेटासेट में यह स्पष्ट नहीं हो सकता है कि अपने आप में, सही शब्दों का एक समूह कैसे जोड़ना है।

लेकिन फिर भी, मुझे लगता है कि यह उदाहरण अच्छी तरह से एक पुनरावर्ती दृष्टिकोण को दर्शाता है।

+0

के बाद उनको पास कर सकते हैं यह बहुत अच्छा है! आपका बहुत बहुत धन्यवाद। मुद्दे सभी जीवित हैं। डेटा बहुत खराब है इसलिए परिदृश्य छोड़ना जहां संयुक्त शब्द काम नहीं करते/सही काम करते हैं, सही दिशा में एक बड़ा कदम है। – screechOwl

+0

मैंने एक नया उत्तर जोड़ा जिसमें इस समाधान के डाउनसाइड्स में से कोई भी नहीं है, और मुझे लगता है कि इसे तेज़ होना चाहिए। –