我想对几个数据点进行线性拟合,如图所示。因为我知道截距(在这种情况下说是0.05),所以我想只使用这个特定的截距来拟合线性区域中的点。在这种情况下,我们可以说点5:22(但不是22:30)。
我正在寻找简单的算法来确定这个最佳点数,基于......嗯,这就是问题...... R ^ 2?任何想法怎么做?
我正在考虑使用点1到2:30,2到3:30来探测R ^ 2,但是我真的不知道如何将它包含在清晰简单的功能中。对于具有固定截距的拟合,我使用polyfit0
(http://www.mathworks.com/matlabcentral/fileexchange/272-polyfit0-m)。谢谢你的任何建议!
编辑: 样本数据:
intercept = 0.043;
x = 0.01:0.01:0.3;
y = [0.0530642513911393,0.0600786706929529,0.0673485248329648,0.0794662409166333,0.0895915873196170,0.103837395346484,0.107224784565365,0.120300492775786,0.126318699218730,0.141508831492330,0.147135757370947,0.161734674733680,0.170982455701681,0.191799936622712,0.192312642057298,0.204771365716483,0.222689541632988,0.242582251060963,0.252582727297656,0.267390860166283,0.282890010610515,0.292381165948577,0.307990544720676,0.314264952297699,0.332344368808024,0.355781519885611,0.373277721489254,0.387722683944356,0.413648156978284,0.446500064130389;];
答案 0 :(得分:4)
您在这里找到一个通用解决方案是一个相当困难的问题。
一种方法是计算所有连续点对之间的所有斜率/相交,然后对间隙进行聚类分析:
slopes = diff(y)./diff(x);
intersepts = y(1:end-1) - slopes.*x(1:end-1);
idx = kmeans(intersepts, 3);
x([idx; 3] == 2) % the points with the intersepts closest to the linear one.
这需要统计工具箱(适用于kmeans
)。这是我尝试的所有方法中最好的,尽管这样找到的点的范围可能中有一些小洞;例如,当开始和结束范围中的两个点的斜率接近线的斜率时,这些点将被检测为属于该线。这(以及其他因素)将需要对这种方式的解决方案进行更多的后处理。
另一种方法(我未能成功构建)是在循环中进行线性拟合,每次从中间的某个点向两个端点增加点的范围,并查看平方的总和错误仍然很小。我很快放弃了,因为定义“小”是非常主观的,必须以某种启发式方式完成。
我尝试了一种更加系统和强大的方法:
function test
%% example data
slope = 2;
intercept = 1.5;
x = linspace(0.1, 5, 100).';
y = slope*x + intercept;
y(1:12) = log(x(1:12)) + y(12)-log(x(12));
y(74:100) = y(74:100) + (x(74:100)-x(74)).^8;
y = y + 0.2*randn(size(y));
%% simple algorithm
[X,fn] = fminsearch(@(ii)P(ii, x,y,intercept), [0.5 0.5])
[~,inds] = P(X, y,x,intercept)
end
function [C, inds] = P(ii, x,y,intercept)
% ii represents fraction of range from center to end,
% So ii lies between 0 and 1.
N = numel(x);
n = round(N/2);
ii = round(ii*n);
inds = min(max(1, n+(-ii(1):ii(2))), N);
% Solve linear system with fixed intercept
A = x(inds);
b = y(inds) - intercept;
% and return the sum of squared errors, divided by
% the number of points included in the set. This
% last step is required to prevent fminsearch from
% reducing the set to 1 point (= minimum possible
% squared error).
C = sum(((A\b)*A - b).^2)/numel(inds);
end
只找到所需索引的粗略近似值(本例中为12和74)。
当fminsearch
使用随机起始值运行几十次(实际上只是rand(1,2)
)时,它会变得更可靠,但我仍然不会赌我的生命。
如果您有统计工具箱,请使用kmeans
选项。
答案 1 :(得分:1)
根据数据值的数量,我会将数据分成相对较少数量的重叠段,并且对于每个段计算线性拟合,或者更确切地说是1阶序列系数,(记住你知道截距,对于所有细分市场都是一样的)。
然后,对于每个系数,计算该假设线和整个数据集之间的MSE,选择产生最小MSE的系数。