We use multiple real datasets:
data(AirPassengers)
data(nottem)
data(sunspots)
data(EuStockMarkets)
ap <- AirPassengers
temp <- nottem
ss <- sunspots
stocks <- EuStockMarkets[,1]
We explore curve fitting techniques using a modified exponential model:
t <- 1:length(ap)
y <- as.numeric(ap)
fit_exp <- lm(log(y) ~ t)
a <- exp(coef(fit_exp)[1])
b <- exp(coef(fit_exp)[2])
fitted_exp <- a*b^t
plot(t, y, pch=16, col="blue", cex=0.7,
main="Exponential Fit (points = actual)",
xlab="t (months)", ylab="Passengers")
lines(t, fitted_exp, col="red", lwd=2)
legend("topleft", legend=c("Actual (points)", "Fitted (curve)"),
col=c("blue","red"), pch=c(16,NA), lty=c(NA,1), lwd=c(NA,2), bty="n")
y2 <- as.numeric(nottem)
t2 <- 1:length(y2)
fit2 <- lm(log(y2 - min(y2) + 1) ~ t2) # shift to avoid log(<=0)
a2 <- exp(coef(fit2)[1]); b2 <- exp(coef(fit2)[2])
fitted2 <- a2*b2^t2 + min(y2) - 1
plot(t2, y2, pch=16, col="blue", cex=0.6,
main="Exponential Fit on nottem (shows misfit)",
xlab="t", ylab="Temperature")
lines(t2, fitted2, col="red", lwd=2)
We study the Gompertz curve, a flexible growth model often used in time series analysis:
The Gompertz curve is a type of sigmoid function, expressed as:
\[ y_t = A \cdot \exp\left(-B \cdot \exp(-C \cdot t)\right) \]
Where: - \(y_t\) — observed value at
time \(t\)
- \(A\) — upper asymptote (maximum
attainable value)
- \(B\) — displacement parameter
(shifts the curve along the time axis)
- \(C\) — growth rate parameter
(controls speed of growth)
# ---------- SAFE GOMPERTZ FIT ----------
t <- 1:length(y)
# Scale time to avoid overflow
t_scaled <- t / max(t)
gompertz_model <- nls(
y ~ K * exp(-A * exp(-b * t_scaled)),
start = list(
K = max(y) * 1.2,
A = 5,
b = 5
),
algorithm = "port",
lower = c(K = max(y), A = 0.001, b = 0.001),
upper = c(K = 10000, A = 100, b = 100),
control = nls.control(maxiter = 500, warnOnly = TRUE)
)
summary(gompertz_model)
##
## Formula: y ~ K * exp(-A * exp(-b * t_scaled))
##
## Parameters:
## Estimate Std. Error t value Pr(>|t|)
## K 2159.991 1751.060 1.23 0.21943
## A 2.954 0.751 3.94 0.00013 ***
## b 0.691 0.283 2.44 0.01579 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 44.9 on 141 degrees of freedom
##
## Algorithm "port", convergence message: relative convergence (4)
fitted_gom <- predict(gompertz_model)
plot(ap, col="darkgreen", lwd=2,
main="Gompertz Curve Fit (Stable Version)")
lines(fitted_gom, col="orange", lwd=2)
legend("topleft",
legend=c("Observed","Gompertz Fit"),
col=c("darkgreen","orange"),
lwd=2, bty="n")