web-dev-qa-db-fra.com

Comment fonctionne removeSparseTerms in R?

J'utilise la méthode removeSparseTerms dans R et il a fallu saisir une valeur seuil. J'ai aussi lu que plus la valeur est élevée, plus le nombre de termes conservés dans la matrice retournée sera grand.

Comment cette méthode fonctionne-t-elle et quelle est sa logique? Je comprends la notion de rareté, mais ce seuil indique-t-il combien de documents un terme doit être présent, ou un autre rapport, etc.?

14
London guy

Au sens de l'argument sparse de removeSparseTerms(), sparsity fait référence au seuil de fréquence relative du document pour un terme, au-dessus duquel le terme sera supprimé. La fréquence relative des documents signifie ici une proportion. Comme le dit la page d’aide de la commande (bien que cela ne soit pas très clair), la légèreté est plus petite à l’approche de 1.0. (Notez que sparsity ne peut pas prendre les valeurs 0 ou 1.0, seulement les valeurs entre les deux.)

Par exemple, si vous définissez sparse = 0.99 en tant qu'argument sur removeSparseTerms(), cela supprimera uniquement les termes qui sont plus plus rares que 0,99 . L'interprétation exacte de sparse = 0.99 est celle du terme $ j $, conserve tous les termes pour lesquels $ df_j> N * (1 - 0,99) $, où $ N $ est le nombre de documents - dans ce cas, tous les termes seront conservés (voir exemple ci-dessous).

Près de l'autre extrémité, si sparse = .01, alors seuls les termes apparaissant dans (presque) tous les documents seront conservés. (Bien entendu, cela dépend du nombre de termes et du nombre de documents, et en langage naturel, des mots courants tels que "le" sont susceptibles d'apparaître dans chaque document et par conséquent de ne jamais être "clairsemés".)

Un exemple du seuil de rareté de 0,99, où un terme qui apparaît au plus dans (premier exemple) inférieur à 0,01 document et (deuxième exemple) à peine plus de 0,01 document:

> # second term occurs in just 1 of 101 documents
> myTdm1 <- as.DocumentTermMatrix(slam::as.simple_triplet_matrix(matrix(c(rep(1, 101), rep(1,1), rep(0, 100)), ncol=2)), 
+                                weighting = weightTf)
> removeSparseTerms(myTdm1, .99)
<<DocumentTermMatrix (documents: 101, terms: 1)>>
Non-/sparse entries: 101/0
Sparsity           : 0%
Maximal term length: 2
Weighting          : term frequency (tf)
> 
> # second term occurs in 2 of 101 documents
> myTdm2 <- as.DocumentTermMatrix(slam::as.simple_triplet_matrix(matrix(c(rep(1, 101), rep(1,2), rep(0, 99)), ncol=2)), 
+                                weighting = weightTf)
> removeSparseTerms(myTdm2, .99)
<<DocumentTermMatrix (documents: 101, terms: 2)>>
Non-/sparse entries: 103/99
Sparsity           : 49%
Maximal term length: 2
Weighting          : term frequency (tf)

Voici quelques exemples supplémentaires avec du texte et des termes réels: 

> myText <- c("the quick brown furry fox jumped over a second furry brown fox",
              "the sparse brown furry matrix",
              "the quick matrix")

> require(tm)
> myVCorpus <- VCorpus(VectorSource(myText))
> myTdm <- DocumentTermMatrix(myVCorpus)
> as.matrix(myTdm)
    Terms
Docs brown fox furry jumped matrix over quick second sparse the
   1     2   2     2      1      0    1     1      1      0   1
   2     1   0     1      0      1    0     0      0      1   1
   3     0   0     0      0      1    0     1      0      0   1
> as.matrix(removeSparseTerms(myTdm, .01))
    Terms
Docs the
   1   1
   2   1
   3   1
> as.matrix(removeSparseTerms(myTdm, .99))
    Terms
Docs brown fox furry jumped matrix over quick second sparse the
   1     2   2     2      1      0    1     1      1      0   1
   2     1   0     1      0      1    0     0      0      1   1
   3     0   0     0      0      1    0     1      0      0   1
> as.matrix(removeSparseTerms(myTdm, .5))
    Terms
Docs brown furry matrix quick the
   1     2     2      0     1   1
   2     1     1      1     0   1
   3     0     0      1     1   1

Dans le dernier exemple avec sparse = 0.34, seuls les termes figurant dans les deux tiers des documents ont été conservés.

Une approche alternative pour supprimer les termes à partir de matrices de termes de document basées sur une fréquence de document est le package d'analyse de texte texte quanteda. La même fonctionnalité se réfère ici non pas à fragmentation _, mais plutôt directement à la fréquence du document de termes (comme dans tf-idf).

> require(quanteda)
> myDfm <- dfm(myText, verbose = FALSE)
> docfreq(myDfm)
     a  brown    fox  furry jumped matrix   over  quick second sparse    the 
     1      2      1      2      1      2      1      2      1      1      3 
> trim(myDfm, minDoc = 2)
Features occurring in fewer than 2 documents: 6 
Document-feature matrix of: 3 documents, 5 features.
3 x 5 sparse Matrix of class "dfmSparse"
       features
docs    brown furry the matrix quick
  text1     2     2   1      0     1
  text2     1     1   1      1     0
  text3     0     0   1      1     1

Cet usage me semble beaucoup plus simple.

42
Ken Benoit

Dans la fonction removeSparseTerms(), l'argument sparse = x signifie:
"supprime tous les termes dont la rareté est supérieure au seuil (x)".
par exemple: removeSparseTerms(my_dtm, sparse = 0.90) signifie supprimer tous les termes du corpus dont la densité est supérieure à 90%.

Par exemple, un terme qui apparaît seulement 4 fois dans un corpus de taille 1000, aura une fréquence d'apparition de 0,004 = 4/1000. 

La rareté de ce terme sera (1000-4)/1000 = 1- 0.004 = 0.996 = 99.6%.
Par conséquent, si le seuil de rareté est défini sur sparse = 0.90, ce terme sera supprimé car sa densité (0.996) est supérieure à la limite supérieure (0.90).
Toutefois, si le seuil de rareté est défini sur sparse = 0.999, ce terme ne sera pas supprimé car sa densité (0.996) est inférieure à la limite supérieure (0.999).

4
PatrickBeuseize

Simple, c'est comme la fréquence d'un élément. Si vous définissez la valeur sur 0, tous les éléments qui apparaissent dans tout le texte seront renvoyés, et si vous définissez la valeur sur 1, tous les éléments du texte seront renvoyés. Si je choisis 0,5, cela me permettra de ne voir que les textes qui apparaissent 50% du temps dans l'élément entier. Ceci est fait en calculant après tout ce que le traitement par 

1- (sum (no_off_times_of_the_individual_text_element)/sum (no_off_total_text_elements)) <= Set_Value

1
Sherl