如何为非线性最小二乘拟合选择初始值

机器算法验证 最小二乘 非线性回归 起始值
2022-03-01 18:39:50

上面的问题说明了一切。基本上我的问题是一个通用的拟合函数(可能是任意复杂的),它在我试图估计的参数中是非线性的,如何选择初始值来初始化拟合?我正在尝试做非线性最小二乘。有什么策略或方法吗?这个有研究过吗?有参考吗?除了临时猜测之外还有什么?具体来说,现在我正在使用的拟合形式之一是高斯加线性形式,其中包含我试图估计的五个参数,例如

y=Ae(xBC)2+Dx+E

其中(横坐标数据)和(纵坐标数据)意味着在对数对数空间中,我的数据看起来像一条直线加上我用高斯近似的凹凸。我没有理论,没有什么可以指导我如何初始化非线性拟合,除了可能像线条的斜率和凹凸的中心/宽度那样的图形和眼球观察。但是我有超过一百个这样的拟合,而不是图形和猜测,我更喜欢一些可以自动化的方法。x=log10y=log10

我在图书馆或网上找不到任何参考资料。我唯一能想到的就是随机选择初始值。MATLAB 提供从均匀分布的 [0,1] 中随机选择值。因此,对于每个数据集,我运行随机初始化的拟合一千次,然后选择具有最高的那个?还有其他(更好的)想法吗?r2


附录#1

首先,这里有一些数据集的可视化表示,只是为了向你们展示我在说什么类型的数据。我以原始形式发布数据,没有任何类型的转换,然后在日志空间中发布它的可视化表示,因为它澄清了一些数据的特征,同时扭曲了其他特征。我正在发布好数据和坏数据的样本。

好数据 log-log 好数据 不良数据 记录不良数据

每个图中的六个面板中的每一个都显示了四个数据集,红色、绿色、蓝色和青色绘制在一起,每个数据集正好有 20 个数据点。由于数据中看到的颠簸,我试图用一条直线加上一个高斯来拟合它们中的每一个。

第一个数字是一些好的数据。第二个图是图一中相同好的数据的对数图。第三个数字是一些不良数据。第四个图是图三的对数图。还有更多数据,这些只是两个子集。大部分数据(大约 3/4)是好的,类似于我在这里展示的好的数据。

现在有一些评论,请耐心等待,因为这可能会很长,但我认为所有这些细节都是必要的。我会尽量简洁。

我最初期望一个简单的幂律(意味着对数空间中的直线)。当我在对数空间中绘制所有内容时,我看到了 4.8 mHz 左右的意外颠簸。颠簸经过彻底调查,并且在其他工作中也被发现,所以不是我们搞砸了。它在物理上就在那里,其他已发表的作品也提到了这一点。所以我只是在我的线性形式中添加了一个高斯项。请注意,这种拟合是在日志空间中完成的(因此我的两个问题包括这个)。

现在,在阅读了Stumpy Joe Pete 对我的另一个问题的回答(根本与这些数据无关)并阅读了这个这个以及其中的引用(Clauset 的东西)之后,我意识到我不应该适合 log-log空间。所以现在我想在预先转换的空间中做所有事情。

问题一:看好数据,我还是觉得在预变换空间中一个线性加一个高斯还是一个好形式。我很想听听其他拥有更多数据经验的人的想法。高斯+线性合理吗?我应该只做高斯吗?还是完全不同的形式?

问题 2:无论问题 1 的答案如何,我仍然需要(很可能)非线性最小二乘拟合,因此仍然需要初始化帮助。

我们看到两组数据,我们非常喜欢在 4-5 mHz 左右捕获第一个颠簸。所以我不想添加更多的高斯项,我们的高斯项应该以第一个凹凸为中心,这几乎总是更大的凹凸。我们希望在 0.8mHz 和 5mHz 左右之间“更准确”。我们不太关心更高的频率,但也不想完全忽略它们。所以也许某种称重?或者 B 可以始终在 4.8mHz 左右初始化?

横坐标数据是以毫赫兹为单位的频率,用表示。纵坐标数据是我们正在计算的系数,用表示。所以没有对数转换,形式为fL

