En ce qui concerne votre demande de papiers, il y a:
Ce n’est pas tout à fait ce que vous cherchez, mais pourrait servir à abreuver le moulin.
Il y a une autre stratégie que personne ne semble avoir mentionnée. Il est possible de générer (pseudo) données aléatoires à partir d'un ensemble de taille sorte qu'un ensemble complet respecte contraintes, pour autant que les données restantes soient fixées à des valeurs appropriées. Les valeurs requises doivent pouvoir être résolues avec un système d' équations , d'algèbre et de graisse pour coudes. N−kNkkk
Par exemple, pour générer un ensemble de données à partir d'une distribution normale qui aura une moyenne d'échantillon donnée, , et une variance, , vous devrez fixer les valeurs de deux points: et . Étant donné que la moyenne de l'échantillon est: doit être:
L'écart exemple est:
ainsi (après avoir remplacé ce qui précède par , déjouant / distribuant, et réarrangeant ... ) on a:
Nx¯s2yz
x¯=∑N−2i=1xi+y+zN
yy=Nx¯−(∑i=1N−2xi+z)
s2=∑N−2i=1(xi−x¯)2+(y−x¯)2+(z−x¯)2N−1
y2(Nx¯−∑i=1N−2xi)z−2z2=Nx¯2(N−1)+∑i=1N−2x2i+[∑i=1N−2xi]2−2Nx¯∑i=1N−2xi−(N−1)s2
Si nous prenons , , et comme négation de RHS, nous pouvons résoudre pour utilisant la
formule quadratique . Par exemple, dans , le code suivant pourrait être utilisé:
a=−2b=2(Nx¯−∑N−2i=1xi)czR
find.yz = function(x, xbar, s2){
N = length(x) + 2
sumx = sum(x)
sx2 = as.numeric(x%*%x) # this is the sum of x^2
a = -2
b = 2*(N*xbar - sumx)
c = -N*xbar^2*(N-1) - sx2 - sumx^2 + 2*N*xbar*sumx + (N-1)*s2
rt = sqrt(b^2 - 4*a*c)
z = (-b + rt)/(2*a)
y = N*xbar - (sumx + z)
newx = c(x, y, z)
return(newx)
}
set.seed(62)
x = rnorm(2)
newx = find.yz(x, xbar=0, s2=1)
newx # [1] 0.8012701 0.2844567 0.3757358 -1.4614627
mean(newx) # [1] 0
var(newx) # [1] 1
Il y a certaines choses à comprendre à propos de cette approche. Tout d'abord, il n'est pas garanti de fonctionner. Par exemple, il est possible que vos données initiales soient telles qu'il n'existe pas de valeurs et rendant la variance de l'ensemble résultant égale à . Considérer: y z s 2N−2yzs2
set.seed(22)
x = rnorm(2)
newx = find.yz(x, xbar=0, s2=1)
Warning message:
In sqrt(b^2 - 4 * a * c) : NaNs produced
newx # [1] -0.5121391 2.4851837 NaN NaN
var(c(x, mean(x), mean(x))) # [1] 1.497324
Deuxièmement, alors que la standardisation uniformise les distributions marginales de toutes vos variables, cette approche n’affecte que les deux dernières valeurs, mais rend leurs distributions marginales faussées:
set.seed(82)
xScaled = matrix(NA, ncol=4, nrow=10000)
for(i in 1:10000){
x = rnorm(4)
xScaled[i,] = scale(x)
}
set.seed(82)
xDf = matrix(NA, ncol=4, nrow=10000)
i = 1
while(i<10001){
x = rnorm(2)
xDf[i,] = try(find.yz(x, xbar=0, s2=2), silent=TRUE) # keeps the code from crashing
if(!is.nan(xDf[i,4])){ i = i+1 } # increments if worked
}
Troisièmement, l'échantillon résultant peut ne pas sembler très normal; il peut sembler qu'il a des «valeurs aberrantes» (c'est-à-dire des points qui proviennent d'un processus de génération de données différent du reste), car c'est essentiellement le cas. Ceci est moins susceptible de poser problème avec des tailles d'échantillon plus grandes, car les statistiques d'échantillon à partir des données générées doivent converger vers les valeurs requises et nécessitent par conséquent moins d'ajustement. Avec des échantillons plus petits, vous pouvez toujours combiner cette approche avec un algorithme d'acceptation / rejet qui tente à nouveau si l'échantillon généré a des statistiques de forme (par exemple, asymétrie et kurtosis) qui sont en dehors des limites acceptables (cf., commentaire de @ cardinal ), ou étendent cette approche pour générer un échantillon avec une moyenne, une variance, une asymétrie etkurtosis (je laisserai cependant l'algèbre à vous). Alternativement, vous pouvez générer un petit nombre d’échantillons et utiliser celui qui contient la statistique la plus petite (disons) de Kolmogorov-Smirnov.
library(moments)
set.seed(7900)
x = rnorm(18)
newx.ss7900 = find.yz(x, xbar=0, s2=1)
skewness(newx.ss7900) # [1] 1.832733
kurtosis(newx.ss7900) - 3 # [1] 4.334414
ks.test(newx.ss7900, "pnorm")$statistic # 0.1934226
set.seed(200)
x = rnorm(18)
newx.ss200 = find.yz(x, xbar=0, s2=1)
skewness(newx.ss200) # [1] 0.137446
kurtosis(newx.ss200) - 3 # [1] 0.1148834
ks.test(newx.ss200, "pnorm")$statistic # 0.1326304
set.seed(4700)
x = rnorm(18)
newx.ss4700 = find.yz(x, xbar=0, s2=1)
skewness(newx.ss4700) # [1] 0.3258491
kurtosis(newx.ss4700) - 3 # [1] -0.02997377
ks.test(newx.ss4700, "pnorm")$statistic # 0.07707929S