【问题标题】:Linear Fit does not adjust b independently form a线性拟合不单独调整 b 形成 a
【发布时间】:2014-06-20 00:06:51
【问题描述】:

我正在使用以下 gnuplot 脚本来绘制线性拟合:

#!/usr/bin/gnuplot
set term cairolatex
set output "linear_fit.tex"
c = 299792458.
x(x) = c / x
y(x) = x
h(x) = a * x + b
fit h(x) "linear_fit.dat" u (x($1)):(y($2)) via a,b
plot "linear_fit.dat" u (x($1)):(y($2)) w points title "", \
    (h(x)) with lines linecolor rgb "black" title "Linear Fit"

但是,在迭代收敛后,b 始终为 1.0:https://dpaste.de/ozReq/

如何让 gnuplot 调整 b 和 a?

更新: 重复 fit 命令几百次并交替使用 via a/via b 确实会产生很好的结果,但这不可能是应该的。

更新2:这是linear_fit.dat中的数据:

# lambda, V
360e-9 1.119
360e-9 1.148
360e-9 1.145
400e-9 0.949
400e-9 0.993
400e-9 0.971
440e-9 0.883
440e-9 0.875
440e-9 0.863
490e-9 0.737
490e-9 0.728
490e-9 0.755
540e-9 0.575
540e-9 0.571
540e-9 0.592
590e-9 0.457
590e-9 0.455
590e-9 0.482

【问题讨论】:

  • 能否提供linear_fit.dat 的样本和一组典型的命令行输入$1$2,好吗?我只是用“自制”linear_fit.dat 尝试了这个,但无法重现您的观察结果。
  • @Schorsch 我用linear_fit.dat 的链接更新了问题。 $1$2 不是指命令行输入,它只是表示gnuplot 应该使用输入数据集的第一列和第二列。

标签: gnuplot


【解决方案1】:

我认为您的麻烦源于您的x-值非常大(大约为10e14)。

如果您没有为 gnuplot 提供 ab 的初始猜测,它将假定 a=1b=1 作为拟合的起点。然而,这是一个糟糕的初步猜测:

请注意x- 和y- 轴上的对数刻度。
来自gnuplot documentation

如果从一个解开始时拟合可能并且经常会“丢失”,其中 SSR 很大并且随着参数的变化而缓慢变化,或者它可能会到达数值不稳定的区域(例如,太大的数字导致浮点溢出)导致“未定义值”消息或 gnuplot 停止。

为了提高找到全局最优值的机会,您应该将起始值至少大致设置在解的附近,例如,如果可能的话,在一个数量级内。您的起始值越接近解决方案,停止在另一个最小值的机会就越小。找到起始值的一种方法是将数据和拟合函数绘制在同一张图上,然后更改参数值并重新绘制,直到达到合理的相似性。相同的图也可用于检查拟合是否因拟合不佳而至少停止。

在你的情况下,这样的起始值可能是:

a = 1e-15
b = -0.5

我通过目测your range of values获得了这些值。
有了这些起始值,线性拟合的结果是:

Final set of parameters            Asymptotic Standard Error
=======================            ==========================

a               = 1.97355e-015     +/- 6.237e-017   (3.161%)
b               = -0.5             +/- 0.04153      (8.306%)

看起来像这样:

您可以使用fit 的控制设置(例如设置FIT_LIMIT = 1.e-35)或起始值来实现比这更好的拟合。


编辑

虽然我仍然无法诱使 gnuplot 同时修改 ab 两个参数,但我找到了使用 R 的替代方法。我知道还有许多其他(脚本)语言可以可以执行线性拟合,这个问题是关于 gnuplot 的。但是,使用 R 所需的工作似乎很少。
这是一个示例,当保存为 linear_fit.R 并使用

调用时
R CMD BATCH linear_fit.R 

将提供 gnuplot 未能提供的两个线性拟合系数。

y <- c(1.119, 1.148, 1.145, 0.949, 0.993, 0.971, 0.883, 0.875, 0.863, 
       0.737, 0.728, 0.755, 0.575, 0.571, 0.592, 0.457, 0.455, 0.482)
x <- c(3.60E-007, 3.60E-007, 3.60E-007, 4.00E-007, 4.00E-007, 
       4.00E-007, 4.40E-007, 4.40E-007, 4.40E-007, 4.90E-007, 
       4.90E-007, 4.90E-007, 5.40E-007, 5.40E-007, 5.40E-007, 
       5.90E-007, 5.90E-007, 5.90E-007)
c = 299792458.
x <- c/x
lm.out <- lm(y ~ x)
svg("linear_fit.svg")
plot(x,y) 
abline(lm.out,col="red")
summary(lm.out)

您最终会得到一个包含绘图的svg 文件和一个linear_fit.Rout 文本文件。在那里你会发现以下系数:

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -5.429e-01  4.012e-02  -13.53 3.55e-10 ***
x            2.037e-15  6.026e-17   33.80 2.61e-16 ***

因此,在原始问题的术语中,我们得到:

a =  2.037e-15
b = -5.429e-01

这些值与您在交替拟合时引用的值非常接近。


如果 cmets 被清除,这些问题被确定为相关:

What is gnuplot's internal representation of floating point numbers?

Gnuplot behaves oddly in polynomial fit. Why is that?

【讨论】:

  • 不幸的是,这不是它应该的样子。它应该如下所示:i.imgur.com/IGwRHZ1.png。 via a 和 via b 之间交替拟合 1000 次后得到的结果。
  • @KlemensBaum 请看我修改后的答案
  • 感谢您抽出时间再次调查此问题。为b 设置一个好的初始值会产生更好的结果,但gnuplot 再一次根本没有尝试更改b(它仍然是-0.5 适合您之后)。我很困惑为什么它一直忽略第二个变量。这可能是gnuplot 中的一个错误,还是我们都忽略了一些重要的事情?您会认为线性拟合是一项经过广泛测试的功能。仅供参考,我通过“交替拟合”方法获得的值是 a = 2.03705e-15b = -0.542891
  • @KlemensBaum 我认为问题在于这两个值的大小差异如此之大。如果您在文档中阅读更多内容,则会提到 gnuplot 会出现问题。我认为1e-15 非常接近0 的浮点表示。也许,正如我最初提出的那样,缩放会更快地产生更好的结果(对于我的试验具有更连贯的数量级,它会改变 ab
  • 根据this questiongnuplot 内部使用双精度数,这意味着即使一些小于1e-307 的数字也可以表示。即使要使用单精度浮点数,1e-37 也是可以表示的。由于这些数量级在科学数据中非常常见,gnuplot 确实应该支持它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 2015-01-31
相关资源
最近更新 更多