Стабильное распределение случайных чисел? - PullRequest
4 голосов
/ 20 февраля 2012

Как генерировать случайные числа со стабильным распределением в C #? Класс Random имеет равномерное распределение. Много другого кода на интернет показывают нормальное распространение. Но нам нужно стабильное распределение означает бесконечное отклонение, a.k.a распределение с жирным хвостом.

Причина заключается в создании реалистичных цен на акции. В реале мир, огромные колебания цен гораздо чаще, чем в нормальные распределения.

Кто-нибудь знает код C # для преобразования вывода в случайный класс? в стабильный дистрибутив?

Редактировать: Хммм. Точное распределение менее критично, чем обеспечение случайного генерирования огромной сигмы, как минимум 20 сигм. Мы хотим проверить торговую стратегию на устойчивость в истинно жирном распределении, которое именно так и ведет себя на фондовом рынке.

Я только что прочитал о ZipFian и Коши из-за комментариев. Так как я должен выбрать, давайте перейдем к распределению Коши, но я также попробую ZipFian для сравнения.

Ответы [ 4 ]

6 голосов
/ 20 февраля 2012

В общем случае метод:

  • Выберите стабильный, жирнохвостый дистрибутив. Скажем, распределение Коши.

  • Найдите квантильную функцию выбранного распределения.

Для распределения Коши это будет p --> peak + scale * tan( pi * (p - 0.5) ).

  • И теперь у вас есть метод преобразования равномерно распределенных случайных чисел в случайные числа с распределением Коши.

Имеет смысл? См

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

для деталей.

Предостережение: Прошло много-много времени с тех пор, как я брал статистику.

ОБНОВЛЕНИЕ:

Мне так понравился этот вопрос, что я просто написал в блоге: см.

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

Моя статья, исследующая несколько интересных примеров дистрибутивов Zipfian, находится здесь:

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

1 голос
/ 21 февраля 2012

Если вы заинтересованы в использовании дистрибутива Zipfian (который часто используется при моделировании процессов из области науки или социальной сферы), вы должны сделать что-то вроде:

  1. Выберите ваш k (перекос) для распределения
  2. Предварительный расчет домена кумулятивного распределения (это всего лишь оптимизация)
  3. Генерация случайных значений для распределения путем нахождения ближайшего значения из домена

Пример кода:

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));

Теперь вы можете генерировать случайные значения, выбирая ближайшее значение из домена:

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 голосов
/ 27 июля 2017

Следующий код C # генерирует случайное число после стабильного распределения с учетом параметров формы alpha и beta.Я публикую его в открытом доступе под Creative Commons Zero.

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);
}

Кроме того, я изложил псевдокод для стабильного распространения в отдельной статье .

0 голосов
/ 21 февраля 2012

Передо мной том Спрингера Джеймса Джентла на эту тему, Генерация случайных чисел и методы Монте-Карло , любезно предоставленные моей женой-статистиком. Обсуждается стабильное семейство на стр. 105:

Стабильное семейство распределений - это гибкое семейство распределений с тяжелым хвостом. Это семейство включает в себя нормальное распределение по одному экстремальному значению одного из параметров и Коши по другому экстремальному значению. Chambers, Mallows, и Stuck (1976) предлагают метод генерации отклонений от стабильных распределений. (Следите за некоторыми ошибками в константах во вспомогательной функции D2 для оценки (e x -1) / x.) Их метод используется в библиотеках IMSL. Для симметричного стабильного распределения Devroye (1986) указывает, что более быстрый метод может быть разработан с использованием отношения симметричного стабильного распределения к распределению Фейера-де-ла-Валле Пуассена. Buckle (1995) показывает, как моделировать параметры стабильного распределения, зависящие от данных.

Трудно сгенерировать отклонения от общего стабильного распределения. Если вам нужно сделать это, я бы порекомендовал такую ​​библиотеку, как IMSL. Я не советую вам делать это самостоятельно.

Однако, если вы ищете конкретное распределение в стабильной семье, например, Коши, тогда вы можете использовать метод, описанный Эриком, известный как интеграл вероятности . Пока вы можете записать обратную функцию распределения в закрытом виде, вы можете использовать этот подход.

...