估计 S 形曲线直线部分的斜率

机器算法验证 估计 密度函数 曲线拟合 逻辑曲线
2022-03-03 23:44:02

我被赋予了这个任务并且被难住了。一位同事让我估计下图的xupperxlower

在此处输入图像描述

曲线实际上是一个累积分布,x 是某种测量值。他有兴趣知道当累积函数开始变直并偏离直线时,x 上的对应值是多少。

我知道我们可以使用微分来找到某个点的斜率,但我不太确定如何确定何时可以将直线称为直线。任何对一些已经存在的方法/文献的轻推将不胜感激。

如果您碰巧知道有关此类调查的任何相关软件包或示例,我也知道 R。

非常感谢。


更新

感谢 Flounderer,我能够进一步扩展工作,建立一个框架,并在这里和那里修改参数。出于学习目的,这里是我当前的代码和图形输出。

library(ESPRESSO)

x <- skew.rnorm(800, 150, 5, 3)
x <- sort(x)
meanX <- mean(x)
sdX <- sd(x)
stdX <- (x-meanX)/sdX
y <- pnorm(stdX)

par(mfrow=c(2,2), mai=c(1,1,0.3,0.3))
hist(x, col="#03718750", border="white", main="")

nq <- diff(y)/diff(x)
plot.ts(nq, col="#6dc03480")

log.nq <- log(nq)
low <- lowess(log.nq)
cutoff <- .7
q <- quantile(low$y, cutoff)
plot.ts(log.nq, col="#6dc03480")
abline(h=q, col="#348d9e")

x.lower <- x[min(which(low$y > q))]
x.upper <- x[max(which(low$y > q))]
plot(x,y,pch=16,col="#03718750", axes=F)
axis(side=1)
axis(side=2)
abline(v=c(x.lower, x.upper),col="red")
text(x.lower, 1.0, round(x.lower,0))
text(x.upper, 1.0, round(x.upper,0))

在此处输入图像描述

1个回答

这是基于@alex 建议的快速而肮脏的想法。

#simulated data
set.seed(100)
x <- sort(exp(rnorm(1000, sd=0.6)))
y <- ecdf(x)(x)

它看起来有点像你的数据。现在的想法是查看导数并尝试查看它最大的位置。这应该是曲线中最直的部分,因为它是 S 形。

NQ <- diff(y)/diff(x)
plot.ts(NQ)

这是摇摆不定的,因为某些值恰好非常接近。但是,获取日志会有所帮助,然后您可以使用平滑版本。x

log.NQ <- log(NQ)
low <- lowess(log.NQ)
cutoff <- 0.75
q <- quantile(low$y, cutoff)
plot.ts(log.NQ)
abline(h=q)

现在您可以尝试像这样找到x

x.lower <- x[min(which(low$y > q))]
x.upper <- x[max(which(low$y > q))]
plot(x,y)
abline(v=c(x.lower, x.upper))

在此处输入图像描述

当然,整个事情最终对cutoff平滑算法的选择和平滑算法的选择以及对日志的选择都很敏感,当我们本可以进行一些其他转换时。此外,对于真实数据,的随机变化也可能导致此方法出现问题。导数在数值上表现不佳。编辑:添加了输出图片。y