web-dev-qa-db-fra.com

La «norme» est-elle équivalente à la «distance euclidienne»?

Je ne sais pas si "norme" et "distance euclidienne" signifient la même chose. Pourriez-vous m'aider à faire cette distinction.

J'ai un n par m tableau a, où m> 3. Je veux calculer la distance éculidienne entre le deuxième point de données a[1,:] à tous les autres points (y compris lui-même). J'ai donc utilisé le np.linalg.norm, qui produit la norme de deux points donnés. Mais je ne sais pas si c'est la bonne façon d'obtenir les services d'urgence.

import numpy as np

a = np.array([[0, 0, 0 ,0 ], [1, 1 , 1, 1],[2,2, 2, 3], [3,5, 1, 5]])
N = a.shape[0] # number of row
pos = a[1,:] # pick out the second data point. 
dist = np.zeros((N,1), dtype=np.float64)

for i in range(N):
    dist[i]= np.linalg.norm(a[i,:] - pos)
21
J_yang

Une norme est une fonction qui prend un vecteur en entrée et renvoie une valeur scalaire qui peut être interprétée comme la "taille", la "longueur" ou la "magnitude" de ce vecteur. Plus formellement, les normes sont définies comme ayant les propriétés mathématiques suivantes:

  • Ils évoluent de manière multiplicative, c'est-à-dire Norm (a · v ) = | a | · Norm ( v ) pour tout scalaire a
  • Ils satisfont l'inégalité du triangle, c'est-à-dire Norm ( u + v ) ≤ Norm ( u ) + Norm ( v )
  • La norme d'un vecteur est nulle si et seulement si c'est le vecteur zéro, c'est-à-dire Norm ( v ) = 0 ⇔ v = 0

La norme euclidienne (également connue sous le nom de norme L²) n'est qu'une des nombreuses normes différentes - il existe également la norme max, la norme Manhattan, etc. La norme L² d'un vecteur unique équivaut à la distance euclidienne de ce point à l'origine , et la norme L² de la différence entre deux vecteurs est équivalente à la distance euclidienne entre les deux points.


Comme le dit @ nobar , np.linalg.norm(x - y, ord=2) (ou simplement np.linalg.norm(x - y)) vous donnera la distance euclidienne entre les vecteurs x et y.

Puisque vous voulez calculer la distance euclidienne entre a[1, :] et toutes les autres lignes de a, vous pouvez le faire beaucoup plus rapidement en éliminant la boucle for et en diffusant sur les lignes de a:

dist = np.linalg.norm(a[1:2] - a, axis=1)

Il est également facile de calculer vous-même la distance euclidienne en utilisant la radiodiffusion:

dist = np.sqrt(((a[1:2] - a) ** 2).sum(1))

La méthode la plus rapide est probablement scipy.spatial.distance.cdist :

from scipy.spatial.distance import cdist

dist = cdist(a[1:2], a)[0]

Quelques synchronisations pour un tableau (1000, 1000):

a = np.random.randn(1000, 1000)

%timeit np.linalg.norm(a[1:2] - a, axis=1)
# 100 loops, best of 3: 5.43 ms per loop

%timeit np.sqrt(((a[1:2] - a) ** 2).sum(1))
# 100 loops, best of 3: 5.5 ms per loop

%timeit cdist(a[1:2], a)[0]
# 1000 loops, best of 3: 1.38 ms per loop

# check that all 3 methods return the same result
d1 = np.linalg.norm(a[1:2] - a, axis=1)
d2 = np.sqrt(((a[1:2] - a) ** 2).sum(1))
d3 = cdist(a[1:2], a)[0]

assert np.allclose(d1, d2) and np.allclose(d1, d3)
32
ali_m

Le concept de "norme" est une idée généralisée en mathématiques qui, appliquée aux vecteurs (ou aux différences de vecteurs), représente globalement une certaine mesure de la longueur. Il existe différentes approches pour calculer une norme, mais celle appelée distance euclidienne est appelée "norme 2" et est basée sur l'application d'un exposant de 2 (le "carré"), et après avoir sommé l'application d'un exposant de 1/2 (la "racine carrée").


C'est un peu cryptique dans la documentation , mais vous obtenez la distance euclidienne entre deux vecteurs en définissant le paramètre ord=2.

sum(abs(x)**ord)**(1./ord)

devient sqrt(sum(x**2)).

Remarque: comme indiqué par @Holt, la valeur par défaut est ord=None, Qui est documentée pour calculer la "norme 2" pour les vecteurs. C'est donc équivalent à ord=2 (Distance euclidienne).

5
nobar