2012-02-20 18 views
4

C#で安定した分布を持つ乱数を生成する方法は? ランダムクラスには一様分布があります。 インターネット上の他の多くのコードは正規分布を示しています。しかし、我々は無限分散、a.k.a太い尾の分布を意味する安定した分布 を必要とする。安定した分布乱数?

理由は現実的な株価を生成するためです。実際の 世界では、通常のディストリビューションの よりもはるかに大きな価格変動があります。

誰かがランダムなクラス出力 を安定した配布に変換するC#コードを知っていますか?

編集:Hmmm。正確な分布は、少なくとも20シグマのような巨大なシグマをランダムに生成することを保証するよりも重要ではありません。株価がどのように振る舞うかを真の裾野の分布で反発力のためのトレーディング戦略をテストしたい。

私はちょうどコメントのためにZipFianとCauchyについて読んでいます。私が選ぶ必要があるので、Cauchyのディストリビューションに行きましょう。でも私はZipFianを試して比較します。

+0

ウィキペディアは、安定した意味についてのあなたの説明に同意しません:http://en.wikipedia.org/wiki/Stable_distributionたとえば、「正規分布は安定した分布の一家族です」と言います。 –

+3

あなたは必要な正確な分布の数学的定義を見つける必要があると思います(@Davidが言ったように、おそらく別の名前が必要です)。そして独自の関数を実装して、必要なものに一様分布を変換します。 – Zruty

+0

上では基本的な数学を学ぶことができます。フィッシャー変換(インジケータ)はガウス正規化を行います。逆のことです。 Bascialylは0-100の数値を得るために、より大きなランダムな空間(0-1000)をとり、0から離れた数に大きな領域を割り当てます。これは実際には一様分布の「ガウス化」であり、定量的なものに取り組んでいるプログラムに尋ねる質問のうちの1つです)統計情報101を知っていることを確認するには – TomTom

答えて

6

一般に、この方法は:

  • が安定し、脂肪テール分布を選択します。 Cauchyの分布を言います。

  • 選択した分布の分位関数をルックアップします。

コーシー分布の場合、これはp --> peak + scale * tan(pi * (p - 0.5))です。

  • ここで、一様分布乱数をコーシー分布乱数に変換する方法があります。

意味がありますか?詳細については、

http://en.wikipedia.org/wiki/Inverse_transform_sampling

を参照してください。

警告:私は統計を取って以来、長い時間がかかりました。

UPDATE:

私はそんなに私はちょうどそれをブログでこの質問を気に入っ:

http://blogs.msdn.com/b/ericlippert/archive/2010/12/07/10100227.aspx

:Zipfian分布のいくつかの興味深い例を模索マイ記事はここにある

http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/

を見ます

+0

これは、ほとんどのディストリビューションで役立ちます。さて、正規分布については、それは別の話です! –

1

