简体   繁体   中英

all.moments function weird outcome

I want to calculate the n-th moment of a distribution. I am trying to using all.moments function of library 'moments' in R. I have tested all.moments in this way:

 library(moments)
 r<-rnorm(10000)
 rr<-all.moments(r,order.max=4)
 rr

 [1]  1.000000000  0.002403360  0.962201478 -0.022694670  2.852696159

This seems to me that it's not true, cause i know that the 3-th and 4-th moment must be 0 in a normal distribution. Where is my mistake?

The third moment is the skewness . You are correct: for a normal distribution this is zero. Since you are only sampling from a normal distribution, your results will be approximately zero, which it is.

The fourth order moment is the kurtosis . For a normal distribution this is 3σ^4. In this case, σ is 1, so your result should be 3, which it is.


To improve the accuracy of your estimate, improve the sample size. For a sample of 1e7 observations:

> library(moments)
> r <- rnorm(1e7)
> all.moments(r,order.max=4)
[1] 1.0000000000 0.0004028138 0.9995373115 0.0007276404 2.9976881271

Because that's only true in expectation and not precisely, and because the higher moments have large variances?

(See @Andrie's answer as well, for why the fourth moment ( V5 below) is not even close to zero.)

> library(moments)
> R <- t(replicate(50,all.moments(rnorm(1e4),order.max=4)))
> summary(R)
       V1          V2                  V3               V4            
 Min.   :1   Min.   :-0.024921   Min.   :0.9714   Min.   :-0.0987174  
 1st Qu.:1   1st Qu.:-0.009527   1st Qu.:0.9911   1st Qu.:-0.0341950  
 Median :1   Median : 0.001021   Median :0.9994   Median : 0.0067138  
 Mean   :1   Mean   :-0.001047   Mean   :1.0006   Mean   :-0.0002613  
 3rd Qu.:1   3rd Qu.: 0.004711   3rd Qu.:1.0147   3rd Qu.: 0.0299731  
 Max.   :1   Max.   : 0.023356   Max.   :1.0398   Max.   : 0.1283456  
       V5       
 Min.   :2.775  
 1st Qu.:2.921  
 Median :3.005  
 Mean   :3.007  
 3rd Qu.:3.092  
 Max.   :3.325  

I got the same problem, working in python, and I think that the limited precision of floating point arithmetic on a computer, esp. with powers of large numbers, is also not helping. I'll cut and paste my Python code and the results I get. This code tries to compute the first 20 moments of a standard normal. In short, I think it's not easy to compute high order moments of a distribution numerically, "high order" meaning here greater than 10 or so. In a separate experiment, I tried to reduce the variance I get on the 18th moment by drawing more and more samples, but that wasn't practical either given my "ordinary" computer.

N = 1000000
w = np.random.normal(size=N).astype("float128")

for i in range(20):
    print i, mean(w**i) # simply computing the mean of the data to the power of i

Gives you:

0 1.0
1 0.000342014729693
2 1.00124397377
3 0.000140133725668
4 3.00334304532
5 0.00506625342217
6 15.0227401941
7 0.0238395446636
8 105.310071549
9 -0.803915389936
10 948.126995798
11 -34.8374820713
12 10370.6527554
13 -1013.23231638
14 132288.117911
15 -26403.9090218
16 1905267.02257
17 -658590.680295
18 30190439.4783
19 -16101299.7354

But the correct moments are: 1, 0, 1, 0, 3, 0, 15, 0, 105, 0, 945, 0, 10395, 0, 135135, 0, 2027025, 0, 34459425, 0, 654729075.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM