2015-10-13 5 views
9

मैं एक ही समय में कई दस्तावेज़ों में होने वाले शब्दों को खोजने का प्रयास कर रहा हूं।उसी तरह से स्थान से अलग शब्दों का इलाज करें

हमें एक उदाहरण लें।

doc1: "this is a document about milkyway" 
doc2: "milky way is huge" 

आप 2 दस्तावेजों ऊपर में देख सकते हैं, शब्द "Milkyway" दोनों डॉक्स में हो रहा है लेकिन दूसरे दस्तावेज़ शब्द "Milkyway" में ऐसा नहीं है एक रिक्ति से और पहले दस्तावेज़ में अलग है।

मैं आर

में
library(tm) 
tmp.text <- data.frame(rbind(doc1, doc2)) 
tmp.corpus <- Corpus(DataframeSource(tmp.text)) 
tmpDTM <- TermDocumentMatrix(tmp.corpus, control = list(tolower = T, removeNumbers = T, removePunctuation = TRUE,stopwords = TRUE,wordLengths = c(2, Inf))) 
tmp.df <- as.data.frame(as.matrix(tmpDTM)) 
tmp.df 

     1 2 
document 1 0 
huge  0 1 
milky 0 1 
milkyway 1 0 
way  0 1 

टर्म milkyway दस्तावेज़ अवधि मैट्रिक्स प्राप्त करने के लिए निम्नलिखित कर रहा हूँ ऊपर मैट्रिक्स के अनुसार पहले दस्तावेज़ में ही मौजूद है।

मैं उपर्युक्त मैट्रिक्स में "मिल्कीवे" शब्द के लिए दोनों दस्तावेज़ों में 1 प्राप्त करने में सक्षम होना चाहता हूं। यह सिर्फ एक उदाहरण है। मुझे बहुत सारे दस्तावेजों के लिए ऐसा करने की ज़रूरत है। आखिरकार मैं इस तरह के शब्दों ("मिल्कीवे" & "दूधिया रास्ता") का इलाज करने में सक्षम होना चाहता हूं।

संपादित करें 1:

मैं अवधि दस्तावेज़ मैट्रिक्स इस तरह से है कि जो कुछ भी शब्द के लिए यह देखने के लिए सिर्फ एक के रूप में उस शब्द के लिए नहीं देखना चाहिए कोशिश कर रहा है में गणना करने के लिए मजबूर नहीं किया जा सकता स्ट्रिंग में अलग शब्द लेकिन तारों के भीतर भी? उदाहरण के लिए, एक शब्द milky है और एक दस्तावेज़ this is milkyway है इसलिए वर्तमान में milky इस दस्तावेज़ में नहीं होता है, लेकिन यदि एल्गोरिदम स्ट्रिंग के भीतर प्रश्न में शब्द को देखता है तो यह milky शब्द milkyway के भीतर भी मिलेगा, इस तरह शब्द milky और way मेरे दोनों दस्तावेज़ों (पहले उदाहरण) में गिना जाएगा।

संपादित करें 2:

अंत में मैं दस्तावेजों के बीच समानता कोज्या सूचकांक गणना करने में सक्षम होना चाहता हूँ।

+0

शायद रिक्त स्थान हटाएं फिर regex का उपयोग करें? – zx8754

+0

क्या आपको केवल 'दूधिया तरीके' या दूसरों के लिए ऐसा करने की ज़रूरत है? क्या आप पसंद करते हैं कि वे दोनों 'मिलकीवे' हों? –

+0

@ सेबेस्टियन-सी मुझे इसे कई शब्दों के लिए करने की ज़रूरत है। मैं दोनों तरह से "मिल्कवे" बनना पसंद करता हूं। "रोज़ाना" और "हर दिन" जैसे मामले हो सकते हैं। इस मामले में मैं उन्हें "रोज़ाना" बनना पसंद करूंगा। – user3664020

उत्तर

0

आप "\\ s?" डालने से शब्दों के हर संभव विभाजन के लिए मिलान करने के लिए रेगेक्स का उपयोग कर सकते हैं। आपके खोज शब्दों में प्रत्येक चरित्र के बीच। यदि आप केवल विशिष्ट विभाजन चाहते हैं, तो आप इसे केवल उन स्थानों पर डालें। निम्न कोड "\\ s?" डालने से खोज शब्दों के लिए रेगेक्स पैटर्न उत्पन्न करता है हर चरित्र के बीच। grep सूचकांक देता है जहां पैटर्न मिलान करता है, लेकिन अन्य regex कार्यों के लिए आदान-प्रदान किया जा सकता है।

