Gnuplot - 如何忽略拟合的异常值?

问题描述 投票:0回答:1

我开始使用 Gnuplot 并尝试了一些东西。现在,我想知道如何自动从拟合中删除异常值。图中显示了一个示例,其中数据点位于第二个数据集的 4,50 处。 以及数据集:

我发现了一个类似的问题here,但我无法让它适用于我的示例。可能有很多不同的方法,而且我对 Gnuplot 或类似软件没有那么丰富的经验。因此,我很高兴收到建议,描述异常值的可能方法是什么。

我在 Windows 10 上的 LaTeX (texlive) 中使用 gnuplottex 包。 gnuplot 代码:

\begin{gnuplot}[terminal=tikz, terminaloptions={color size 7cm,5cm}]
reset session

$Data <<EOD
#data
x   y1  y2  y3  y4
1   1   6   4   2   
2   4   10  1   1   
3   9   15  0   0.5 
4   16  50  1   2   
5   25  31  4   5   
6   36  42  9   12  
7   49  55  30  23
EOD

datafile = 'data.dat'
set print 'parameters.dat'

#_____________Set the label for data points________________________
set key top left                            # set position of legend
set key Left                                # set raggedleft
set key samplen 2 spacing 1.2 font ",8" # set fontsize and spacing
set key noautotitle 

###1__________Define function and number of columns_________________________
f(x,a,b,c) = a*(x-b)**2 + c
colMin = 2
colMax = 5
set fit quiet nolog
array A[colMax]
array B[colMax]
array C[colMax]

do for [col=colMin:colMax] {
    a=1; b=1; c=4            # some initial values, sometimes 0 or NaN is not a good start
    fit f(x,a,b,c) datafile u 1:col via a,b,c
    A[col] = a;  B[col] = b;  C[col] = c
    
    print sprintf ('%d %.4f %.4f %.4f',col-1,A[col],B[col],C[col])
}

plot for [col=colMin:colMax] datafile u 1:col ls col, \
     for [col=colMin:colMax] f(x,A[col],B[col],C[col]) ls col, \
     for [col=colMin:colMax] keyentry w lp ls col \ 
     title sprintf("$y%d$",col-1)
\end{gnuplot}
gnuplot outliers
1个回答
0
投票

正如评论中提到的,您必须以某种方式定义您认为的异常值。当然有几种方法可以做到这一点。我并不是说这是最好的方法,只是将其视为一个起点。

一些评论:

  • 您对所有数据点进行拟合
  • 定义绝对距离
    OutlierDist
    您认为的异常值
  • 将数据绘制到表格中
    $NOOUTLIERS
    ,如果到拟合曲线的绝对距离是
    >=OutlierDist
    ,则将
    NaN
    写入第二列,将原始值写入第三列。
  • 现在,第二次拟合(没有异常值)
  • 绘制数据、拟合曲线(第二次拟合)以及异常值(如果需要)

这当然可以优化。

数据:

"SO77774328.dat

x   y1  y2  y3  y4
1    1    6   4    2
2    4   10   1    1
3    9   15   0    0.5
4   16   50   1    2
5   25   31   4    5
6   36   42   9   12
7   49   55  30   23

脚本:

### remove outliers for fitting
reset session

FILE     = "SO77774328.dat"
PARAMS_1 = "SO77774328_1.par"
PARAMS_2 = "SO77774328_2.par"

f(x,a,b,c) = a*(x-b)**2 + c
colMin = 2
colMax = 5
set fit quiet nolog
array A[colMax]
array B[colMax]
array C[colMax]

set print PARAMS_1
do for [col=colMin:colMax] {
    a=1; b=1; c=4            # some initial values, sometimes 0 or NaN is not a good start
    fit f(x,a,b,c) FILE u 1:col via a,b,c
    A[col] = a;  B[col] = b;  C[col] = c
    print sprintf ('%d %.4f %.4f %.4f',col-1,A[col],B[col],C[col])
}
unset print

# write data to table with outliers --> NaN
OutlierDist = 10   # outlier distance
dev(colX,colY) = abs(column(colY)-f(column(colX),A[colY],B[colY],C[colY])-1) >= OutlierDist ? NaN :  column(colY)
set table $NOOUTLIERS
    do for [colY=colMin:colMax] {
        plot FILE u 1:(v0=dev(1,colY)):(v0!=v0?column(colY):NaN) lc var
    }
unset table

# fit again
set print PARAMS_2
do for [col=colMin:colMax] {
    i = col-colMin   # datablock index
    a=1; b=1; c=4            # some initial values, sometimes 0 or NaN is not a good start
    fit f(x,a,b,c) $NOOUTLIERS index i u 1:2 via a,b,c
    A[col] = a;  B[col] = b;  C[col] = c
    print sprintf ('%d %.4f %.4f %.4f',col-1,A[col],B[col],C[col])
}
unset print

set key noautotitle left top

plot for [col=colMin:colMax] FILE u 1:col ls col-1, \
     for [col=colMin:colMax] f(x,A[col],B[col],C[col]) ls col-1, \
     for [col=colMin:colMax] keyentry w lp ls col-1 title sprintf("y%d",col-1), \
     $NOOUTLIERS u 1:(valid(2) ? NaN : column(3)) w p pt 6 ps 2 lc "red" ti "Outlier"
### end of script

结果:

© www.soinside.com 2019 - 2024. All rights reserved.