L=Ae(fBC)2+Df+E.

  • f是频率,总是正的。
  • L为正系数。所以我们在第一象限工作。
  • A,我认为幅度也应该始终为正,因为我们只是在处理颠簸。当我查看数据时,我总是看到高峰而没有低谷。看起来在所有数据中都有多个更高频率的颠簸。第一个凸起总是比其他凸起大得多。在良好的数据中,次级凸起非常弱,但在不良数据(例如面板 2 和 5)中,次级凸起很强。所以我们实际上没有一个山谷,而是两个颠簸。意味着幅度而且由于我们主要关心第一个峰值,因此更有理由保持积极态度。A>0A
  • B是凸起的中心,我们总是希望它位于 4-5mHz 左右的那个大凸起上。在我们解析的频率范围内,它几乎总是出现在 4.8mHz。
  • C是凸块的宽度。我想它是围绕零对称的,这意味着相同的效果,因为它是平方的。所以我们不在乎它的价值是什么。假设我们更喜欢它是积极的。CC
  • D是线的斜率,似乎它可能略微为负,因此不对它实施任何限制。斜坡本身就很有趣,所以我们不想对其施加任何限制,我们只想看看它会是什么。它是积极的还是消极的?它的大小有多大/小?等等。
  • E是(几乎)截距。这里微妙的是,由于高斯项,不完全是截距。实际截距(如果我们外推到)将是LELf=0

Ae(B/C)2+E.

所以这里唯一的限制是截距也应该是正数。截距为零,我不知道这意味着什么。但消极肯定看起来很荒谬。我想在这里我们可以允许在必要时以较小的幅度略微为负。和截距的原因在这里很重要,但我们的一些同事实际上也对外推感兴趣。我们拥有的最小频率是 0.8mHz,他们想在 0 到 0.8mHz 之间进行推断。我幼稚的想法是只使用 fit 一直到EEf=0

我知道外推比插值更难/更危险,但使用直线加高斯(希望它衰减得足够快)对我来说似乎是合理的。有点像具有自然边界条件的自然三次样条曲线,左端点处的斜率,只需延长线并查看它与轴相交的位置。如果它不是负数,则使用该线进行外推。L

问题3:你们认为在这种情况下以这种方式推断是什么?有什么优点/缺点吗?还有其他外推想法吗?同样,我们只关心较低的频率,因此在 0 和 1mHz 之间进行外推......有时非常非常小的频率,接近于零。我知道这篇文章已经打包了。我在这里问了这个问题,因为答案可能是相关的,但如果你们愿意,我可以把这个问题分开,稍后再问另一个。

最后,根据要求,这里有两个示例数据集。

0.813010000000000   0.091178000000000   0.012728000000000
1.626000000000000   0.103120000000000   0.019204000000000
2.439000000000000   0.114060000000000   0.063494000000000
3.252000000000000   0.123130000000000   0.071107000000000
4.065000000000000   0.128540000000000   0.073293000000000
4.878000000000000   0.137040000000000   0.074329000000000
5.691100000000000   0.124660000000000   0.071992000000000
6.504099999999999   0.104480000000000   0.071463000000000
7.317100000000000   0.088040000000000   0.070336000000000
8.130099999999999   0.080532000000000   0.036453000000000
8.943100000000001   0.070902000000000   0.024649000000000
9.756100000000000   0.061444000000000   0.024397000000000
10.569000000000001   0.056583000000000   0.025222000000000
11.382000000000000   0.052836000000000   0.024576000000000
12.194999999999999   0.048727000000000   0.026598000000000
13.008000000000001   0.045870000000000   0.029321000000000
13.821000000000000   0.041454000000000   0.067300000000000
14.633999999999999   0.039596000000000   0.081800000000000
15.447000000000001   0.038365000000000   0.076443000000000
16.260000000000002   0.036425000000000   0.075912000000000

第一列是以 mHz 为单位的频率,在每个数据集中都相同。第二列是一个好的数据集(好的数据图一和二,面板 5,红色标记),第三列是一个坏的数据集(坏数据图三和四,面板 5,红色标记)。

希望这足以激发一些更开明的讨论。谢谢大家。

4个回答

如果有一种既通用的策略——总是有效的——它已经在每个非线性最小二乘程序中实施,并且起始值将不是问题。

对于许多特定问题或问题系列,存在一些很好的初始值方法;一些软件包带有针对特定非线性模型的良好起始值计算或更通用的方法,这些方法通常有效,但可能需要通过更具体的函数或直接输入起始值来帮助解决。

