我从金融市场获得的变量有500,000个值。具体而言,该变量表示距平均值的距离(标准偏差)。该变量具有任意分布。我需要一个公式,允许我选择这个变量的任何值周围的范围,使得相等(或接近它)的数据点数量落在该范围内。
这样我就可以分析特定范围内的所有数据点,并将它们视为“与输入类似的情况”。
据我所知,这意味着我需要将它从任意分布转换为均匀分布。我已经读过(但几乎没有理解)我正在寻找的东西叫做“概率积分变换”。
任何人都可以帮助我完成一些代码(Matlab首选,但这并不重要)?
答案 0 :(得分:2)
这是我快速拼凑的东西。它没有抛光而且不完美,但它可以做你想做的事。
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,这是numel(randList)
的10%
numel(newList)
ans =
2045
注意:强>
yCdfRange
是否超出[0 1]
,在这种情况下{{1} }将返回interp1
。这很容易实现,我会留给你。NaN
非常占用CPU。我不建议将ksdensity
增加到npoints
以上。我假设您只使用固定列表(即,您有一个1e4
点列表,您已经以某种方式获得,现在您只是运行测试/分析它)。在这种情况下,您可以运行5e5
一次并保存结果。答案 1 :(得分:1)
我不会说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}