10.1 Distâncias

Distâncias e divergências são métricas utilizadas em problemas de classificação, agrupamento e reconhecimento de padrões. São utilizadas para medir a similaridade entre pontos, vetores e distribuições.

É comum realizar a padronização, i.e., subtrair cada valor da média e dividir pelo desvio padrão da coluna à qual o valor pertence. Este procedimento pode ser realizado através da função base::scale. Note que o termo normalização pode se referir a outros tipos de ajustamento.

Exemplo 10.1 Vetores para a aplicação dos exemplos.

# criando data frame 'df' para os exemplos a seguir
df <- data.frame(V1=c(3,2), V2=c(2,4), V3=c(0,5))  # vetores V1 e V2
rownames(df) <- c('x','y')  # rótulo das linhas
df
##   V1 V2 V3
## x  3  2  0
## y  2  4  5
# padronizando os dados
df.s <- scale(df)
df.s
##           V1         V2         V3
## x  0.7071068 -0.7071068 -0.7071068
## y -0.7071068  0.7071068  0.7071068
## attr(,"scaled:center")
##  V1  V2  V3 
## 2.5 3.0 2.5 
## attr(,"scaled:scale")
##        V1        V2        V3 
## 0.7071068 1.4142136 3.5355339

10.1.1 Manhattan

A distância de Manhattan, norma 1 ou \(L_1\) é uma medida de dissimilaridade que avalia a distância absoluta entre dois vetores.

\[\begin{equation} \Delta_{Man}(x,y) = \sum_{i=1}^{n} |x_i - y_i| \tag{10.1} \end{equation}\]

sum(abs(df[1,]-df[2,]))  # distância manhattan aplicando Eq. (18)
## [1] 8
stats::dist(df, method = 'manhattan')  # distância manhattan via 'dist'
##   x
## y 8
stats::dist(df.s, method = 'manhattan')  # distância manhattan via 'dist' dos valores padronizados
##          x
## y 4.242641

10.1.2 Euclidiana

A distância euclidiana, norma 2 ou \(L_2\) é dada pela Equação (10.2).

\[\begin{equation} \Delta_{Euc}(x,y) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2} \tag{10.2} \end{equation}\]

sqrt(sum((df[1,]-df[2,])^2))  # distância euclidiana aplicando Eq. (19)
## [1] 5.477226
stats::dist(df, method = 'euclidean')  # distância euclidiana via 'dist'
##          x
## y 5.477226
stats::dist(df.s, method = 'euclidean')  # distância euclidiana via 'dist' dos valores padronizados
##         x
## y 2.44949

10.1.3 Minkowski

A distância de Minkowski, norma p ou \(L_p\) é uma medida de dissimilaridade que generaliza as distâncias de Manhattan e euclidiana.

\[\begin{equation} \Delta_{Min}(x,y) = \sqrt[\leftroot{-2}\uproot{3}p]{\sum_{i=1}^{n} (|x_i - y_i|)^p} \tag{10.3} \end{equation}\]

sum((abs(df[1,]-df[2,]))^5)^(1/5)     # distância de Minkowski com p=5 aplicando Eq. (20)
## [1] 5.010516
stats::dist(df, method = 'minkowski', p = 5) # distância de Minkowski com p=5 via 'dist'
##          x
## y 5.010516
stats::dist(df.s, method = 'minkowski', p = 5) # dist. de Minkowski com p=5 via 'dist' dos valores padronizados
##         x
## y 1.76173

Exercício 10.1 Considere a função stats::dist.
(a) Verifique sua documentação, fazendo ?dist.
(b) Compare as distâncias euclidiana e de Minkowski com \(p=2\). O que você observa?
(c) Compare as distâncias de Manhattan e de Minkowski com \(p=1\). O que você observa?
\(\\\)

Exercício 10.2 Considere as distâncias da Seção ?? aplicada às colunas numéricas do banco de dados pib, obtido pelo código abaixo.
(a) Padronize os dados e atribua a uma variável chamada pib.s.
(b) Realize os cálculos ‘a mão’ como nos exemplos, tanto para pib quanto para pib.s.
(c) Realize novamente os cálculos do item (b) utilizando a função dist.

pib <- read.table('https://filipezabala.com/data/pib.txt', head = T, sep = '\t')

10.1.4 Cosseno

A divergência de cosseno é assim chamada pois não possui a desigualdade triangular, como espera-se de uma distância.

\[\begin{equation} \Delta_{Cos}(x,y) = 1 - \frac{x \cdot y}{||x|| \, ||y||} = 1 - \frac{\sum_{i=1}^n x_i y_i}{\sqrt{\sum_{i=1}^n x_i^2} \, \sqrt{\sum_{i=1}^n y_i^2}} \tag{10.4} \end{equation}\]

# Função para cálculo da similaridade do cosseno
cosine_similarity <- function(vec_a, vec_b) {
  dot_product <- sum(vec_a * vec_b)
  magnitude_a <- sqrt(sum(vec_a^2))
  magnitude_b <- sqrt(sum(vec_b^2))
  return(dot_product / (magnitude_a * magnitude_b))
}

# Calcula a similaridade do cossenos
(similarity <- cosine_similarity(df$V1, df$V2))
## [1] 0.8682431
# Calcula a distância de cosseno
(cos_dist <- 1 - similarity)
## [1] 0.1317569

Exemplo 10.2 Usando o pacote lsa (Wild 2022).

# install.packages('lsa')
library(lsa)

(similarity <- lsa::cosine(df$V1, df$V2))
##           [,1]
## [1,] 0.8682431
(distance <- 1 - similarity)
##           [,1]
## [1,] 0.1317569
1-lsa::cosine(as.matrix(df))
##           V1        V2        V3
## V1 0.0000000 0.1317569 0.4452998
## V2 0.1317569 0.0000000 0.1055728
## V3 0.4452998 0.1055728 0.0000000

10.1.5 Fermat

Groisman, Jonckheere, and Sapienza (2022) definem a distância de Fermat \(\Delta_{Fer}\), uma grandeza macroscópica que mede a distância entre dois pontos em uma variedade neste contexto, e a distância amostral de Fermat \(\hat{\Delta}_{Fer}\), como um estimador de \(\Delta_{Fer}\).

Exemplo 10.3 Da documentação de fermatdistance::fermat_dist().

library(fermatdistance)

n <- 100
d <- 2
X <- matrix(rnorm(n*d), nrow=n, ncol=d)
fd <- fermat_dist(X, "full", alpha = 1)
landmark_fd <- fermat_dist(X, "landmarks", alpha = 2, landmarks_frac = 0.1)
knn_fd <- fermat_dist(X, "knn", alpha = 2)
# lib
# renv::install("diegobatt/fermat-distance")

library(fermatdistance)

# Sample data (replace with your actual data)
X <- matrix(rnorm(100*2), ncol = 2) 

# Compute full Fermat distance matrix
fd_full <- fermat_dist(X, "full", alpha = 1) 

# Compute Fermat distance using landmarks approximation
fd_landmarks <- fermat_dist(X, "landmarks", alpha = 2, landmarks_frac = 0.1)

# Compute Fermat distance using k-nearest neighbors approximation
fd_knn <- fermat_dist(X, "knn", alpha = 2)

References

Groisman, Pablo, Matthieu Jonckheere, and Facundo Sapienza. 2022. “Nonhomogeneous Euclidean First-Passage Percolation and Distance Learning.” Bernoulli 28 (1): 255–76. https://doi.org/10.3150/21-BEJ1341.
Wild, Fridolin. 2022. Lsa: Latent Semantic Analysis. https://doi.org/10.32614/CRAN.package.lsa.