在某些情况下,探索这个空间是必要的,但我认为你的情况可能是这样的,更具体的策略可能是值得的——但设计一个好的策略几乎需要很多我们不太可能拥有的领域知识。

对于您的特定问题,可以设计可能的好策略,但这不是一个简单的过程;关于峰值的可能大小和范围的信息越多(典型的参数值和典型的会给出一些想法),就可以做更多的事情来设计一个好的起始值选择。x

的典型范围是多少?平均结果是什么样的?有哪些不寻常的案例?您知道哪些参数值是可能的或不可能的?yx

一个例子——高斯部分是否一定会产生一个转折点(峰或谷)?或者它有时相对于线太小以至于它没有?总是积极的吗?等等A

如果可以的话,一些示例数据会有所帮助 - 典型案例和困难案例。


编辑:这是一个例子,如果问题不是太嘈杂,你可以如何做得相当好:

这是从您的模型生成的一些数据(总体值为 A = 1.9947,B = 10,C = 2.828,D = 0.09,E = 5):

数据

我能够估计的起始值是
(As = 1.658,Bs = 10.001,Cs = 3.053,Ds = 0.0881,Es = 5.026)

该启动模型的拟合如下所示:

启动

步骤是:

  1. 拟合 Theil 回归以获得 D 和 E 的粗略估计
  2. 减去 Theil 回归的拟合
  3. 使用 LOESS 拟合平滑曲线
  4. 找到峰值得到A的粗略估计,峰值对应的x值得到B的粗略估计
  5. 将 y 值大于 A 估计值的 60% 的 LOESS 拟合作为观测值并拟合二次
  6. 使用二次来更新 B 的估计并估计 C
  7. 从原始数据中减去高斯的估计值
  8. 将另一个 Theil 回归拟合到该调整后的数据以更新 D 和 E 的估计值

在这种情况下,这些值非常适合开始非线性拟合。

我把它写成R代码,但同样的事情可以在 MATLAB 中完成。

我认为比这更好的事情是可能的。

如果数据非常嘈杂,这根本不会奏效。


Edit2:这是我在 R 中使用的代码,如果有人感兴趣的话:

gausslin.start <- function(x,y) {

  theilreg <- function(x,y){
    yy <- outer(y, y, "-")
    xx <- outer(x, x, "-")
    z  <- yy / xx
    slope     <- median(z[lower.tri(z)])
    intercept <- median(y - slope * x)
    cbind(intercept=intercept,slope=slope)
  }

  tr <- theilreg(x,y1)
  abline(tr,col=4)
  Ds = tr[2]
  Es = tr[1]
  yf  <- y1-Ds*x-Es
  yfl <- loess(yf~x,span=.5)

  # assumes there are enough points that the maximum there is 'close enough' to 
  #  the true maximum

  yflf   <- yfl$fitted    
  locmax <- yflf==max(yflf)
  Bs     <- x[locmax]
  As     <- yflf[locmax]

  qs     <- yflf>.6*As
  ys     <- yfl$fitted[qs]
  xs     <- x[qs]-Bs
  lf     <- lm(ys~xs+I(xs^2))
  bets   <- lf$coefficients
  Bso    <- Bs
  Bs     <-  Bso-bets[2]/bets[3]/2
  Cs     <- sqrt(-1/bets[3])
  ystart <- As*exp(-((x-Bs)/Cs)^2)+Ds*x+Es

  y1a <- y1-As*exp(-((x-Bs)/Cs)^2)
  tr  <- theilreg(x,y1a)
  Ds  <- tr[2]
  Es  <- tr[1]
  res <- data.frame(As=As, Bs=Bs, Cs=Cs, Ds=Ds, Es=Es)
  res
}

.

# population parameters: A = 1.9947 , B = 10, C = 2.828, D = 0.09, E = 5
# generate some data
set.seed(seed=3424921)
x  <- runif(50,1,30)
y  <- dnorm(x,10,2)*10+rnorm(50,0,.2)
y1 <- y+5+x*.09 # This is the data
xo <- order(x)

starts <- gausslin.start(x,y1)
ystart <- with(starts, As*exp(-((x-Bs)/Cs)^2)+Ds*x+Es)
plot(x,y1)
lines(x[xo],ystart[xo],col=2)

