我有几个数据集(实际上有数百个),我知道可以使用几个正态累积分布的总和(参见here)。
以下是此类数据集的一个示例,此处包含两个累积分布函数:
library(pracma)
library(minpack.lm)
x <- seq(1, 1000, length.out = 50)
k1 <- 0.5
mu1 <- 500
sigma1 <- 100
y1 <- k1 * (1 + erf((x - mu1) / (sqrt(2) * sigma1)))
k2 <- 0.5
mu2 <- 300
sigma2 <- 50
y2 <- k2 * (1 + erf((x - mu2) / (sqrt(2) * sigma2)))
my.df <- data.frame(x, y = y1 + y2, type = "data")
ggplot(my.df, aes(x, y)) + geom_line()
现在我想要拟合这些曲线,所以我使用nls
来完成:
model <- nlsLM(y ~ k1 * (1 + erf((x - mu1) / (sqrt(2) * sigma1)))
+ k2 * (1 + erf((x - mu2) / (sqrt(2) * sigma2))),
start= c(mu1 = 500 , sigma1 = 50, k1 = 0.5,
mu2 = 300 , sigma2 = 50, k2 = 0.5),
data = my.df,
control = nls.lm.control(maxiter = 500))
tmp <- data.frame(x, y = predict(model), type = "fit")
combined <- rbind(my.df, tmp)
ggplot(combined, aes(x, y, colour = type, shape = type)) + geom_line() + geom_point()
这是我得到的:
合身很棒。但是,我帮助了nls
:
为了解决第一点问题,我计算了一个,两个和三个函数的3个模型,并选择具有最小偏差的模型。
对于第二点,遗憾的是我的数百个数据集的参数变化很大,当我为所有集合提供相同的起始参数时,我的结果令人失望。
有没有更好的方法来选择这些起始值?
我听说过mixtools
库,但我不确定它是否适用于CDF(累积分发函数)。