在下面绘制的2D数组中,我们有兴趣找到“肿块”区域。正如您所看到的,它不是一个连续的图形。此外,我们知道“肿块”区域的大致尺寸。下面给出了一组数据。第一列包含y值,第二列包含x值。关于如何检测像这样的肿块区域的任何建议?
21048 -980
21044 -956
21040 -928
21036 -904
21028 -880
21016 -856
21016 -832
21016 -808
21004 -784
21004 -760
20996 -736
20996 -712
20992 -684
20984 -660
20980 -636
20968 -612
20968 -588
20964 -564
20956 -540
20956 -516
20952 -492
20948 -468
20940 -440
20936 -416
20932 -392
20928 -368
20924 -344
20920 -320
20912 -296
20912 -272
20908 -248
20904 -224
20900 -200
20900 -176
20896 -152
20888 -128
20888 -104
20884 -80
20872 -52
20864 -28
20856 -4
20836 16
20812 40
20780 64
20748 88
20744 112
20736 136
20736 160
20732 184
20724 208
20724 232
20724 256
20720 280
20720 304
20720 328
20724 352
20724 376
20732 400
20732 424
20736 448
20736 472
20740 496
20740 520
20748 544
20740 568
20736 592
20736 616
20736 640
20740 664
20740 688
20736 712
20736 736
20744 760
20748 788
20760 812
20796 836
20836 860
20852 888
20852 912
20844 936
20836 960
20828 984
20820 1008
20816 1032
20820 1056
20852 1080
20900 1108
20936 1132
20956 1156
20968 1184
20980 1208
20996 1232
21004 1256
21012 1280
21016 1308
21024 1332
21024 1356
21028 1380
21024 1404
21020 1428
21016 1452
21008 1476
21004 1500
20992 1524
20980 1548
20956 1572
20944 1596
20920 1616
20896 1640
20872 1664
20848 1684
20812 1708
20752 1728
20664 1744
20640 1768
20628 1792
20628 1816
20620 1836
20616 1860
20612 1884
20604 1908
20596 1932
20588 1956
20584 1980
20580 2004
20572 2024
20564 2048
20552 2072
20548 2096
20536 2120
20536 2144
20524 2164
20516 2188
20512 2212
20508 2236
20500 2260
20488 2280
20476 2304
20472 2328
20476 2352
20460 2376
20456 2396
20452 2420
20452 2444
20436 2468
20432 2492
20432 2516
20424 2536
20420 2560
20408 2584
20396 2608
20388 2628
20380 2652
20364 2676
20364 2700
20360 2724
20352 2744
20344 2768
20336 2792
20332 2812
20328 2836
20332 2860
20340 2888
20356 2912
20380 2940
20428 2968
20452 2996
20496 3024
20532 3052
20568 3080
20628 3112
20652 3140
20728 3172
20772 3200
20868 3260
20864 3284
20864 3308
20868 3332
20860 3356
20884 3384
20884 3408
20912 3436
20944 3464
20948 3488
20948 3512
20932 3536
20940 3564
答案 0 :(得分:7)
这可能只是巧合,但你表现出的肿块看起来相当抛物线。通过“了解肿块区域的大致尺寸”并不完全清楚你的意思,但是如果你的意思是你大致知道它有多宽(即它占用多少x轴),你可以简单地滑动一个窗口沿着x轴的那个宽度,并且对于在每个点处适合窗口的所有数据进行抛物线拟合(也称为2度的聚变)。然后,计算每个点处的r ^ 2拟合优度值,并且r ^ 2最接近1.0的点将是最佳拟合。你可能需要一个阈值并抛弃那些x ^ 2系数为正(为了找到肿块而不是逢低)以获得理智,但这可能是一种可行的方法。
即使抛物线外观是巧合,我认为这将是一个合理的方法 - 向下指向抛物线是我能想到的任何定义的一般“疙瘩”的非常好的描述。
编辑:尝试实施
我很好奇并继续实施我提出的解决方案(略有修改)。首先,这是代码(丑陋但功能齐全):
function [x, p] = find_lump(data, width)
n = size(data, 1);
f = plot(data(:,1),data(:,2), 'bx-');
hold on;
bestX = -inf;
bestP = [];
bestMSE = inf;
bestXdat = [];
bestYfit = [];
spanStart = 0;
spanStop = 1;
spanWidth = 0;
while (spanStop < n)
if (spanStart > 0)
% Drop first segment from window (since we'll advance x):
spanWidth = spanWidth - (data(spanStart + 1, 1) - x);
end
spanStart = spanStart + 1;
x = data(spanStart, 1);
% Advance spanStop index to maintain window width:
while ((spanStop < n) && (spanWidth <= width))
spanStop = spanStop + 1;
spanWidth = data(spanStop, 1) - x;
end
% Correct for overshoot:
if (spanWidth > width)
spanStop = spanStop - 1;
spanWidth = data(spanStop, 1) - x;
end
% Fit parabola to data in the current window:
xdat = data(spanStart:spanStop, 1);
ydat = data(spanStart:spanStop, 2);
p = polyfit(xdat, ydat, 2);
% Compute fit quality (mean squared error):
yfit = polyval(p,xdat);
r = yfit - ydat;
mse = (r' * r) / size(xdat,1);
if ((p(1) < -0.002) && (mse < bestMSE))
bestMSE = mse;
bestX = x;
bestP = p;
bestXdat = xdat;
bestYfit = yfit;
end
end
x = bestX;
p = bestP;
plot(bestXdat,bestYfit,'r-');
...这里是使用给定数据的结果(我交换了列,因此第1列是x值,第2列是y值),窗口宽度参数为750:
<强>注释:强>
我选择使用拟合抛物线与每个窗口内的原始数据之间的均方误差作为质量度量,而不是由于懒惰而比相关系数(r ^ 2值)更重要。我认为结果与其他方式不同。
输出严重依赖于为二次系数选择的阈值(参见循环结束时的bestMSE条件)。说实话,我在这里通过输出每个点的拟合系数来欺骗,然后根据已知的肿块形状选择阈值。这相当于使用@chaohuang建议的块模板,并且可能不是非常强大,具体取决于数据中预期的方差。
请注意,如果使用此方法,则似乎需要某种形状控制参数。原因是任何随机(平滑)数据运行都可以很好地拟合某些抛物线,但不一定在最大值附近。这是一个结果,我将阈值设置为零,因此只限制了向下指向抛物线的拟合:
一个改进是添加一个检查,拟合抛物线在窗口间隔内至少有一个最大值(也就是说,检查窗口中的一阶导数是否为零,这样我们至少可以找到沿曲线的局部最大值) 。仅仅这一点是不够的,因为你仍然可能有一个比一个“明显的”大块更适合抛物线的小块,如给定的数据集所示。