关于您的论文要求,有:
这不是您要找的东西,但可能会成为工厂的要点。
似乎没有人提到过另一种策略。可以从大小为的集合中生成(伪)随机数据,以便整个集合满足约束,只要剩余的数据固定为适当的值即可。所需的值应该可以由方程,代数和一些肘部润滑脂组成的系统求解。 N−kNkkk
例如,要从将具有给定样本均值和方差的正态分布生成一组数据,则需要固定两个点的值:和。由于样本均值是:必须为:
样本方差为:
因此(在将替换为,挫败/分发和重新排列... ),我们得到:
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
如果我们取,则和作为RHS的取反,我们可以使用
二次公式来求解。例如,在中,可以使用以下代码:
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
关于这种方法,有些事情要理解。首先,不能保证它能正常工作。例如,您的初始数据可能不存在值和,这将使结果集的方差等于。考虑: N−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
其次,尽管标准化使您所有变量的边际分布更加均匀,但是此方法仅影响最后两个值,但使它们的边际分布偏斜:
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
}
第三,结果样本看起来可能不太正常。看起来好像有“异常值”(即,点来自与其余数据不同的数据生成过程),因为实际上是这种情况。对于较大的样本量,这不太可能出现问题,因为来自生成数据的样本统计信息应收敛到所需值,因此需要较少的调整。对于较小的样本,您始终可以将此方法与接受/拒绝算法结合使用,该算法会再次尝试生成的样本具有超出可接受范围(例如,@ cardinal的注释)的形状统计信息(例如,偏斜度和峰度),或者扩展这种方法可以生成均值,方差,偏度和峰度(不过,我将代数交给您)。或者,您可以生成少量样本,并使用具有最小(例如)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