2016-10-30 5 views
0

J'essaye de calculer une matrice de co-occurrence de terme-term (ou TCM) d'un corpus en utilisant le text2vec dans R (puisqu'il a un backend parallèle gentil). J'ai suivi this tutorial, mais tout en inspectant certains exemples de jouets, j'ai remarqué que la fonction create_tcm effectue une sorte de mise à l'échelle ou de pondération sur les valeurs de co-occurrence à terme terme. Je sais qu'il utilise des skip-grams en interne, mais la documentation ne mentionne pas comment il les met à l'échelle - clairement, les termes/les unigrammes plus lointains sont pondérés plus bas.Calculer TCM non pondéré basé sur des mots-clés en utilisant text2vec dans R?

Voici un exemple:

tcmtest = function(sentences){ 
    tokens <- space_tokenizer(sentences) 
    it = itoken(tokens, progressbar = FALSE) 
    vocab <- create_vocabulary(it, ngram = c(ngram_min = 1L, ngram_max = 1L)) 
    vectorizer <- vocab_vectorizer(vocab, grow_dtm = FALSE, skip_grams_window = 5L) 
    return(create_tcm(it, vectorizer)) 
} 

> tcmtest(c("a b", "a b c")) 
3 x 3 sparse Matrix of class "dgTMatrix" 
    b c a 
b . 1 2.0 
c . . 0.5 
a . . . 
> tcmtest(c("a b", "c a b")) 
3 x 3 sparse Matrix of class "dgTMatrix" 
    b c a 
b . 0.5 2 
c . . 1 
a . . . 
> tcmtest(c("a b", "c a a a b")) 
3 x 3 sparse Matrix of class "dgTMatrix" 
    b c  a 
b . 0.25 2.833333 
c . . 1.833333 
a . . . 

Question: est-il possible de désactiver ce comportement, de sorte que chaque terme/unigramme dans la fenêtre saut-gramme est traité de manière égale? C'est-à-dire que si un terme apparaît à l'intérieur de la fenêtre contextuelle d'un autre terme deux fois dans un corpus, il doit indiquer "2" dans la matrice TCM. Question de bonification: comment la mise à l'échelle par défaut fonctionne-t-elle quand même? Si vous ajoutez plus de "a" au dernier exemple, alors la valeur b-c semble diminuer linéairement, alors que la valeur b-a augmente réellement - bien que plus d'occurrences ou "a" apparaissent plus loin de "b".

+2

Question supplémentaire: Dans le dernier exemple, "b" est la 4ème lettre de c. C'est 1/4. Pour "a" et "c", vous avez "a" à 1, 2 et 3 lettres de c. C'est 1 + 1/2 + 1/3 = 1.833333. Pour "b" et "a", vous avez 2 occasions où "a" est juste à côté de "b", puis deux autres instances de "a" où il est à une distance de 2 et 3 de "b", respectivement. C'est 2 + 1/2 + 1/3. Puisque vous avez 'skip_grams_window = 5',' c ("a b", "c a a a a a b") 'et' c ("a b", "c a a a a b") 'produira le même résultat de' tcmtest'. – Jota

+0

@Jota cool, cela a du sens. Maintenant, comment puis-je contourner cette mise à l'échelle? – user3554004

+0

@ user3554004 En fait, vous n'utilisez aucun backend parallèle dans votre exemple. Voyez comment nous créons des «jobs» dans cette [vignette] (https://cran.r-project.org/web/packages/text2vec/vignettes/files-multicore.html#multicore_machines). Aussi je veux ajouter, que l'utilisation de backend parallèle à 'tcm' n'a de sens que pour les très grands corpus. –

Répondre

1

MISE À JOUR 2017-02-01 Pushed update to github - vous pouvez désormais spécifier vecteur pondération directement dans create_tcm.

La fonction de pondération est définie here. Si vous avez besoin de poids égal pour chaque terme dans la fenêtre, vous devez régler la fonction de pondération pour revenir toujours 1 (clone juste repo, la définition de la fonction de changement et construire des paquets de la source avec devtools ou R CMD build):

inline float weighting_fun(uint32_t offset) { 
    return 1.0; 
} 

Cependant plusieurs les gens ont déjà demandé cette fonctionnalité et j'inclurai probablement cette option dans la prochaine version.