Произвольное распределение -> Равномерное распределение (Вероятность интегрального преобразования?) - PullRequest
0 голосов
/ 10 мая 2011

У меня есть 500 000 значений для переменной, полученной на финансовых рынках.В частности, эта переменная представляет расстояние от среднего значения (в стандартных отклонениях).Эта переменная имеет произвольное распределение.Мне нужна формула, которая позволит мне выбрать диапазон вокруг любого значения этой переменной так, чтобы равное (или близкое к нему) количество точек данных попадало в этот диапазон.

Это позволит мне затем проанализироватьвсе точки данных в пределах определенного диапазона и рассматривать их как «ситуации, аналогичные входным».

Насколько я понимаю, это означает, что мне нужно преобразовать его из произвольного распределения в равномерное распределение.Я прочитал (но с трудом понимал), что то, что я ищу, называется «интегралом вероятности».

Может ли кто-нибудь помочь мне с каким-нибудь кодом (предпочтительно Matlab, но это не имеет значения), чтобы помочь мневыполнить это?

Ответы [ 2 ]

2 голосов
/ 10 мая 2011

Вот кое-что, что я быстро собрал. Он не отполирован и не идеален, но делает то, что вы хотите.

clear
randList=[randn(1e4,1);2*randn(1e4,1)+5];
[xCdf,xList]=ksdensity(randList,'npoints',5e3,'function','cdf');
xRange=getInterval(5,xList,xCdf,0.1); 

и функция getInterval равна

function out=getInterval(yPoint,xList,xCdf,areaFraction)
    yCdf=interp1(xList,xCdf,yPoint);
    yCdfRange=[-areaFraction/2, areaFraction/2]+yCdf;

    out=interp1(xCdf,xList,yCdfRange);

Пояснение:

CDF случайного распределения показан ниже синей линией. Вы задаете точку (здесь 5 во входных данных для getInterval), относительно которой вы хотите диапазон, который дает вам 10% площади (от 0.1 до getInterval). Выбранная точка отмечена красным крестом и интервал отмечен зелеными линиями. Вы можете получить соответствующие точки из исходного списка, которые лежат в этом интервале как

newList=randList(randList>=xRange(1) & randList<=xRange(2));

Вы увидите, что в среднем количество очков в этом примере составляет ~ 2000, что составляет 10% от numel(randList)

numel(newList)

ans =

        2045

enter image description here

Примечание:

  • Обратите внимание, что это было сделано быстро, и я не проверял, находится ли выбранная точка вне диапазона или если yCdfRange выходит за пределы [0 1], в этом случае interp1 вернет NaN. Это довольно просто реализовать, и я оставлю это вам.
  • Кроме того, ksdensity очень сильно загружает процессор. Я бы не рекомендовал увеличивать npoints до более чем 1e4. Я предполагаю, что вы работаете только с фиксированным списком (т. Е. У вас есть список из 5e5 баллов, которые вы каким-то образом получили, и теперь вы просто запускаете тесты / анализируете его). В этом случае вы можете запустить ksdensity один раз и сохранить результат.
1 голос
/ 10 мая 2011

Я не говорю на Matlab, но вам нужно найти квантили в ваших данных.Это код Mathematica, который сделает это:

In[88]:= data = RandomVariate[SkewNormalDistribution[0, 1, 2], 10^4];

Вычислить квантильные точки:

In[91]:= q10 = Quantile[data, Range[0, 10]/10];

Теперь формируйте пары последовательных квантилей:

In[92]:= intervals = Partition[q10, 2, 1];

In[93]:= intervals

Out[93]= {{-1.397, -0.136989}, {-0.136989, 0.123689}, {0.123689, 
  0.312232}, {0.312232, 0.478551}, {0.478551, 0.652482}, {0.652482, 
  0.829642}, {0.829642, 1.02801}, {1.02801, 1.27609}, {1.27609, 
  1.6237}, {1.6237, 4.04219}}

Убедитесь, чтоточки разделения разделяют данные почти равномерно:

In[94]:= Table[Count[data, x_ /; i[[1]] <= x < i[[2]]], {i, intervals}]

Out[94]= {999, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000}
...