单变量、二元“loess”与“lowess”

Nut*_*tle 0 r loess

考虑以下数据:

probs <- seq(0,0.3, by=0.001)

targets <- sapply(probs, function(p){
  sample(c(0,1),size=1,prob = c(1-p,p))
})
Run Code Online (Sandbox Code Playgroud)

然后使用loess我可以将平滑的“目标”值绘制为概率估计:

require(magrittr)
loess(targets~probs,span=0.3) %>% predict %>% {plot(. ~ probs)}
Run Code Online (Sandbox Code Playgroud)

但是,无论选择lowess什么值,我都无法使用 来做到这一点:f

lowess(x = probs, y = targets, f = 0.01) %>% with(plot(y ~ x))
Run Code Online (Sandbox Code Playgroud)

我的问题:为什么结果不同?有没有什么方法可以实现与lowess该输出loess相匹配的相同输出?

根据 SO 上的众多线程,对于单变量情况,loess 和 lowess 似乎应该匹配。


不相关的旁注:为什么我不使用loess呢?目标是了解lowess和之间的差异loess。此外,我想使用 Python 重新应用结果statsmodels,据我所知,Python 只提供lowess.

All*_*ron 5

使用以下方法更容易生成随机样本rbinom

probs <- seq(0, 0.3, by = 0.001)

set.seed(1)
targets <- rbinom(301, 1, probs)
Run Code Online (Sandbox Code Playgroud)

光滑loess的看起来像这样:

est_loess <- loess(targets ~ probs, span = 0.3) |> predict()

plot(probs, est_loess, type = "l") 
Run Code Online (Sandbox Code Playgroud)

如果您想要类似的结果lowess,请尝试设置iter为 0:

est_lowess <- lowess(x = probs, y = targets, f = 0.2, iter = 0) 

plot(est_lowess, type = "l")
Run Code Online (Sandbox Code Playgroud)

无论哪种情况,在平滑这样的概率时都要非常小心。您可能会面临出现超出 0-1 范围的无意义值的风险。在可能的情况下,您应该转换为赔率,平滑它们,然后转换回概率。实现此目的的一种方法是gam使用family = "binomial"

library(mgcv)

est_gam <- gam(targets ~ s(probs, k = 100, m = 1), gamma = 0.9,
               family = binomial) |>
  predict(type = "response")

plot(probs, est_gam, type = "l", ylim = c(0, 0.3))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

创建于 2023-09-06,使用reprex v2.0.2