有一种通用的方法可以拟合这类非线性模型。它涉及使用因变量的值重新参数化线性参数,例如第一个、最后一个频率值和中间的一个好点,例如第 6 个点。然后您可以将这些参数固定并在最小化的第一阶段求解非线性参数,然后最小化总共 5 个参数。

Schnute 和我在 1982 年左右为鱼类拟合生长模型时发现了这一点。

http://www.nrcresearchpress.com/doi/abs/10.1139/f80-172

然而,没有必要阅读这篇论文。由于参数是线性的,因此只需建立和求解 3x3 线性方程组即可使用模型的稳定参数化。

对于您的模型,线性部分由矩阵确定M

M=(exp(((x(1)B)/C)2)x(1)1exp(((x(6)B)/C)2)x(6)1exp(((x(n)B)/C)2)x(n)1)
在哪里n=20在这种情况下。1 代码是在 AD Model Builder 中编写的,现在是开源的。它进行自动微分并支持许多使非线性优化更容易的事情,例如不同参数保持固定的阶段。

DATA_SECTION
  init_int n
  int mid
 !! mid=6;
  init_matrix data(1,n,1,3)
  vector x(1,n)
  vector y(1,n)
 !! x=column(data,1);
 !! y=column(data,3);   //use column 3
PARAMETER_SECTION
  init_number L1(3)     //(3) means estimate in phase 3
  init_number Lmid(3)
  init_number Ln(3)

  vector L(1,3)
  init_number log_B       // estimate in phase 1
  init_number log_C(2)    // estimate in phase 2 
  matrix M(1,3,1,3);
  objective_function_value f
  sdreport_vector P(1,3)
  sdreport_number B
  sdreport_number C
  vector pred(1,n);
PROCEDURE_SECTION
  L(1)=L1;
  L(2)=Lmid;
  L(3)=Ln;
  B=exp(log_B);
  C=exp(log_C);
  M(1,1)=exp(-square((x(1)-B)/C));
  M(1,2)=x(1);
  M(1,3)=1;
  M(2,1)=exp(-square((x(mid)-B)/C));
  M(2,2)=x(mid);
  M(2,3)=1;
  M(3,1)=exp(-square((x(n)-B)/C));
  M(3,2)=x(n);
  M(3,3)=1;

  P=solve(M,L);  // solve for standard parameters 
                 // P is vector corresponding to A,D,E

  pred=P(1)*exp(-square((x-B)/C))+P(2)*x+P(3);
  if (current_phase()<4)
    f+=norm2(y-pred);
  else
    f+=0.5*n*log(norm2(y-pred))  //concentrated likelihood

该模型适合三个阶段。仅在阶段 1B估计。这里最重要的是C足够大,以便模型可以“看到”移动的位置B到。在第 2 阶段BC 估计。最后在第 3 阶段估计所有参数。在图中,绿线是第 1 阶段之后的拟合,蓝线是最终拟合。

在此处输入图像描述

对于您使用不良数据的情况,它很容易拟合,并且(通常的)参数估计是:

         estimate    std dev
A      2.0053e-01 5.8723e-02
D      1.6537e-02 4.7684e-03
E     -1.8197e-01 7.3355e-02
B      3.0609e+00 5.0197e-01
C      5.6154e+00 9.4564e-01]

如果您必须多次这样做,那么我建议您在 SSE 函数上使用进化算法作为前端来提供起始值。

另一方面,您可以使用 GEOGEBRA 使用滑块创建函数,并使用它们来获取起始值。

或者数据的起始值可以通过观察来估计。

  1. D 和 E 来自数据的斜率和截距(忽略高斯)
  2. A 是高斯最大值与 Dx+E 线估计的垂直距离。
  3. B是高斯最大值的x值
  4. C 是高斯表观宽度的一半

对于起始值,您可以进行普通的最小二乘拟合。它的斜率和截距将是 D 和 E 的起始值。最大残差将是 A 的起始值。最大残差的位置将是 B 的起始值。也许其他人可以建议 sigma 的起始值。

然而,在没有从主题知识中推导出任何类型的机械方程的情况下,非线性最小二乘法是有风险的,并且进行大量单独的拟合会使事情变得更加可疑。您提出的方程式背后是否有任何主题知识?是否还有其他独立变量与 100 个左右的单独拟合之间的差异有关?如果您可以将这些差异合并到一个可以同时拟合所有数据的方程中,这可能会有所帮助。