R: результаты отличаются при вычислении евклидова расстояния между двумя векторами разными методами.

Предположим, что у меня есть два вектора.

x1 = c(-1, 2, 3)
x2 = c(4, 0, -3)

Для вычисления евклидова расстояния я использовал три разных способа

1- Построенная функция norm

s = cbind(x1, x2)
norm(s, "2")
#[1] 5.797896

2- Ручной расчет

sqrt(sum(x2 - x1) ^ 2)
#[1] 8.062258

3- пользовательская функция

lpnorm <- function(x, p){  
  n <- sum(abs(x) ^ p) ^ (1 / p)
  return(n)
  }

lpnorm(s, 2)
#[1] 6.244998

Почему у меня другие результаты?

Если я ошибаюсь, как решить эту проблему?


person jeza    schedule 31.07.2018    source источник


Ответы (1)


Вам нужно s = x2 - x1.

norm(s, "2")
#[1] 8.062258

sqrt(sum(s ^ 2))  ## or: sqrt(c(crossprod(s)))
#[1] 8.062258

lpnorm(s, 2)
#[1] 8.062258

Если вы определите s = cbind(x1, x2), ни один из перечисленных вами параметров не будет вычислять евклидово расстояние между x1 и x2, но мы все равно можем заставить их выводить одно и то же значение. В этом случае они являются нормой L2 вектора c(x1, x2).

norm(s, "F")
#[1] 6.244998

sqrt(sum(s ^ 2))
#[1] 6.244998

lpnorm(s, 2)
#[1] 6.244998

Наконец, norm не является распространенным способом вычисления расстояния. Это действительно для матричной нормы. Когда вы делаете norm(cbind(x1, x2), "2"), он вычисляет норму матрицы L2, которая является наибольшим сингулярным значением матрицы cbind(x1, x2).


Итак, моя проблема заключается в определении s. Хорошо, а что, если у меня больше трех векторов?

В этом случае вам нужна попарная евклидова матрица. См. функцию ?dist.

У меня есть наборы поездов (содержащие три или более строк) и один тестовый набор (одна строка). Итак, я хотел бы рассчитать евклидово расстояние или, возможно, другие расстояния. Вот почему я хочу убедиться в расчете расстояния.

Вы хотите, чтобы расстояние между одним вектором и каждым из многих других было вектором?

set.seed(0)
X_train <- matrix(runif(10), 5, 2)
x_test <- runif(2)
S <- t(X_train) - x_test

apply(S, 2, norm, "2")  ## don't try other types than "2"
#[1] 0.8349220 0.7217628 0.8012416 0.6841445 0.9462961

apply(S, 2, lpnorm, 2)
#[1] 0.8349220 0.7217628 0.8012416 0.6841445 0.9462961

sqrt(colSums(S ^ 2))  ## only for L2-norm
#[1] 0.8349220 0.7217628 0.8012416 0.6841445 0.9462961

Я хотел бы еще раз подчеркнуть, что norm потерпит неудачу на векторе, если только type = "2". ?norm ясно говорит, что эта функция предназначена для matrix. То, что делает norm, сильно отличается от вашей собственной функции lpnorm. lpnorm соответствует векторной норме, norm соответствует матричной норме. Даже "L2" означает по-разному для матрицы и вектора.

person Zheyuan Li    schedule 31.07.2018