2016-08-11 4 views
5

Я пытаюсь понять, что происходит с моими расчетами расстояния в Канберре. Я пишу свою собственную простую функцию canberra.distance, однако результаты не согласуются с функцией dist. Я добавил опцию na.rm = T к моей функции, чтобы иметь возможность рассчитать сумму при нулевом знаменателе. Из ?dist Я понимаю, что они используют аналогичный подход: Terms with zero numerator and denominator are omitted from the sum and treated as if the values were missing.canberra distance - непоследовательные результаты

canberra.distance <- function(a, b){ 
    sum((abs(a - b))/(abs(a) + abs(b)), na.rm = T) 
} 

a <- c(0, 1, 0, 0, 1) 
b <- c(1, 0, 1, 0, 1) 
canberra.distance(a, b) 
> 3 
# the result that I expected 
dist(rbind(a, b), method = "canberra") 
> 3.75 


a <- c(0, 1, 0, 0) 
b <- c(1, 0, 1, 0) 
canberra.distance(a, b) 
> 3 
# the result that I expected 
dist(rbind(a, b), method = "canberra") 
> 4 

a <- c(0, 1, 0) 
b <- c(1, 0, 1) 
canberra.distance(a, b) 
> 3 
dist(rbind(a, b), method = "canberra") 
> 3 
# now the results are the same 

пар 0-0 и 1-1, кажется проблематичным. В первом случае (0-0) и числитель, и знаменатель равны нулю, и эта пара должна быть опущена. Во втором случае (1-1) числитель равен 0, а знаменатель - нет, и тогда он также равен 0, и сумма не должна меняться.

Что мне здесь не хватает?

РЕДАКТИРОВАТЬ: Для того, чтобы быть в соответствии с определением R, функция canberra.distance может быть изменена следующим образом:

canberra.distance <- function(a, b){ 
    sum(abs(a - b)/abs(a + b), na.rm = T) 
} 

Однако результаты являются такими же, как и раньше.

+2

Я думаю, что вы, возможно, наткнулись на ошибку в базе R. Я не уверен, но [Wolfram Alpha соглашается с вами] (https://www.wolframalpha.com/input/?i=CanberraDistance%5B% 7Б1 + 0, + 1, + 0% 7D +% 7B0 + 1, + 0 + 0% 7D% 5D). К сожалению, я не могу найти авторитетную ссылку, но ваша реализация кажется правильной согласно Wikipedia и Wolfram. –

+0

Фактически, [документация 'dist'] (https://stat.ethz.ch/R-manual/R-devel/library/stats/html/dist.html) определяет расстояние Канберры как * sum (| x_i - y_i |/| x_i + y_i |) * (который отличается от вашего и Wolfram's). Он также отмечает, что «[t] его предназначено для неотрицательных значений (например, подсчетов): принятие абсолютного значения знаменателя является модификацией 1998 R, чтобы избежать отрицательных расстояний». - Таким образом, определение R документировано как другое. –

+0

@ KonradRudolph Спасибо за ваш ответ! Я редактировал свой пост. С определением R из-за несоответствий расстояния в Канберре остаются, поэтому я не думаю, что это проблема. – Adela

ответ

0

Это может пролить свет на разницу. Насколько я могу видеть это фактический код запускаемым для вычисления расстояния

static double R_canberra(double *x, int nr, int nc, int i1, int i2) 
{ 
    double dev, dist, sum, diff; 
    int count, j; 

    count = 0; 
    dist = 0; 
    for(j = 0 ; j < nc ; j++) { 
    if(both_non_NA(x[i1], x[i2])) { 
     sum = fabs(x[i1] + x[i2]); 
     diff = fabs(x[i1] - x[i2]); 
     if (sum > DBL_MIN || diff > DBL_MIN) { 
     dev = diff/sum; 
     if(!ISNAN(dev) || 
      (!R_FINITE(diff) && diff == sum && 
      /* use Inf = lim x -> oo */ (int) (dev = 1.))) { 
      dist += dev; 
      count++; 
     } 
     } 
    } 
    i1 += nr; 
    i2 += nr; 
    } 
    if(count == 0) return NA_REAL; 
    if(count != nc) dist /= ((double)count/nc); 
    return dist; 
} 

Я думаю, что виновник является этой линией

if(!ISNAN(dev) || 
       (!R_FINITE(diff) && diff == sum && 
       /* use Inf = lim x -> oo */ (int) (dev = 1.))) 

который обрабатывает особый случай и не может быть документирован.

+0

Благодарим вас за ответ. К сожалению, я не очень разбираюсь в C++, поэтому я не уверен, что происходит с этими особыми случаями. Не могли бы вы пролить свет на него? – Adela

+0

Строка содержит специальный случай, что если два значения идентичны 'diff == sum', то он добавляет один к числителю, так как он устанавливает' dev = 1'. Однако, почему код проходит мимо 'diff> DBL_MIN', для меня это немного неясно. Возможно, есть проблемы с преобразованием/точностью с плавающей запятой? – ekstroem

+0

Ну, добавив один к числителю, объясните случай 1-1 пары и значение расстояния 4. Однако я не вижу, как это связано с случаем пары 0-0. Есть идеи? – Adela

Смежные вопросы