docs <- c("this is a document about milkyway", "milky way is huge") 
search_terms <- c("milkyway", "document") 
pattern_fix <- sapply(strsplit(search_terms, split = NULL), paste0, collapse = "\\s?") 
sapply(pattern_fix, grep, docs) 

$`m\\s?i\\s?l\\s?k\\s?y\\s?w\\s?a\\s?y` 
[1] 1 2 

$`d\\s?o\\s?c\\s?u\\s?m\\s?e\\s?n\\s?t` 
[1] 1 

संपादित करें:

सभी शब्द खोजने के लिए, तुम सिर्फ tmp.df के नाम अपनी स्क्रिप्ट में मेरे समाधान में से SEARCH_TERMS के रूप में इस्तेमाल कर सकते हैं।

doc1 <- "this is a document about milkyway" 
doc2 <- "milky way is huge" 

library(tm) 
tmp.text<-data.frame(rbind(doc1,doc2)) 
tmp.corpus<-Corpus(DataframeSource(tmp.text)) 
tmpDTM<-TermDocumentMatrix(tmp.corpus, control= list(tolower = T, removeNumbers = T, removePunctuation = TRUE,stopwords = TRUE,wordLengths = c(2, Inf))) 
tmp.df<-as.data.frame(as.matrix(tmpDTM)) 
tmp.df 

search_terms <- row.names(tmp.df) 
pattern_fix <- sapply(strsplit(search_terms, split = NULL), paste0, collapse = "\\s?") 
names(pattern_fix) <- search_terms 
word_count <- sapply(pattern_fix, grep, tmp.text[[1]]) 
h_table <- sapply(word_count, function(x) table(factor(x, levels = 1:nrow(tmp.text)))) #horizontal table 
v_table <- t(h_table) #vertical table (like tmp.df) 
v_table 

     1 2 
document 1 0 
huge  0 1 
milky 1 1 
milkyway 1 1 
way  1 1 
+0

के लिए धन्यवाद एक प्रयास करना। लेकिन आपके समाधान के लिए मुझे उन शर्तों का स्पष्ट रूप से उल्लेख करने की आवश्यकता है जिन्हें मैं मिलान करना चाहता हूं जिन्हें मैं पहले से नहीं जानता। मेरा EDIT 1 और EDIT 2 देखें यदि इससे आपको बेहतर समाधान के साथ आने में मदद मिलती है। – user3664020

+0

मेरा संपादन देखें। एक बेहतर तरीका हो सकता है, लेकिन यह कम से कम इस संक्षिप्त उदाहरण के लिए काम करता है। – JohannesNE

1

आप प्रतिनिधित्व से पहले आदिम-शब्द का एक बैग के लिए दस्तावेजों में परिवर्तित करने की आवश्यकता होगी। जहां आदिम-शब्द शब्दों के एक सेट के साथ मेल खाता है। आदिम शब्द कॉर्पस में भी हो सकता है।

उदाहरण के लिए:

milkyway -> {milky, milky way, milkyway} 
economy -> {economics, economy} 
sport -> {soccer, football, basket ball, basket, NFL, NBA} 

आप दोनों एक समानार्थी शब्द शब्दकोश और levenstein जो पर्याय शब्दकोश पूरा हो जाएगा की तरह एक संपादित दूरी के साथ कोज्या दूरी की गणना से पहले इस तरह के शब्दकोश का निर्माण कर सकते हैं।

कंप्यूटिंग 'खेल' कुंजी अधिक शामिल है।

0

यहाँ एक समाधान है कि शब्द का कोई पूर्व निर्धारित सूचियों की आवश्यकता है, लेकिन Bigrams के रूप में पाठ जहां आसन्न शब्दों के बीच कोई विभाजक वर्ण है tokenising, और फिर unigram tokenisation में मैचों की तलाश द्वारा जुदाई प्रदर्शन करती है। इन्हें तब सहेजा जाता है, और बाद में अलग-अलग संस्करणों के साथ ग्रंथों में बदल दिया जाता है।

इसका मतलब है कि कोई प्री-सेट सूचियों की आवश्यकता नहीं है, लेकिन केवल वे ही अनपढ़ हैं जिनके पाठ में समकक्ष पार्स किए गए संस्करण हैं। ध्यान दें कि इससे "बेरेटेड" और "रेटेड" जैसे झूठे सकारात्मक उत्पन्न हो सकते हैं, जो कि एक ही जोड़ी की घटना नहीं हो सकती हैं, बल्कि दूसरी अवधि में समकक्ष समेकित बिग्राम से अलग, पहले शब्द के रूप में एक वैध यूनिग्राम हो सकती है। (इस विशेष समस्या के लिए कोई सही समाधान मौजूद है।)

