求教一个最小二乘法曲线拟合的问题

公共马甲0315 2011-08-04 03:44:25
我很费解的是像这样的复合函数式:y = a*exp(b*x)+c + f(x),又是如何进行曲线拟合的呢?其中的f(x)是一个关于x的线性多项式,可以使一次式或是二次式的。这个表达式好像无法线性化的,又是怎么来进行最小二乘法拟合的呢?

我不明白为什么matlab/origin就能够得到这样的复合拟合结果函数式,但是想自己写个小程序来计算,在网上却找不到合适的算法?

希望能指点下,给加100分,谢谢!
...全文
1122 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
fanfan_im 2011-08-29
  • 打赏
  • 举报
回复
origin用的是Levenberg-Marquardt算法,标准的非线性最小二乘算法。
E文够好的话:
这里有一个免费的Levenberg-Marquardt算法C语言实现:
http://www.ics.forth.gr/~lourakis/levmar/
关于算法的具体细节,可以看看:
http://www.nrbook.com/a/bookcpdf.php
第15.5节。
fire_woods 2011-08-23
  • 打赏
  • 举报
回复
一般的迭代都是先定義誤差函數.
迭代的目標是誤差函數收斂到極小值.

迭代一般採用先選取一個起始點, 在起始點確定方向與步長, 然後移動到下一個點作為新的點, 一直循環, 直到目標函數的值收斂.

迭代的方向一般選擇的是對各個變量當前點的偏導數, 各個算法不同的地方是在步長的選擇上.
fire_woods 2011-08-22
  • 打赏
  • 举报
回复
楼主可以看一下非线性最小二乘问题.
一般是用迭代法来求解的.
kerbcurb 2011-08-22
  • 打赏
  • 举报
回复
这个不是什么难问题,难的是你转不过弯来!
假设你一定要包含sqrt(x+c*x*x),展开式中无非多了这些项:x^0.5, x^1.5, x^2.5,...的项。
让t = x^2,加上其他的项,还是一个多项式。
公共马甲0315 2011-08-22
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 newtttttt 的回复:]

泰勒展式是有问题的,比如这个函数式:
y = a + b*sqrt(x+c*x*x);(100<x<2000)
展开为:
y = a + b*sqrt(c)*x + b/(2*sqrt(c)) - b/(c^3/2*x) + b/[16*c^5/2*x*x] - 5*b/[128*c^7/2*x*x*x] + ...
从数学上看没问题,但是实际测量结果是c*x*x只是个修正项,是可以忽略的;而简化的表达式为
y = a + b*sqrt(x)
但是展式中完全没有了体现?
[/Quote]
这个我还展错了,根本就没办法把根式下的x分离出来的,求导后每一项都有根式的。
cnmhx 2011-08-22
  • 打赏
  • 举报
回复
非线性优化。
公共马甲0315 2011-08-22
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 fire_woods 的回复:]

楼主可以看一下非线性最小二乘问题.
一般是用迭代法来求解的.
[/Quote]
谢谢!能不能具体一点儿,怎么迭代的?网上的资料太简略了,一些个文献就给个泛泛的收敛结果,没有一点儿算法相关的东西呀?
超级大笨狼 2011-08-08
  • 打赏
  • 举报
回复
求几次导数,就可以过滤掉一些常数项和多项式,剩余指数方程先可以得到。
cnmhx 2011-08-06
  • 打赏
  • 举报
回复
指数关系具有scaling law。
而趋势向没有,所以将指数和线性趋势的分离不难。
你画个图就知道了!
bourbaki 2011-08-05
  • 打赏
  • 举报
回复
有个fortran版本,比lm算法好,不会丢弃二阶导数项

http://www.mirrorservice.org/sites/netlib.bell-labs.com/netlib/toms/573.gz
bourbaki 2011-08-05
  • 打赏
  • 举报
回复
csdn资源里能下到 c数值算法 的电子版和代码。
bourbaki 2011-08-05
  • 打赏
  • 举报
回复
matlab里有个函数lsqcurvefit,实现了这个算法。

数值分析教材里一般也有,比如Timothy Sauer的数值分析。

或者用levenberg-marquardt方法,这个在William H. Press的 C数值算法ch15.5.2里有,代码也现成。
kerbcurb 2011-08-05
  • 打赏
  • 举报
回复
最小二乘可以这样做:你测的N个点的x和y,假设你用一个M次多项式拟合这批数据,一般N>M;
计算xi从零次方到M次方,生成一个行向量(有M+1个元素),N个xi的这种行向量生成一个N*(M + 1)矩阵A,用B表示yi组成的列向量,你要求的未知系数组成的列向量用F(有M+1个元素)表示,所以:
A*F = B

假设AT表示A的转置,用AT左乘上面的方程:(AT*A)*F = (AT*B),(AT*A)是一个方阵,一般是满秩的,因此可以求解。
kerbcurb 2011-08-05
  • 打赏
  • 举报
回复
你不能光想:a*exp(b*x)+c + f(x)中的a,b,c以及f(x)中的系数怎么求。

拟合本身就是近似的,所以你可以先把exp(b*x)级数展开,取有限项作为近似,然后把a*exp(b*x)+c + f(x)近似用一个多项式代替,求的这个多项式的系数。下一步在把这个多项式弄成上面的形式,这个弄的过程,你可以利用经验观察、也可以计算。
公共马甲0315 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bourbaki 的回复:]

Gauss–Newton algorithm
[/Quote]
能具体一点儿吗?我只查到一篇英文的,讲得很粗糙,看不太懂哈。
bourbaki 2011-08-05
  • 打赏
  • 举报
回复
Gauss–Newton algorithm
公共马甲0315 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 cnmhx 的回复:]

先拟合 y = a*exp(b*x)+c ;
然后对残差再消除趋势项。
[/Quote]
但问题是,你知道哪个函数表达式是小比例的?
y=f(x)+g(x),可能是f(x)是个残差,也可能g(x)才是残差呀?这个这个好像不好掌握哈
bourbaki 2011-08-05
  • 打赏
  • 举报
回复
我没有研究过这个代码,只是教材里参考文献里的。
kerbcurb 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 newtttttt 的回复:]

引用 9 楼 kerbcurb 的回复:

你不能光想:a*exp(b*x)+c + f(x)中的a,b,c以及f(x)中的系数怎么求。

拟合本身就是近似的,所以你可以先把exp(b*x)级数展开,取有限项作为近似,然后把a*exp(b*x)+c + f(x)近似用一个多项式代替,求的这个多项式的系数。下一步在把这个多项式弄成上面的形式,这个弄的过程,你可以利用经验观察、也可以计算。
……
[/Quote]
我不知道你的例子和你的问题是否相关,
但是应该明白:a*exp(b*x)+c + f(x)这个和y = a + b*sqrt(x+c*x*x);(100<x<2000)在一定的范围内一定是可以用多项式近似拟合的。
公共马甲0315 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 bourbaki 的回复:]

有个fortran版本,比lm算法好,不会丢弃二阶导数项

http://www.mirrorservice.org/sites/netlib.bell-labs.com/netlib/toms/573.gz
[/Quote]
谢谢,但是这个算法有拟合误差σ或是卡方χ的计算吗?
加载更多回复(6)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