2015-10-13 18 views
9

Aynı anda birden fazla belgede oluşan kelimeleri bulmaya çalışıyorum.Aynı şekilde boşlukla ayrılmış sözcükleri aynı şekilde davranın

Örnek verelim.

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

size 2 belgelerde yukarıda görebileceğiniz gibi

, kelime "milkyway" hem docs meydana gelen ancak ikinci belge dönem "Milkyway" içinde değil bir boşlukla ve ilk doc ayrılır.

I Dönem 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 

R.

belge terimi matris elde etmek için aşağıdaki işlemleri am yukarıdaki matriks başına birinci doküman sadece mevcut bulunmaktadır.

Yukarıdaki matriste "milkyway" terimi için her iki belgede de 1 tane elde edebilmek istiyorum. Bu sadece bir örnektir. Bunu bir sürü belge için yapmalıyım. Nihayetinde benzer bir şekilde ("milkyway" & "sütlü yol") benzer bir şekilde davranabilmek istiyorum.

DÜZENLEME 1:

ben ne kelime için sadece bir olarak bu kelime aramak gerekir bunun için aramaya çalışıyor şekilde hesaplanan almak süreli belge matrisi zorunlu kılınamaz dizede ayrı bir kelime değil, aynı zamanda dizeler içinde? Örneğin, bir terim milky ve this is milkyway belgesi var, bu nedenle bu belgede şu anda milky bulunmuyor, ancak algoritma dizeleri içinde söz konusu sözcüğü ararsadizesini milkyway dizesinde bulabilirsiniz, bu şekilde milky sözcükleri ve way, her iki belgede de sayılır (önceki örnek).

DÜZENLEME 2:

Sonuçta ben belgeler arasında benzerlik kosinüs indeksini hesaplamak mümkün istiyorum.

+0

Belki alanlardan kaldırın ve regex kullanın? – zx8754

+0

Sadece 'samanyolu' ya da başkaları için mi ihtiyacınız var? İkisinin de 'Samanyolu' olmasını tercih ediyor musunuz? –

+0

@ sebastian-c Bunu birden çok kelime için yapmalıyım. Ben her ikisini de "milkyway" olmaya tercih ederim. "Her gün" ve "her gün" gibi durumlar olabilir. Bu durumda onların "her gün" olmasını tercih ederim. – user3664020

cevap

0

"\\ s?" Ifadesini ekleyerek sözcüklerin olası tüm bölümleri için eşleşecek regex'i kullanabilirsiniz. arama kelimelerinizdeki her karakter arasında. Yalnızca belirli bölümler istiyorsanız, yalnızca bu yerlere ekleyin. Aşağıdaki kod, arama terimleri için "\\ s?" Ifadesini ekleyerek regex modeli oluşturur. her karakter arasında. grep, desenin eşleştiği dizini döndürür, ancak diğer normal ifade işlevleri için değiştirilebilir.

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 

Düzenleme:

tüm kelimeleri aramak için, sadece benim çözümde SEARCH_TERMS olarak komut tmp.df isimlerini kullanabilirsiniz.

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

için teşekkürler çaba sarfetmek. Ama çözümünüz, önceden bilmediğim, önceden bilmediğim terimleri açıkça belirtmemi gerektirir. Daha iyi bir çözüm bulmaya yardım ederse EDIT 1 ve EDIT 2'ye bakın. – user3664020

+0

Düzenlememe bakın. Daha iyi bir yol olabilir, ancak bu en azından bu kısa örnek için çalışır. – JohannesNE

1

Sen temsil önce ilkel-kelimenin bir çanta belgeleri dönüştürmek gerekir. Bir ilkel kelimesi'un bir kelime kümesiyle eşleştiği yer. İlkel kelime de korpus içinde olabilir.Örneğin

:

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

Bir eş sözlüğe ve eşanlamlı sözlüğü tamamlayacak Levenstein gibi bir düzenleme mesafesi hem kosinüs mesafe hesaplama önce böyle sözlüğü oluşturabilirsiniz.

Computing 'spor' tuşuna daha karıştığı olduğunu.

0

Önceden belirlenmiş sözcük listeleri gerektiren bir çözümdür, ancak metni, bitişik sözcükler arasında ayırıcı karakter bulunmayan bigramlar olarak belirleyerek ayırma işlemini gerçekleştirir ve ardından unigram belirtecinde eşleşmeleri arar. Bunlar daha sonra kaydedilmiş ve daha sonra ayrılan sürümleri ile metinlerde değiştirilir.

Bu, hiçbir önceden ayarlanmış listeleri gerekli anlamına gelir, ancak yalnızca bu metinde eşdeğer çözümlü versiyonlarını sahip olduğunu çözümlenmemiş olması. Bu tür "berated" ikinci dönem eşdeğer birleştirilmiş Bigram ayrı aynı çiftin oluşumları değil, ilk dönemde geçerli bir unigram, olmayabilir verilen "Puan" olarak yanlış pozitif oluşturabilir unutmayın. (Bu özel sorunun yok mükemmel bir çözüm yoktur.)

Bu çözüm metin analizi için quanteda paketini ve vektörleştirilmiş regex değiştirilmesi için Stringi paketini gerektirir. ayrıca kosinüs mesafe gibi benzerlik hesaplamaları yapabilir

# 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: Ben NA ne olduğundan emin değilim

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

- sadece varken çıktıda hata gibi görünüyor İki belge kümesiyle karşılaştırmak için bir belge. (Yakında Bunu düzeltmek edeceğiz ama sonuç yine doğrudur.)

0

olarak Ken zaten belirtilmiş: (. Bu özel sorunun yok mükemmel bir çözüm var)

tamamı için

genellikle ilk birkaç paragraf içinde - Bu metin madenciliği üzerine birçok metin kitap ve dergiler tarafından kesinlikle doğru ve destekli olduğunu biliyoruz.

Araştırmamda, halihazırda hazırlanmış olan the „Deutscher Wortschatz“ project. gibi veri setlerine güveniyorum. Daha önce sıkı çalışmayı yapmışlar ve eş anlamlılar, zıt anlamlılar, polisemik terimler gibi yüksek kaliteli listeler sundular. Bu proje i.a. Sabun aracılığıyla bir arayüz erişimi sağlar. İngiliz dili için bir veritabanı, Wordnet olduğunu örn .. Bir önceden hesaplanmış kümesi kullanmak istemiyorsanız ya da göze alamaz

Sana Amirouche yaklaşımı ve ilkel kelime gösterimleri ile gitmek öneririz. kelime bunları Bina sıkıcı ve emek yoğun, henüz en uygun yaklaşım.

Aklıma gelen her diğer yöntem kesinlikle daha karmaşıktır. Sadece G. Heyer, U. Quasthoff ve T. tarafından “Metin Madenciliği, Wissensrohstoff Metni” den alınan diğer cevapları veya en son yaklaşımı görün.Wittig, (1) karakteristik özelliklerin (indeks terimlerinin) tanımlanması, (2) Terim-Cümle-Matris'in oluşturulması ve bir dönem-matrisinin hesaplanması için bir ağırlık seçimi, (3) bir benzerlik seçilmesi yoluyla kelime formları üzerinde kümelenme gibi. term-term-matrisinizde ölçüp çalıştırır ve son olarak (4) bir kümeleme algoritması seçer ve çalıştırır.

Amirouche'un post'unu doğru bir cevap olarak işaretlemenizi öneririm çünkü bu, şu ana kadar yapılması gereken en iyi ve en pratik yoldur (biliyorum).

İlgili konular