यह समाधान पाठ विश्लेषण के लिए quanteda पैकेज, और vectorised regex प्रतिस्थापन के लिए stringi पैकेज की आवश्यकता है।

# original example 
myTexts <- c(doc1 = "this is a document about milkyway", doc2 = "milky way is huge") 

require(quanteda) 

unparseMatches <- function(texts) { 
    # tokenize all texts 
    toks <- quanteda::tokenize(toLower(texts), simplify = TRUE) 
    # tokenize bigrams 
    toks2 <- quanteda::ngrams(toks, 2, concatenator = " ") 
    # find out which compressed pairs exist already compressed in original tokens 
    compoundTokens <- toks2[which(gsub(" ", "", toks2) %in% toks)] 
    # vectorized replacement and return 
    result <- stringi::stri_replace_all_fixed(texts, gsub(" ", "", compoundTokens), compoundTokens, vectorize_all = FALSE) 
    # because stringi strips names 
    names(result) <- names(texts) 
    result 
} 

unparseMatches(myTexts) 
##         doc1         doc2 
## "this is a document about milky way"     "milky way is huge" 
quanteda::dfm(unparseMatches(myTexts), verbose = FALSE) 
## Document-feature matrix of: 2 documents, 8 features. 
## 2 x 8 sparse Matrix of class "dfmSparse" 
##  features 
## docs this is a document about milky way huge 
## doc1 1 1 1  1  1  1 1 0 
## doc1 0 1 0  0  0  1 1 1 


# another test, with two sets of phrases that need to be unparsed 
testText2 <- c(doc3 = "This is a super duper data set about the milky way.", 
       doc4 = "And here is another superduper dataset about the milkyway.") 
unparseMatches(testText2) 
##               doc3               doc4 
##   "This is a super duper data set about the milky way." "And here is another super duper data set about the milky way." 
(myDfm <- dfm(unparseMatches(testText2), verbose = FALSE)) 
## Document-feature matrix of: 2 documents, 14 features. 
## 2 x 14 sparse Matrix of class "dfmSparse" 
##  features 
## docs this is a super duper data set about the milky way and here another 
## doc3 1 1 1  1  1 1 1  1 1  1 1 0 0  0 
## doc4 0 1 0  1  1 1 1  1 1  1 1 1 1  1 

quanteda भी इस तरह के कोज्या दूरी के रूप में समानता संगणना कर सकते हैं:

quanteda::similarity(myDfm, "doc3", margin = "documents", method = "cosine") 
##  doc4 <NA> 
## 0.7833  NA 

मुझे यकीन है कि क्या लागू नहीं है नहीं कर रहा हूँ - यह उत्पादन में बग होने के लिए जब वहाँ बस है प्रकट होता है एक दस्तावेज़ दो दस्तावेज़ दस्तावेज़ की तुलना करने के लिए। (मैं इस जल्दी ही ठीक कर देंगे, लेकिन परिणाम अभी भी सही है।)

0

के रूप में केन पहले ही कहा गया: (। इस विशेष समस्या के लिए कोई सही समाधान मौजूद है)

सभी के लिए मुझे पता है कि पाठ खनन पर कई पाठ्य पुस्तकों और पत्रिकाओं द्वारा यह बिल्कुल सही है और समर्थित है - आम तौर पर पहले कुछ पैराग्राफ के भीतर।

अपना शोध में मैं the „Deutscher Wortschatz“ project. वहाँ की तरह पहले से ही तैयार डेटासेट पर भरोसा करते हैं वे पहले से ही कड़ी मेहनत और समानार्थी शब्द, विलोम के वर्तमान उच्च गुणवत्ता सूचियों, आदि इस परियोजना i.a. polysemic शर्तों किया है साबुन के माध्यम से एक इंटरफेस का उपयोग प्रदान करता है। अंग्रेजी भाषा के लिए एक डाटाबेस, Wordnet है, उदा ..

आप एक precalculated सेट का उपयोग नहीं करना चाहते हैं या इसे बर्दाश्त नहीं कर सकता अगर मैं सुझाव है कि आप amirouche के दृष्टिकोण और आदिम-शब्द प्रतिनिधित्व के साथ चलते हैं। शब्द से उन्हें बनाना कठिन और श्रम-केंद्रित है, फिर भी सबसे व्यवहार्य दृष्टिकोण है।

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

मैं आपको सुझाव दूंगा कि आप अमीरोचे की पोस्ट को सही उत्तर के रूप में चिह्नित करें क्योंकि यह अब तक चीजों को करने का सबसे अच्छा और सबसे व्यावहारिक तरीका है (मुझे पता है)।

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