问题描述
无法进行正确的线性外推。这是图表。
很明显,外推应该减少,因为左边有点在顶部,而在右边,一切都在底部,而且有很多。示例数据。
1.12.2010;6700
5.12.2010;330000
8.12.2010;45300
12.12.2010;15400
5.05.2011;5300
31.05.2011;1500
2.06.2011;11400
24.11.2011;51000
19.03.2012;3300
....
我使用以下脚本绘制图形。
#! /usr/bin/gnuplot -persist
set terminal postscript eps enhanced color solid
set output "result.ps"
set grid xtics ytics
set datafile separator ";"
set xtics rotate by 45 right
set grid xtics ytics
set xdata time
set timefmt "%d.%m.%Y"
# The equation
f(x) = a*x + b
fit f(x) "q.csv" u 1:2 via a,b
plot "q.csv" using 1:2 title "DATA" with p linestyle 3 lt 7 lw 2,\
f(x) w l lt 1 lw 2 title "trendline"
这里是在很多地方描述的进行线性外推的部分。 For example,here. 好像逻辑规定它应该工作,但不起作用......
# The equation
f(x) = a*x + b
fit f(x) "q.csv" u 1:2 via a,b
我做错了什么?
我tested it。尝试了那里提供的内容,它对我没有帮助。我就是这样做的。
# find out the StartDate
StartDate = "1.12.2010" # manually by setting a value
f(x) = a*(x-StartDate) + b
set fit brief nolog
b=10
fit f(x) "q.csv" u 1:2 via a,b
set key top left
set format x "%d.%m.%Y" timedate
plot "q.csv" u 1:2 ti "Data" with linespoints linestyle 1 pt 7 ps 1,\
f(x) w l lc rgb "red" ti "Fit"
解决方法
拟合失败主要是因为 (1) 一般的 Marquardt-Levenberg 算法不是解决线性最小二乘问题的最佳算法,以及 (2) a
和 b
的结果解不同几个数量级。
对于处理(2),你可以用a
和b
的初始值进行实验,试试
a = 0.001
b = 150000
这应该会有所帮助。但如果不是,您可以通过在运行 fit
命令之前通过设置以下变量将 Marquardt-Levenberg“转换”为一步高斯-牛顿来处理(1)(参见 help set fit
或 {{ 1}} 用于旧版本的 gnuplot):
help fit control variables
请注意,gnuplot 仍然需要两个步骤:一个用于找到解决方案,另一个用于验证它是否已经收敛。
正如@theozh 指出的那样,使用 set fit lambda_factor 1
set fit start_lambda 0.00001
### or for older versions of gnuplot
# FIT_START_LAMBDA=0.00001
# FIT_LAMBDA_FACTOR=1
通常有助于移动 x 值。像这样缩放参数也可能有帮助:f(x) = a*(x-StartDate) + b
。或者可以尝试将两者结合起来,或者...