【问题标题】:Why do geom_smooth nls and the standalone nls give different fit results?为什么 geom_smooth nls 和独立 nls 给出不同的拟合结果?
【发布时间】:2021-02-01 12:36:25
【问题描述】:

当我使用 geom_smooth nls 拟合我的数据时,我得到了一个非常好的拟合。但是,如果我使用独立的 nls 函数使用相同的方程和起始值来拟合我的数据,我得到的拟合效果要差得多。我想提取拟合参数,所以真的需要独立的 nls 来生成与 geom_smooth nls 相同的拟合。

对可能发生的事情有任何建议/提示吗?


df <- data.frame("x" = c(4.63794469, 1.54525711, 0.51508570, 0.17169523, 0.05737664, 5.11623138, 1.70461130, 0.56820377, 0.18940126, 0.06329358, 0.02109786), 
                 "y" = c(0.1460101, 0.7081954, 0.9619413, 1.0192286, 1.0188301, 0.3114495, 0.7602488, 0.8205661, 0.9741323, 1.0922553, 1.1130464))

fit <- nls(data = df, y ~ (1/(1 + exp(-b*x + c))), start = list(b=1, c=0))
df$stand_alone_fit <- predict(fit, df)

df %>% ggplot() +
  geom_point(aes(x = x, y = y)) +
  scale_x_log10() +
  ylim(0,1.2) +
  geom_smooth(aes(x = x, y = y), method = "nls", se = FALSE, 
              method.args = list(formula = y ~ (1/(1 + exp(-b*x + c))), start = list(b= 1, c=0))) +
  geom_line(aes(x = x, y = stand_alone_fit), color = "red") +
  labs(title = "Blue: geom_smooth nls fit\nRed: stand alone nls fit")

【问题讨论】:

    标签: r ggplot2 data-fitting nls


    【解决方案1】:

    这里有两个问题,首先预测(红线)仅针对 x 点执行,导致曲线看起来很方正而不平滑。

    第二个问题的原因。两条拟合曲线不相等是因为由于这条线scale_x_log10() 在 x 轴上发生了变换,所以 geom_smooth 中的 nls 函数执行的拟合与独立拟合不同。

    看看移除 x 轴变换后会发生什么。 (绿线是来自外部拟合的更精细的预测)。

    df <- data.frame("x" = c(4.63794469, 1.54525711, 0.51508570, 0.17169523, 0.05737664, 5.11623138, 1.70461130, 0.56820377, 0.18940126, 0.06329358, 0.02109786), 
                     "y" = c(0.1460101, 0.7081954, 0.9619413, 1.0192286, 1.0188301, 0.3114495, 0.7602488, 0.8205661, 0.9741323, 1.0922553, 1.1130464))
    
    
    fit <- nls(data = df, y ~ (1/(1 + exp(-b*x + c))), start = list(b=0, c=0))
    df$stand_alone_fit <- predict(fit, df)
    
    #finer resolution (green line)
    new <- data.frame(x=seq(0.02, 5.1, 0.1))
    new$y <-predict(fit, new)
    
    df %>% ggplot() +
       geom_point(aes(x = x, y = y)) +
    #   scale_x_log10() +
       ylim(0,1.2) +
       geom_smooth(aes(x = x, y = y), method = "nls", se = FALSE, 
                   method.args = list(formula = y ~  (1/(1 + exp(-b*x + c))), start = list(b=0, c=0))) +
       geom_line(aes(x = x, y = stand_alone_fit), color = "red") +
       geom_line(data=new, aes(x, y), color="green") +
       labs(title = "Blue: geom_smooth nls fit\nRed: stand alone nls fit")
    

    或者在你原来的 ggplot 定义中使用这个:method.args = list(formula = y ~ (1/(1 + exp(-b*10^(x) + 2*c))), start = list(b=-1, c=-3)))

    【讨论】:

    • 太棒了!太感谢了。即使在 scale_x_log10() 之后,在拟合之前对数据进行对数转换也使我得到与 geom_smooth 相同的拟合(我想用对数比例绘制)。
    猜你喜欢
    • 2017-07-29
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 2011-05-21
    • 2016-11-07
    • 2017-04-19
    • 1970-01-01
    相关资源
    最近更新 更多