2017-07-28 4 views
0

Peut-être que j'interprète mal comment fonctionne tm::DocumentTermMatrix. J'ai un corpus qui, après traitement préalable ressemble à ceci:TM DocumentTermMatrix donne des résultats inattendus étant donné le corpus

head(Description.text, 3) 
[1] "azi sanitar local to1 presid osp martin presid ospedalier martin tofan torin tel possibil raggiung ospedal segu bus tram"      
[2] "torin croll controsoffitt repart pediatr martin mag cartell compars sest pian ospedal martin torin ospedal tofan sol due anno riapertur"  
[3] "ospedal martin croll controsoffitt repart pediatr mag ospedal martin croll controsoffitt repart pediatr distacc intonac avven nott mattin" 

que je processus via:

Description.text.features <- DocumentTermMatrix(Corpus(VectorSource(Description.text)), list(
    bounds = list(local = c(3, Inf)), 
    tokenize = 'scan' 
)) 

quand j'inspecte la première ligne du DTM i obtenir ceci:

inspect(Description.text.features[1,]) 
<<DocumentTermMatrix (documents: 1, terms: 887)>> 
Non-/sparse entries: 0/887 
Sparsity   : 100% 
Maximal term length: 15 
Weighting   : term frequency (tf) 
Sample    : 
    Terms 
Docs banc camill mar martin ospedal presid san sanitar torin vittor 
    1 0  0 0  0  0  0 0  0  0  0 

Ces termes ne correspondent pas au premier document du corpus Description.text (par exemple banc ou camill ne figurent pas dans le premier document et il y a un zéro pour par exemple martin ou presid qui sont).

En outre, si je cours:

Description.text.features[1,] %>% as.matrix() %>% sum 

Je reçois zéro, ce qui montre que dans le premier document, il n'y a pas de termes avec une fréquence> zéro!

Que se passe-t-il ici?

Merci

MISE À JOUR

J'ai créé ma propre fonction « corpus DtM » et en effet, il donne des résultats très différents. Mis à part les termes du document qui sont très différents de ceux de tm::DocumentTermMatrix (les miens sont ce que vous attendez du corpus), j'obtiens beaucoup plus de termes avec ma fonction qu'avec la fonction tm (~ 3000 vs 800 de tm).

Voilà ma fonction:

corpus.to.DTM <- function(corpus, min.doc.freq = 3, minlength = 3, weight.fun = weightTfIdf) { 
    library(dplyr) 
    library(magrittr) 
    library(tm) 
    library(parallel) 

    lvls <- mclapply(corpus, function(doc) words(doc) %>% unique, mc.cores = 8) %>% 
     unlist %>% 
     table %>% 
     data.frame %>% 
     set_colnames(c('term', 'freq')) %>% 
     mutate(lengths = str_length(term)) %>% 
     filter(freq >= min.doc.freq & lengths >= minlength) %>% 
     use_series(term) 

    dtm <- mclapply(corpus, function(doc) factor(words(doc), levels = lvls) %>% table %>% as.vector, mc.cores = 8) %>% 
     do.call(what = 'rbind') %>% 
     set_colnames(lvls) 

    as.DocumentTermMatrix(dtm, weighting = weightTfIdf) %>% 
     as.matrix() %>% 
     as.data.frame() 
} 

Répondre

1

Voici une solution utilisant la tm alternatif, quanteda. Vous pourriez même trouver la simplicité relative de ce dernier, combinée avec sa vitesse et ses caractéristiques, suffisante pour l'utiliser aussi pour le reste de votre analyse!

description.text <- 
    c("azi sanitar local to1 presid osp martin presid ospedalier martin tofan torin tel possibil raggiung ospedal segu bus tram", 
    "torin croll controsoffitt repart pediatr martin mag cartell compars sest pian ospedal martin torin ospedal tofan sol due anno riapertur", 
    "ospedal martin croll controsoffitt repart pediatr mag ospedal martin croll controsoffitt repart pediatr distacc intonac avven nott mattin") 

require(quanteda) 
require(magrittr) 

qdfm <- dfm(description.text) 
head(qdfm, nfeat = 10) 
# Document-feature matrix of: 3 documents, 35 features (56.2% sparse). 
# (showing first 3 documents and first 10 features) 
#  features 
# docs azi sanitar local to1 presid osp martin ospedalier tofan torin 
# text1 1  1  1 1  2 1  2   1  1  1 
# text2 0  0  0 0  0 0  2   0  1  2 
# text3 0  0  0 0  0 0  2   0  0  0 

qdfm2 <- qdfm %>% dfm_trim(min_count = 3, min_docfreq = 3) 
qdfm2 
# Document-feature matrix of: 3 documents, 2 features (0% sparse). 
# (showing first 3 documents and first 2 features) 
#  features 
# docs martin ospedal 
# text1  2  1 
# text2  2  2 
# text3  2  2 

Pour reconvertir tm:

convert(qdfm2, to = "tm") 
# <<DocumentTermMatrix (documents: 3, terms: 2)>> 
# Non-/sparse entries: 6/0 
# Sparsity   : 0% 
# Maximal term length: 7 
# Weighting   : term frequency (tf) 

Dans votre exemple, vous utilisez la pondération tf-idf. C'est aussi facile à quanteda:

dfm_weight(qdfm, "tfidf") %>% head 
# Document-feature matrix of: 3 documents, 35 features (56.2% sparse). 
# (showing first 3 documents and first 6 features) 
#   features 
# docs   azi sanitar  local  to1 presid  osp 
# text1 0.4771213 0.4771213 0.4771213 0.4771213 0.9542425 0.4771213 
# text2 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 
# text3 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 
+0

Merci pour la suggestion! Je vais jeter un oeil à l'emballage! mais ma question était spécifiquement sur ce qui n'allait pas avec tm! – Bakaburg