You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gnuplot拟合时如何自动忽略异常值?

Gnuplot拟合时自动剔除异常值的实用方案

针对你拟合二次函数时遇到的异常点(比如y2列的(4,50))干扰拟合结果的问题,以下是几种可直接落地的解决方案:

方案1:基于残差迭代过滤异常值

核心思路是先完成一次初始拟合,计算每个数据点的残差(实际值与拟合值的差值),以3倍标准差作为阈值剔除残差超标的点,再用清洗后的数据集重新拟合,确保拟合结果不受异常点干扰。

适配你的gnuplottex环境的修改后代码:

\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

set print 'parameters.dat'

# 图例设置
set key top left Left samplen 2 spacing 1.2 font ",8" noautotitle

# 定义拟合函数
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]
array residuals[7]  # 存储7个数据点的残差

do for [col=colMin:colMax] {
    a=1; b=1; c=4
    # 第一次初始拟合
    fit f(x,a,b,c) $Data u 1:col via a,b,c
    
    # 计算残差并统计标准差
    stats $Data u (residuals[$0+1] = abs(column(col) - f(column(1),a,b,c))) nooutput
    threshold = 3 * STATS_stddev  # 以3倍标准差作为异常值阈值
    
    # 创建清洗后的临时数据集
    $CleanData <<EOD
EOD
    do for [i=1:7] {
        if (residuals[i] <= threshold) {
            stats $Data u 1:col every ::i-1::i-1 nooutput
            print sprintf("%d %.4f", STATS_x, STATS_y) >> $CleanData
        }
    }
    
    # 用清洗后的数据集重新拟合
    fit f(x,a,b,c) $CleanData 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])
}

plot for [col=colMin:colMax] $Data 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}

方案2:加权拟合削弱异常值影响

如果不想完全剔除点,可以通过加权方式降低异常点的影响力:给残差小的点设置高权重,残差大的点设置低权重,让拟合过程更偏向正常数据。

修改拟合逻辑的代码片段:

do for [col=colMin:colMax] {
    a=1; b=1; c=4
    # 初始拟合获取残差基准
    fit f(x,a,b,c) $Data u 1:col via a,b,c
    
    # 定义权重规则:残差越小权重越高,加0.1避免除以0
    weight(x,y) = 1/(abs(y - f(x,a,b,c)) + 0.1)
    
    # 执行加权拟合
    fit f(x,a,b,c) $Data u 1:col:(weight($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])
}

方案3:手动指定排除规则(适合已知异常特征)

如果你明确知道某些点是异常(比如y2列x=4的点),可以直接在拟合时针对性排除,适合场景简单的情况:

修改拟合行的代码片段:

do for [col=colMin:colMax] {
    a=1; b=1; c=4
    # 针对y2列(col=3)排除x=4的点,其他列正常拟合
    if (col == 3) {
        fit f(x,a,b,c) $Data u 1:col not (column(1) == 4) via a,b,c
    } else {
        fit f(x,a,b,c) $Data 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])
}

内容的提问来源于stack exchange,提问作者Konstantin Weigmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 15:15:59