サンプルの尖度は絶望的に偏っていますか?


8

かなり歪んだ確率変数の尖度のサンプルを調べていますが、結果に一貫性がないようです。問題を簡単に説明するために、対数正規RVのサンプル尖度を調べました。R(私はゆっくりと学習しています):

library(moments); 

samp_size = 2048;
n_trial = 4096;

kvals <- rep(NA,1,n_trial); #preallocate
for (iii in 1:n_trial) {
    kvals[iii] <- kurtosis(exp(rnorm(samp_size)));
}
print(summary(kvals));

私が得る要約は

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  11.87   28.66   39.32   59.17   61.70 1302.00 

Wikipediaによると、この対数正規RVの尖度は約114であるはずです。明らかに、サンプルの尖度は偏っています。

いくつかの調査を行ったところ、サンプルの尖度はサンプルサイズが小さいと偏っていることがわかりました。e1071CRAN のパッケージで提供される「G2」推定量を使用して、このサンプルサイズで非常に類似した結果を得ました。

質問:次のどれが起こっているのかを特徴づけます:

  1. サンプルの尖度の標準誤差は、このRVの場合は非常に大きくなります(標準的な誤差の一般的な推定値は)。または、この研究では使用したサンプルが少なすぎます(2048)。1/n
  2. サンプルの尖度のこれらの実装は、たとえば Terriberryの方法(Welfordの方法がサンプルの分散の単純な方法よりも優れた結果を与えるのとほぼ同じ方法)によって修正される可能性がある数値の問題に悩まされています。
  3. 人口尖度を誤って計算しました。(痛い)
  4. サンプルの尖度は本質的にバイアスされており、このような小さなサンプルサイズでは修正できません。

ところで、私はRの初心者なので、スタイルと内容の両方の点で、私のコードに関するどんな短いコメントでも感謝します。特に、forループをよりエレガントな方法で表現できることを望んでいました。
shabbychef 2010

1
Rスタイルで;は、ステートメントの終わりに必要はありません。あなたは事前に割り当てることは右なかった、しかしで埋めるために必要NAkvals <- numeric(length = n_trial)足りているだろう。を使用するとrep、呼び出しからの引数1と3のみが必要になります(例:)rep(NA, 10)。ではforループセットアップ、1:n_trialプログラミングあれば危険なことができます。優れているseq_along(kvals)か、seq_len(n_trial)この場合には 最後に、印刷を強制する必要がない場合は、print()ラウンドをドロップしsummary()ます。R。HTHと対話的に作業していない場合にのみ、ラウンドを必要とします。
Gavin Simpson、

ありがとう!間違いなく私が探していたもの。これをファイルから実行していたため、が必要でしたprint。への議論repは確かに誤りでした。
shabbychef 2010

回答:


6

バイアス補正があります。それは巨大ではありません。尖度の標本分散は8番目の中心モーメント(!)に比例し、対数正規分布では非常に大きくなると思います。CVが小さい場合を除き、バイアスを検出するにはシミュレーションで数百万回(またはそれ以上)の試行が必要になります。(kvalのヒストグラムをプロットして、それらがどの程度異常に歪んでいるかを確認します。)

正しい尖度は確かに約113.9364です。

Rスタイルに関する限り、シミュレーションを関数にカプセル化すると、サンプルサイズや試行回数を簡単に変更できるので便利です。


2
からのG2推定量e1071は、「標準」のバイアス補正を提供します。cran.r-project.org/web/packages/e1071/e1071.pdfを参照してください。momentsパッケージで実装されているg2の代わりにこの推定量を使用しても、Qで指摘したようにほとんど効果がありませんでした。
shabbychef 2010

5

[Rスタイルのみ-@whuberがカートシスQに回答しました]

これは少し複雑すぎてコメントを付けられません。使用するような単純なループの場合、シミュレーションを関数にカプセル化するという@whuberの提案を関数と組み合わせることができreplicate()ます。replicate()割り当てを処理し、ループを実行します。以下に例を示します。

require(moments)
foo <- function(size, trials, meanlog = 0, sdlog = 1) {
    replicate(trials,
              kurtosis(rlnorm(size, meanlog = meanlog, 
                              sdlog = sdlog)))
}

次のように使用します。

> set.seed(1)
> out <- foo(2048, 10000)
> summary(out)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.93   28.77   39.99   62.53   62.58 1557.00

このrlnorm()関数を使用して対数正規確率変数を生成していることに注意してください。これはexp(rnorm())ループ内と同じですが、正しいツールを使用しており、ユーザーが指定した対数正規分布のパラメーターを関数に渡すことができます。

> set.seed(123)
> exp(rnorm(1))
[1] 0.5709374
> set.seed(123)
> rlnorm(1)
[1] 0.5709374

+1 for set.seed、これはこのような例に役立ちます。関数にカプセル化する実質的な理由はありますか(たとえば、Rインタープリターは関数をプリコンパイルするため、速度が向上します)、またはスタイルがあります(たとえば、ブロッコリーなどの関数をカプセル化するのが良いでしょう)、またはその中間(たとえば、Rには関数に作用する演算子がたくさんあるので、関数型プログラミングに慣れる必要があります)。
shabbychef 2010

@shabbychef:主なものは努力だと思います。ループなどでコードを繰り返し実行することもできますが、問題はありませんが、コードのすべての行を実行し続ける必要があります。カプセル化することで、実行するシミュレーションごとに1行のRコードを実行します。Rは事前にIIRCをコンパイルしないため、速度は向上しません。
Gavin Simpson

1
説明をありがとう。これはすべて小さなファイルなので、とにかく1行です。source('foo.r');)
shabbychef
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.