很抱歉这个长标题,但总结一下。
我希望以最高计算效率的方式找到数组中类似值的最大丛的中值。
例如:
H = [99,100,101,102,103,180,181,182,5,250,17]
我会寻找101.
数组没有排序,我只是按上面的顺序键入它以便于理解。 数组具有恒定的长度,您可以始终假设至少有一个相似值的丛。
到目前为止,我一直在做的是基本上用去除的一个值计算标准偏差,找到对应于STD最大减少的值,并重复数组中元素数量的值,这非常低效
for j = 1:7
G = double(H);
for i = 1:7
G(i) = NaN;
T(i) = nanstd(G);
end
best = find(T==min(T));
H(best) = NaN;
end
x = find(H==max(H));
有什么想法吗?
答案 0 :(得分:1)
这种可能性可以存储您的数据并查找包含大多数元素的bin。如果您的发行版由分离良好的集群组成,那么这应该可以很好地工作。
H = [99,100,101,102,103,180,181,182,5,250,17];
nbins = length(H); % <-- set # of bins here
[v bins]=hist(H,nbins);
[vm im]=max(v); % find max in histogram
bl = bins(2)-bins(1); % bin size
bm = bins(im); % position of bin with max #
ifb =find(abs(H-bm)<bl/2) % elements within bin
median(H(ifb)) % average over those elements in bin
输出:
ifb = 1 2 3 4 5
H(ifb) = 99 100 101 102 103
median = 101
要设置的更具挑战性的参数是垃圾箱数量和查看人口最多的垃圾箱的区域大小。在您提供的示例中,这些都不是那么重要,您可以将容器数设置为3
(而不是length(H)
),它仍然可以正常工作。使用length(H)
作为垃圾箱的数量实际上有点极端,可能不是一个很好的一般选择。更好的选择介于该数字与预期的聚类数之间。
某些发行版可能有助于将bl
表达式中的find
更改为您事先判断得更好的值。
我还应该注意,有些聚类方法(kmeans
)可能效果更好,但可能效率较低。例如,这是[H' kmeans(H',4) ]
:
99 2
100 2
101 2
102 2
103 2
180 3
181 3
182 3
5 4
250 3
17 1
在这种情况下,我提前决定尝试分组为4个群集。
使用kmeans
,您可以获得如下答案:
nbin = 4;
km = kmeans(H',nbin);
[mv iv]=max(histc(km,[1:nbin]));
H(km==km(iv))
median(H(km==km(iv)))
但请注意,kmeans
每次运行时都不一定返回相同的值,因此您可能需要平均几次迭代。
我计算了两种方法,发现kmeans
需要大约10倍的时间。但是,它更加健壮,因为箱子大小适应您的问题而且不需要事先设置(只有箱子的数量)。