Modification de la distance Canberra de la fonction dist

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Varin Thibault
Messages : 31
Enregistré le : 08 Nov 2006, 11:23

Modification de la distance Canberra de la fonction dist

Messagepar Varin Thibault » 24 Jan 2008, 18:34

Bonjour,
la formule de la fonction Canberra est : sum(|x_i - y_i| / |x_i + y_i|)
Si on a x_i=0 et y_i=0, la fonction dist donne une distance égale à 1..., mais je souhaiterai obtenir une distance égale à 0.
Par exemple si on tape :
dist(rbind(c(0,0,1,0),c(0,0,0,0)),method="canberra")
j'obtiens la une distance égale à 4.
Je souhaite modifier le script de cette distance pour obtenir une distance égale à 1.
Le problème est que si l'on tape dist dans la console, on obtient le script de la fonction, mais là ça devient compliqué et je ne trouve pas comment accéder aux formules des distances...?
Est-ce que quelqu'un sait?
Merci d'avance!
PS : je pourrai évidemment écrire une fonction directement, mais je travaille sur des matrices de distances volumineuses et le temps de calcul devient alors trop important, je pense que la fonction dist fait appel à un sous programme en C, mais je ne suis pas sur...

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 24 Jan 2008, 22:16

je pense que la fonction dist fait appel à un sous programme en C, mais je ne suis pas sur...


oui c'est pour cela qu'il y a la fonction .C dans le code de dist. Le passage en C permet de grandement accélérer les calculs.

Par contre si :

avec xi=yi=0

Je ne suis pas plus matheux que ça mais cela a t il un sens de mesurer une distance car il me semble que cela revient à mesurer une distance de l'origine à l'origine dans une base.

Ceci dit, dist(...,method="canberra") est sensée ignorer les couples {0,0} comme il est dit dans l'aide de dist. Alors je ne comprend pas trop pourquoi R donne une valeur. A moins que ce ne soit encore un problème de 0 véritable. C'est à dire que l'informatique ne connaissant pas la vraie valeur 0, elle est approximée par une valeur très faible (c'est ainsi que dans R ont peut inverser une matrice de déterminant nul, sans message d'erreur...les valeurs sont tout de même abérrantes :) )

un petit tour par ici pour savoir comment obtenir les sources en C et pour un commentaire sur le calcul de la distance de Canberra dans R :
viewtopic.php?t=412&highlight=canberra
viewtopic.php?t=703&highlight=canberra

bon courage.

Nicolas.

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 25 Jan 2008, 08:53

Bonjour,


tout est dans l'aide ?dist :
Missing values are allowed, and are excluded from all computations involving the rows within which they occur. Further, when Inf values are involved, all pairs of values are excluded when their contribution to the distance gave NaN or NA.
If some columns are excluded in calculating a Euclidean, Manhattan, Canberra or Minkowski distance, the sum is scaled up proportionally to the number of columns used.


Le problème n'est donc pas qu'il calcule 1 quand les deux valeurs sont zéros mais que la somme est recalée par rapport aux nombres de valeurs "manquantes" (0 au numérateur et au dénominateur). Donc plus tu auras de double zéros et plus ta somme va augmenter. Ce n'est donc pas un problème informatique de reconnaissance de zéros.

Code : Tout sélectionner

dist(rbind(c(1,rep(0,19)),rep(0,20)),"canberra")
   1
2 20


Après à toi de voir comment tu gères les doubles zéros.

Le code est de calcul de la distance est en C :

Code : Tout sélectionner

d <- .C("R_distance", x = as.double(x), nr = N, nc = ncol(x),
        d = double(N * (N - 1)/2), diag = as.integer(FALSE),
        method = as.integer(method), p = as.double(p), DUP = FALSE,
        NAOK = TRUE, PACKAGE = "stats")$d


La je ne peux pas t'aider.

Maxime

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 25 Jan 2008, 10:11

La fonction dist() ne prend pas en compte le fait qu'on lui donne une valeur qui n'a pas vraiment de sens

En fouillant un peu :

Code : Tout sélectionner

> vegdist(rbind(c(0,0,1,0),c(0,0,0,0)),method="canberra")
  1
2 1
Warning message:
In vegdist(rbind(c(0, 0, 1, 0), c(0, 0, 0, 0)), method = "canberra") :
  you have empty rows: their dissimilarities may be meaningless in method canberra


Ce qui semble correspondre à ce qui est recherché :) et en plus on a un warning qui nous averti sur le calcul de distance entre 2 valeurs nulles.

Varin Thibault
Messages : 31
Enregistré le : 08 Nov 2006, 11:23

Messagepar Varin Thibault » 28 Jan 2008, 13:29

Merci beaucoup pour les éclaircissements!
Dommage, je ne connais pas le C mais effectivement, une fonction comme vegdist me conviendra parfaitement!
Merci!


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité