A questão de "significativamente" diferente sempre, sempre pressupõe um modelo estatístico para os dados. Esta resposta propõe um dos modelos mais gerais que é consistente com as informações mínimas fornecidas na pergunta. Em resumo, ele funcionará em uma ampla variedade de casos, mas nem sempre pode ser a maneira mais poderosa de detectar uma diferença.
Três aspectos dos dados são realmente importantes: a forma do espaço ocupado pelos pontos; a distribuição dos pontos dentro desse espaço; e o gráfico formado pelos pares de pontos com a "condição" - que chamarei de grupo "tratamento". Por "gráfico", quero dizer o padrão de pontos e interconexões implícitos pelos pares de pontos no grupo de tratamento. Por exemplo, dez pares de pontos ("arestas") do gráfico podem envolver até 20 pontos distintos ou até cinco pontos. No primeiro caso, duas arestas não compartilham um ponto em comum, enquanto no último caso as arestas consistem em todos os pares possíveis entre cinco pontos.
n = 3000σ( vEu, vj)( vσ( I ), vσ( J ))3000 ! ≈ 1021024permutações. Nesse caso, sua distância média deve ser comparável às distâncias médias que aparecem nessas permutações. Podemos facilmente estimar a distribuição dessas distâncias médias aleatórias amostrando alguns milhares de todas essas permutações.
(Vale ressaltar que essa abordagem funcionará, com apenas pequenas modificações, com qualquer distância ou qualquer quantidade que esteja associada a todos os pares de pontos possíveis. Também funcionará para qualquer resumo das distâncias, e não apenas a média.)
Para ilustrar, aqui estão duas situações envolvendo pontos e arestas em um grupo de tratamento. Na linha superior, os primeiros pontos em cada aresta foram escolhidos aleatoriamente entre os pontos e, em seguida, os segundos pontos de cada aresta foram escolhidos de forma independente e aleatória entre os pontos diferentes de seu primeiro ponto. No total, pontos estão envolvidos nessas arestas.n = 10028.100100 - 139.28.
Na linha inferior, oito dos pontos foram escolhidos aleatoriamente. As arestas consistem em todos os pares possíveis.10028.
Os histogramas à direita mostram as distribuições de amostragem para permutações aleatórias das configurações. As distâncias médias reais dos dados são marcadas com linhas vermelhas tracejadas verticais. Ambos os meios são consistentes com as distribuições de amostragem: nenhuma fica muito à direita ou à esquerda.10000
As distribuições amostrais diferem: embora, em média, as distâncias médias sejam as mesmas, a variação na distância média é maior no segundo caso, devido às interdependências gráficas entre as arestas. Essa é uma das razões pelas quais nenhuma versão simples do Teorema do Limite Central pode ser usada: calcular o desvio padrão dessa distribuição é difícil.
n = 30001500
56.
Geralmente, a proporção de distâncias médias de tanto a simulação e o grupo de tratamento que são iguais ou maiores do que a distância média no grupo de tratamento pode ser tomada como o valor de p deste teste não paramétrico de permutação.
Este é o R
código usado para criar as ilustrações.
n.vectors <- 3000
n.condition <- 1500
d <- 2 # Dimension of the space
n.sim <- 1e4 # Number of iterations
set.seed(17)
par(mfrow=c(2, 2))
#
# Construct a dataset like the actual one.
#
# `m` indexes the pairs of vectors with a "condition."
# `x` contains the coordinates of all vectors.
x <- matrix(runif(d*n.vectors), nrow=d)
x <- x[, order(x[1, ]+x[2, ])]
#
# Create two kinds of conditions and analyze each.
#
for (independent in c(TRUE, FALSE)) {
if (independent) {
i <- sample.int(n.vectors, n.condition)
j <- sample.int(n.vectors-1, n.condition)
j <- (i + j - 1) %% n.condition + 1
m <- cbind(i,j)
} else {
u <- floor(sqrt(2*n.condition))
v <- ceiling(2*n.condition/u)
m <- as.matrix(expand.grid(1:u, 1:v))
m <- m[m[,1] < m[,2], ]
}
#
# Plot the configuration.
#
plot(t(x), pch=19, cex=0.5, col="Gray", asp=1, bty="n",
main="The Data", xlab="X", ylab="Y",
sub=paste(length(unique(as.vector(m))), "points"))
invisible(apply(m, 1, function(i) lines(t(x[, i]), col="#80000040")))
points(t(x[, unique(as.vector(m))]), pch=16, col="Red", cex=0.6)
#
# Precompute all distances between all points.
#
distances <- sapply(1:n.vectors, function(i) sqrt(colSums((x-x[,i])^2)))
#
# Compute the mean distance in any set of pairs.
#
mean.distance <- function(m, distances)
mean(distances[m])
#
# Sample from the points using the same *pattern* in the "condition."
# `m` is a two-column array pairing indexes between 1 and `n` inclusive.
sample.graph <- function(m, n) {
n.permuted <- sample.int(n, n)
cbind(n.permuted[m[,1]], n.permuted[m[,2]])
}
#
# Simulate the sampling distribution of mean distances for randomly chosen
# subsets of a specified size.
#
system.time(
sim <- replicate(n.sim, mean.distance(sample.graph(m, n.vectors), distances))
stat <- mean.distance(m, distances)
p.value <- 2 * min(mean(c(sim, stat) <= stat), mean(c(sim, stat) >= stat))
hist(sim, freq=FALSE,
sub=paste("p-value:", signif(p.value, ceiling(log10(length(sim))/2)+1)),
main="Histogram of mean distances", xlab="Distance")
abline(v = stat, lwd=2, lty=3, col="Red")
}