计算给出数组中最小标准差的子集

Posted

技术标签:

【中文标题】计算给出数组中最小标准差的子集【英文标题】:Computing the subset giving the minimum standard deviation in an array 【发布时间】:2013-12-07 06:33:27 【问题描述】:

让我们有一个大小为N 的向量。例如:

x = rand(N,1)

我想计算向量中长度为K 的子集的最小标准差。

NK 很小时,很容易找到最佳子集,因为我可以使用nchoosek(N,K) 枚举所有可能的子集。但是当NK 的值大于假设N=50K=25 时,nchoosek 无法计算组合,因为可能的子集的大小很大。

我想知道是否有更好的算法来计算子集,从而有效地给出数组中的最小标准偏差。例如通过动态编程。有什么想法吗?

更新

我在答案之后循环实现了它,并与组合解决方案进行了比较。结果总是一样的,但速度却是前所未有的。

n = 20;
k = 10;
x = rand(n,1);
C = nchoosek(x, k);

tic
mins = realmax;
for i = 1:size(C,1)
    s = std(C(i,:));
    if s < mins
        mins = s;
        bestC = C(i,:);
    end
end
toc

tic
[x2, j] = sort(x);
mins2 = realmax;
for i = 1:(n-k+1)
    s = std(x2(i:(i+k-1)));
    if s < mins2
        mins2 = s;
        idx = j((i:(i+k-1)));
    end
end
toc

if mins == mins2
    'Equal'
end

给予

Elapsed time is 7.786579 seconds.
Elapsed time is 0.002068 seconds.

ans =

Equal

【问题讨论】:

【参考方案1】:

对数组进行排序,然后使用长度为K 的滚动窗口一次性计算。

我相信这会给你正确的答案,如果我能证明它会思考。

手摇论据,在“扩展这个”部分可能存在逻辑差距:

考虑您列表中的元素x。让我们尝试找出包含该元素的一组大小为 2 的最小标准差。我们将通过选择x 和最接近x 的元素来获得它。将此扩展到k 元素,我们将得到一个集合,它是包含x 的排序列表的连续部分。因此,要选择k 元素的最小子集(即任何x),我们只需如前所述遍历排序列表。

【讨论】:

我认为您是正确的,并且我认为我发布的解决方案使用conv 而不是 matlab 循环(可能更快也可能不会更快)找到它。但我也无法证明。 @Dan 发布了一个理由,但我认为它不完整。 这种归纳方法证明了添加最接近的元素会导致波动性的最小增加。但是,它并没有说它会给你一组大小为 n+1 且波动性最小的集合。显然,情况并非如此,因为从异常值开始绝对不必将您引导至最小波动率集。这可以通过从每一点开始来反驳,但这里还没有证明这是否足够。--直觉上感觉这个答案是正确的,所以我会给你我的投票,希望它是正确的。 @DennisJaheruddin 你是对的,它不是水密的。我认为这可能是一种更好的证明方法。第 1 步:证明对于任何非连续子集,我们可以通过用其中一个“洞”中的元素替换适当的(例如最小或最大)元素来减少方差。第 2 步:重复应用第 1 步,我们看到任何最小方差子集都必须是排序列表的连续部分。当然,繁琐的部分是证明第 1 步。但是这种方法可以避免您指出的问题。

以上是关于计算给出数组中最小标准差的子集的主要内容,如果未能解决你的问题,请参考以下文章

最大值,最小值,平均值,标准差的计算

Python:使用pandas和numpy计算标准差的区别

一种计算标准差的高效方法:Welford迭代法

一种计算标准差的高效方法:Welford迭代法

计算标准差的在线算法

标准差怎么计算 标准差的计算方法