Zipfianディストリビューションの使用に興味がある場合はこれはちょうどある(分布

  • 事前計算累積分布のドメインのためのあなたのk(スキュー)を選択し

    1. :科学や社会のドメイン)からのプロセスをモデル化するとき、あなたはの線に沿って何かをするだろう使用

      List<int> domain = Enumerable.Range(0,1000); // generate your domain 
      double skew = 0.37; // select a skew appropriate to your domain 
      double sigma = domain.Aggregate(0.0d, (z,x) => x + 1.0/Math.Pow(z+1, skew)); 
      List<double> cummDist = domain.Select( 
           x => domain.Aggregate(0.0d, (z,y) => z + 1.0/Math.Pow(y, skew) * sigma)); 
      
      :最適化)
    2. は、ドメイン

    サンプルコードから最も近い値を見つけることによって、配布用の乱数値を生成します

    今、あなたはドメイン内から最も近い値を選択することで、ランダムな値を生成することができます

    Random rand = new Random(); 
    double seek = rand.NextDouble(); 
    int searchIndex = cummDist.BinarySearch(seek); 
    // return the index of the closest value from the distribution domain 
    return searchIndex < 0 ? (~searchIndex)-1 : searchIndex-1; 
    

    あなたは、もちろん、から分布のドメインを実体化ロジックを因数分解することによって、このプロセス全体を一般化することができますそのドメインからの値をマップして返します。

  • +0

    あなたの優雅なコードに感心し、値の事前計算の最適化を掘り下げます。それを時系列株価に変換する手掛かりはありますか? – Wayne

    +0

    Cauchyは株価乱数に適しているようです。あなたは同意しますか?私は両方を試し、どちらがよさそうだか見てみましょう。 – Wayne

    +0

    @Wayne:株価の変動をより正確にモデル化しているディストリビューションを提案するために、より賢く、より多くの経験を積んでいます。金融市場をモデリングすることについては、大きな論点があります(Wikipediaには、氷山http://en.wikipedia.org/wiki/Modeling_and_analysis_of_financial_marketsのちょっとしたヒントがあります)。結局のところ、あなたのシミュレーションで最も重要なことに応じて、どの分布が最も適切かという質問に答えられるのはあなただけかもしれません。 – LBushkin

    0

    私の前に、このトピックのJames GentleのSpringerのボリュームRandom Number Generation and Monte Carlo Methods、私の統計学者の妻の礼儀があります。

    安定したファミリの分布は、一般的にヘビーテール分布の柔軟なファミリです。このファミリには、パラメータの1つの極値に正規分布が含まれ、その他の極値にCauchyが含まれます。 Chambers、Mallows、Stuck(1976)は、安定した分布からの逸脱を生成する方法を提供する。 ((x -1)/ xを評価するために、補助関数D2の定数のいくつかのエラーを見てください。)それらのメソッドはIMSLライブラリで使用されます。対称安定分布の場合、Devroye(1986)はFejer-de la Vallee Poissin分布に対する対称安定性の関係を利用することにより、より高速な方法を開発できることを指摘している。 Buckle(1995)は、安定した分布のパラメータをデータ上で条件付きでシミュレートする方法を示します。

    ジェネリックな安定したディストリビューションからの逸脱は難しいです。これを行う必要がある場合は、IMSLなどのライブラリをお勧めします。私はあなた自身でこれを試みることを勧めません。

    ただし、安定したファミリの特定のディストリビューションを探している場合は、 Cauchyの場合、probability integral transformというEricの記述方法を使用できます。分布関数の逆関数を閉じた形で書くことができれば、このアプローチを使うことができます。

    0

    次のC#コードは、形状パラメータalphaおよびbetaが与えられた安定した分布に従う乱数を生成します。クリエイティブ・コモンズ・ゼロの下でパブリック・ドメインに公開します。また

    public static double StableDist(Random rand, double alpha, double beta){ 
        if(alpha<=0 || alpha>2 || beta<-1 || beta>1) 
         throw new ArgumentException(); 
        var halfpi=Math.PI*0.5; 
        var unif=NextDouble(rand); 
        while(unif == 0.0)unif=NextDouble(rand); 
        unif=(unif - 0.5) * Math.PI; 
        // Cauchy special case 
        if(alpha==1 && beta==0) 
         return Math.Tan(unif); 
        var expo=-Math.Log(1.0 - NextDouble(rand)); 
        var c=Math.Cos(unif); 
        if(alpha == 1){ 
         var s=Math.Sin(unif); 
         return 2.0*((unif*beta+halfpi)*s/c - 
          beta * Math.Log(halfpi*expo*c/(
           unif*beta+halfpi)))/Math.PI; 
        } 
        var z=-Math.Tan(halfpi*alpha)*beta; 
        var ug=unif+Math.Atan(-z)/alpha; 
        var cpow=Math.Pow(c, -1.0/alpha); 
        return Math.Pow(1.0+z*z, 1.0/(2*alpha))* 
         (Math.Sin(alpha*ug)*cpow)* 
         Math.Pow(Math.Cos(unif-alpha*ug)/expo, (1.0-alpha)/alpha); 
    } 
    
    private static double NextDouble(Random rand){ 
        // The default NextDouble implementation in .NET (see 
        // https://github.com/dotnet/corert/blob/master/src/System.Private.CoreLib/shared/System/Random.cs) 
        // is very problematic: 
        // - It generates a random number 0 or greater and less than 2^31-1 in a 
        // way that very slightly biases 2^31-2. 
        // - Then it divides that number by 2^31-1. 
        // - The result is a number that uses roughly only 32 bits of pseudorandomness, 
        // even though `double` has 53 bits in its significand. 
        // To alleviate some of these problems, this method generates a random 53-bit 
        // random number and divides that by 2^53. Although this doesn't fix the bias 
        // mentioned above (for the default System.Random), this bias may be of 
        // negligible importance for most purposes not involving security. 
        long x=rand.Next(0,1<<30); 
        x<<=23; 
        x+=rand.Next(0,1<<23); 
        return (double)x/(double)(1L<<53); 
    } 
    

    、Iは、a separate articleで安定配信のための擬似コードを記載します。

    関連する問題