假设我们有这个矩阵:
main = [10000 5 3 1;
5 5677 0 134;
1 1 456 3];
这种方法是计量经济学和统计问题中使用最广泛的方法。X
是我们在其中搜索异常值的数据。
X-mean(X)>= n*std(X)
所以如果这个不平等是真的,那个样本就是异常,否则我们会保留样本。
现在我的问题。我想找到这些代码的异常值:
meann = mean(main);
stdd = std(main);
out = find(main-repmat(meann,size(main,1),1)>=repmat(2*stdd,size(main,1),1));
我们正在搜索每一栏中的异常值。 Out
应指明异常值的索引。在最后一步中,我们应该删除每列中的异常值。有没有更简单的函数或方法在MAtLAB中执行此操作?
感谢。
答案 0 :(得分:4)
2 * sigma标准当然很简单,但平均值和标准偏差对异常值非常敏感。因此,out
变量将受到影响,实际上您的代码在给定矩阵中找不到任何异常值。
要检测异常值,您只需将矩阵中出现的值与中位数进行比较,或采用更精确的标准。有一个漂亮的讲座在https://www.mne.psu.edu/me345/Lectures/outliers.pdf
解释这个答案 1 :(得分:3)
如果你想在每列的基础上找到2个标准偏差,我会使用bsxfun
而不是repmat
这样:
meann = mean(main)
stdd = std(main)
I = bsxfun(@gt, abs(bsxfun(@minus, main, meann)), 2*stdd)
我会停在I
,因为这样可以删除异常值。不过,您可以随意拨打find
:
out = find(I)
虽然对我来说这样做更直观:
I = bsxfun(@lt, meann + 2*stdd, main) | bsxfun(@gt, meann - 2*stdd, main)
我认为您的repmat
解决方案缺少abs
btw
答案 2 :(得分:2)
如果要从不同列中删除某些元素,请使用单元格数组。
main = rand(100,4);
main(10,1) = 10000;
main(40,2) = 4321;
main([10,20,30],3)=[938;10;4];
mu = num2cell(mean(main));
sig = num2cell(std(main));
m = num2cell(main,1);
ind = cellfun(@(x,m,s) find( bsxfun(@lt, abs( bsxfun(@minus,x,m) ), 2*s) ),...
m, mu, sig, 'uni', 0);
data = cellfun(@(x,m,s) x( bsxfun(@lt, abs( bsxfun(@minus,x,m) ), 2*s) ),...
m, mu, sig, 'uni', 0);
PS。您的示例太小,因此可能没有足够的样本来建立阈值。