Mise à jour : 7 avril 2011 Cette réponse devient assez longue et couvre plusieurs aspects du problème à résoudre. Cependant, j'ai résisté, jusqu'à présent, à le diviser en réponses distinctes.
J'ai ajouté tout en bas une discussion sur les performances du de Pearson pour cet exemple.χ2
Bruce M. Hill est peut-être l'auteur de l'article «fondateur» sur l'estimation dans un contexte de type Zipf. Il a écrit plusieurs articles au milieu des années 70 sur le sujet. Cependant, «l'estimateur de Hill» (comme il s'appelle maintenant) s'appuie essentiellement sur les statistiques d'ordre maximal de l'échantillon et ainsi, selon le type de troncature présent, cela pourrait vous causer des ennuis.
Le document principal est:
BM Hill, Une approche générale simple de l'inférence sur la queue d'une distribution , Ann. Stat. , 1975.
Si vos données sont vraiment initialement Zipf et sont ensuite tronquées, une belle correspondance entre la distribution des degrés et le tracé Zipf peut être exploitée à votre avantage.
Plus précisément, la distribution des degrés est simplement la distribution empirique du nombre de fois que chaque réponse entière est vue,
di=#{j:Xj=i}n.
Si nous traçons ceci contre sur un tracé log-log, nous obtiendrons une tendance linéaire avec une pente correspondant au coefficient d'échelle.i
D'un autre côté, si nous traçons le tracé Zipf , où nous trions l'échantillon du plus grand au plus petit, puis traçons les valeurs en fonction de leurs rangs, nous obtenons une tendance linéaire différente avec une pente différente . Cependant les pentes sont liées.
Si est le coefficient de loi d'échelle pour la distribution Zipf, alors la pente dans le premier tracé est et la pente dans le deuxième tracé est . Vous trouverez ci-dessous un exemple de tracé pour et . Le volet de gauche est la distribution des degrés et la pente de la ligne rouge est . Le côté droit est le tracé Zipf, avec la ligne rouge superposée ayant une pente de .- α - 1 / ( α - 1 ) α = 2 n = 10 6 - 2 - 1 / ( 2 - 1 ) = - 1α−α−1/(α−1)α=2n=106−2−1/(2−1)=−1
Donc, si vos données ont été tronquées de sorte que vous ne voyez aucune valeur supérieure à un certain seuil , mais que les données sont autrement distribuées par Zipf et que est raisonnablement grande, alors vous pouvez estimer partir de la distribution des degrés . Une approche très simple consiste à ajuster une ligne au tracé log-log et à utiliser le coefficient correspondant.τ αττα
Si vos données sont tronquées de sorte que vous ne voyez pas de petites valeurs (par exemple, la façon dont le filtrage est effectué pour les grands ensembles de données Web), vous pouvez utiliser le tracé Zipf pour estimer la pente sur une échelle log-log puis " reculer "l'exposant de mise à l'échelle. Supposons que votre estimation de la pente à partir du tracé Zipf soit . Ensuite, une simple estimation du coefficient de la loi d'échelle est
alpha =une-uneβ^
α^=1−1β^.
@csgillespie a donné un article récent co-écrit par Mark Newman au Michigan sur ce sujet. Il semble publier beaucoup d'articles similaires à ce sujet. Ci-dessous est un autre avec quelques autres références qui pourraient être intéressantes. Newman ne fait parfois pas la chose la plus sensée statistiquement, alors soyez prudent.
MEJ Newman, Power lois, distributions de Pareto et loi de Zipf , Contemporary Physics 46, 2005, pp. 323-351.
M. Mitzenmacher, A Brief History of Generative Models for Power Law and Lognormal Distributions , Internet Math. , vol. 1, non. 2, 2003, p. 226-251.
K. Knight, Une simple modification de l'estimateur de Hill avec des applications à la robustesse et à la réduction du biais , 2010.
Addendum :
Voici une simulation simple dans pour démontrer ce à quoi vous pourriez vous attendre si vous preniez un échantillon de taille dans votre distribution (comme décrit dans votre commentaire ci-dessous votre question d'origine).10 5R105
> x <- (1:500)^(-0.9)
> p <- x / sum(x)
> y <- sample(length(p), size=100000, repl=TRUE, prob=p)
> tab <- table(y)
> plot( 1:500, tab/sum(tab), log="xy", pch=20,
main="'Truncated' Zipf simulation (truncated at i=500)",
xlab="Response", ylab="Probability" )
> lines(p, col="red", lwd=2)
Le tracé résultant est
De l'intrigue, nous pouvons voir que l'erreur relative de la distribution des degrés pour (ou ainsi) est très bonne. Vous pouvez faire un test chi carré formel, mais cela ne vous dit pas strictement que les données suivent la distribution prédéfinie. Il vous indique seulement que vous n'avez aucune preuve pour conclure que non .i≤30
Pourtant, d'un point de vue pratique, une telle intrigue devrait être relativement convaincante.
Addendum 2 : Considérons l'exemple que Maurizio utilise dans ses commentaires ci-dessous. Nous supposerons que et , avec une distribution Zipf tronquée ayant une valeur maximale .n = 300α=2x m a x = 500n=300000xmax=500
Nous allons calculer la statistique Pearson de deux manières. La méthode standard est via la statistique
où est le nombre observé de la valeur dans l'échantillon et .X 2 = 500 ∑ i = 1 ( O i - E i ) 2χ2 OiiEi=npi=ni-α/∑ 500 j = 1 j-α
X2=∑i=1500(Oi−Ei)2Ei
OiiEi=npi=ni−α/∑500j=1j−α
Nous calculerons également une deuxième statistique formée en regroupant d'abord les nombres dans des bacs de taille 40, comme indiqué dans la feuille de calcul de Maurizio (le dernier bac ne contient que la somme de vingt valeurs de résultat distinctes.
Tirons 5000 échantillons distincts de taille de cette distribution et calculons les valeurs utilisant ces deux statistiques différentes.pnp
Les histogrammes des valeurs sont ci-dessous et sont considérés comme assez uniformes. Les taux d'erreur empiriques de type I sont respectivement de 0,0716 (méthode standard non combinée) et 0,0502 (méthode combinée) et aucun n'est statistiquement significativement différent de la valeur cible de 0,05 pour la taille d'échantillon de 5000 que nous avons choisie.p
Voici le codeR
# Chi-square testing of the truncated Zipf.
a <- 2
n <- 300000
xmax <- 500
nreps <- 5000
zipf.chisq.test <- function(n, a=0.9, xmax=500, bin.size = 40)
{
# Make the probability vector
x <- (1:xmax)^(-a)
p <- x / sum(x)
# Do the sampling
y <- sample(length(p), size=n, repl=TRUE, prob=p)
# Use tabulate, NOT table!
tab <- tabulate(y,xmax)
# unbinned chi-square stat and p-value
discrepancy <- (tab-n*p)^2/(n*p)
chi.stat <- sum(discrepancy)
p.val <- pchisq(chi.stat, df=xmax-1, lower.tail = FALSE)
# binned chi-square stat and p-value
bins <- seq(bin.size,xmax,by=bin.size)
if( bins[length(bins)] != xmax )
bins <- c(bins, xmax)
tab.bin <- cumsum(tab)[bins]
tab.bin <- c(tab.bin[1], diff(tab.bin))
prob.bin <- cumsum(p)[bins]
prob.bin <- c(prob.bin[1], diff(prob.bin))
disc.bin <- (tab.bin - n*prob.bin)^2/(n * prob.bin)
chi.stat.bin <- sum(disc.bin)
p.val.bin <- pchisq(chi.stat.bin, df=length(tab.bin)-1, lower.tail = FALSE)
# Return the binned and unbineed p-values
c(p.val, p.val.bin, chi.stat, chi.stat.bin)
}
set.seed( .Random.seed[2] )
all <- replicate(nreps, zipf.chisq.test(n, a, xmax))
par(mfrow=c(2,1))
hist( all[1,], breaks=20, col="darkgrey", border="white",
main="Histogram of unbinned chi-square p-values", xlab="p-value")
hist( all[2,], breaks=20, col="darkgrey", border="white",
main="Histogram of binned chi-square p-values", xlab="p-value" )
type.one.error <- rowMeans( all[1:2,] < 0.05 )