Earth Timing Tests
Here is a table of some timing tests.
ozone 9x330
nk degree earth ------------------time ratios----------------------------- ------------------grsq------------------------
time mars minspan=1 no-fastk fastk=10 fastk=5 no-bcache allowed earth mars minspan=1 no-fastk fastk=10 fastk=5
21 1 0.021 0.96 1.1 1.0 1.0 1.0 1.1 1.0 0.77 0.77 0.77 0.77 0.77 0.77
21 2 0.059 1.6 1.3 1.0 0.97 0.68 1.3 1.1 0.79 0.78 0.79 0.79 0.79 0.79
21 3 0.074 1.4 1.3 1.0 0.84 0.6 1.3 1.1 0.8 0.79 0.79 0.8 0.8 0.8
21 10 0.077 1.4 1.3 1.0 0.82 0.59 1.3 1.1 0.8 0.79 0.79 0.8 0.8 0.8
51 1 0.032 1.9 1.6 1.0 1.0 1.0 1.2 1.1 0.78 0.77 0.78 0.78 0.78 0.78
51 2 0.25 2.6 1.3 1.0 0.74 0.43 1.7 1.1 0.8 0.8 0.81 0.8 0.81 0.8
51 3 0.32 3 1.4 1.3 0.61 0.34 1.7 1.1 0.82 0.8 0.81 0.81 0.81 0.8
51 10 0.34 3.3 1.4 1.5 0.63 0.38 1.6 1.1 0.81 0.82 0.82 0.81 0.8 0.8
101 1 0.034 2.0 1.9 1.0 1.0 1.0 1.2 1.1 0.78 0.77 0.78 0.78 0.78 0.78
101 2 0.65 3.9 1.5 1.0 0.67 0.33 2.1 1.1 0.81 0.8 0.82 0.81 0.8 0.82
101 3 0.86 5.5 1.6 1.8 0.53 0.28 2.0 1.1 0.82 0.83 0.81 0.82 0.82 0.8
101 10 0.85 8.5 1.5 2.7 0.62 0.35 1.9 1.1 0.83 0.83 0.81 0.83 0.83 0.81
robot arm 30x3000
nk degree earth ------------------time ratios----------------------------- ------------------grsq------------------------
time mars minspan=1 no-fastk fastk=10 fastk=5 no-bcache allowed earth mars minspan=1 no-fastk fastk=10 fastk=5
21 1 0.24 1.9 1.2 1.0 1.0 0.98 1.1 0.98 0.78 0.79 0.78 0.78 0.78 0.78
21 2 1.3 1.5 1.6 1.0 1.0 0.68 1.3 1.0 0.9 0.9 0.89 0.9 0.9 0.9
21 3 2.2 1.6 1.4 1.0 0.8 0.52 1.3 1.0 0.91 0.9 0.9 0.91 0.91 0.9
21 10 2.4 1.6 1.4 1.0 0.77 0.47 1.3 1.0 0.91 0.9 0.9 0.91 0.91 0.9
51 1 0.23 8 1.4 1.1 1.1 1.0 1.2 1.1 0.78 0.79 0.78 0.78 0.78 0.78
51 2 5.5 2.3 1.4 1.0 0.89 0.29 1.6 1.0 0.94 0.94 0.95 0.94 0.94 0.91
51 3 11 2.5 1.5 1.2 0.55 0.16 1.6 1.1 0.97 0.96 0.97 0.97 0.96 0.92
51 10 12 3.1 1.5 1.5 0.57 0.32 1.6 1.0 0.97 0.96 0.97 0.97 0.96 0.94
101 1 0.24 14 1.3 1.0 1.1 1.1 1.3 1.1 0.78 0.79 0.78 0.78 0.78 0.78
101 2 5.9 11 1.4 1.0 0.89 0.28 1.6 1.0 0.94 0.95 0.95 0.94 0.94 0.91
101 3 16 11 1.4 1.1 0.47 0.11 1.6 1.0 0.97 0.98 0.97 0.97 0.96 0.92
101 10 19 14 1.4 1.2 0.38 0.22 1.6 1.0 0.98 0.98 0.97 0.97 0.96 0.94
201 1 0.25 14 1.3 1.1 1.2 1.2 1.2 1.2 0.78 0.79 0.78 0.78 0.78 0.78
201 2 6.3 66 1.3 1.0 0.89 0.28 1.5 1.0 0.94 0.95 0.95 0.94 0.94 0.91
201 3 17 91 1.4 1.1 0.47 0.11 1.6 1.0 0.97 0.99 0.97 0.97 0.96 0.92
201 10 20 139 1.4 1.3 0.38 0.22 1.6 1.0 0.98 1.0 0.97 0.97 0.96 0.94
The reference model for each line is earth with default arguments and with minspan=0
(i.e. automatically calculate the minimum span as per the MARS paper).
Note that the default fastk is 20.
The times in the "earth time" column are in seconds.
The "mars" columns are for the Hastie/Tibshirani implementation mda:mars.
The time ratios are relative to the earth reference model.
Smaller means faster i.e. small values are better.
The ozone data is the ozone1 data included with the earth package. It has 330 cases and 9 predictors.
The robot arm is from Friedman's Fast MARS paper, with 3000 cases and
25 noise predictors in addition to the 5 original predictors.
The measurements were made using R 2.6-1 and earth 1.2-2 on a 3 Ghz Pentium running Windows XP.
Here is the code to generate the results above:
# earth-times.R
library(earth)
data(ozone1)
library(mda) # for mars
test <- function(nk, degree, use.ozone) {
if (use.ozone) {
# example of a small model: 9 predictors 330 cases
x = ozone1[,-1]
y = ozone1[,1]
niters <- 100
} else {
# example of a bigger model: 30 predictors 3000 cases
robotArm <- function(x) { # lifted from Friedman's Fast MARS paper
x. <- with(x, l1 * cos(theta1) - l2 * cos(theta1 + theta2) * cos(phi))
y <- with(x, l1 * sin(theta1) - l2 * sin(theta1 + theta2) * cos(phi))
z <- with(x, l2 * sin(theta2) * sin(phi))
sqrt(x.^2 + y^2 + z^2)
}
set.seed(1) # for reproducibility
ncases <- 3000
l1 <- runif(ncases, 0, 1)
l2 <- runif(ncases, 0, 1)
theta1 <- runif(ncases, 0, 2 * pi)
theta2 <- runif(ncases, 0, 2 * pi)
phi <- runif(ncases, -pi/2, pi/2)
x <- cbind(l1, l2, theta1, theta2, phi)
for (i in 1:25) # 25 dummy vars, so 30 vars in total
x <- cbind(x, runif(ncases, 0, 1))
x <- data.frame(x)
y <- robotArm(x)
niters <- 5
}
e.time <- system.time(e <- for (i in 1:niters)
earth(x, y, nk=nk, degree=degree, minspan=0))
gcv.null <- e$gcv.per.subset[1]
e.grsq <- 1 - e$gcv/gcv.null
e.minspan1.time <- system.time(e.minspan1 <- for (i in 1:niters)
earth(x, y, nk=nk, degree=degree, minspan=1))
e.fastk0.time <- system.time(e.fastk0 <- for (i in 1:niters)
earth(x, y, nk=nk, degree=degree, minspan=0, fast.k=0))
e.fastk10.time <- system.time(e.fastk10 <- for (i in 1:niters)
earth(x, y, nk=nk, degree=degree, minspan=0, fast.k=10))
e.fastk5.time <- system.time(e.fastk5 <- for (i in 1:niters)
earth(x, y, nk=nk, degree=degree, minspan=0, fast.k=5))
e.nobcache.time <- system.time(e.nobcache <- for (i in 1:niters)
earth(x, y, nk=nk, degree=degree, minspan=0, Use.beta.cache=FALSE))
# dummy func to estimate time taken by an "allowed" function
allowed <- function(degree, pred, parents)
{
if (degree > 0 && (parents[1] == 999 || pred == 999))
return(FALSE) # never get here
TRUE
}
e.allowed.time <- system.time(e.allowed <- for (i in 1:niters)
earth(x, y, nk=nk, degree=degree, minspan=0, allowed=allowed))
m.time <- system.time(m <- for (i in 1:niters)
mars(x, y, degree=degree, nk=nk))
m.grsq <- 1 - m$gcv/gcv.null
options(digits=2)
cat("\t ",
nk, "\t",
degree, "\t",
e.time[1] / niters, "\t",
m.time[1] / e.time[1], "\t",
e.minspan1.time[1] / e.time[1], "\t\t",
e.fastk0.time[1] / e.time[1], "\t",
e.fastk10.time[1] / e.time[1], "\t",
e.fastk5.time[1] / e.time[1], "\t",
e.nobcache.time[1] / e.time[1], "\t",
e.allowed.time[1] / e.time[1], "\t ",
e.grsq, "\t",
m.grsq, "\t",
e.minspan1$grsq, "\t",
e.fastk0$grsq, "\t",
e.fastk10$grsq, "\t",
e.fastk5$grsq, "\n")
}
cat("data nk degree earth ")
cat("------------------time ratios--------------------------------- ")
cat("------------------grsq--------------------------\n")
cat(" time ")
cat("mars minspan=1 no-fastk fastk=10 fastk=5 no-bcache allowed ")
cat("earth mars minspan=1 no-fastk fastk=10 fastk=5\n")
cat("ozone 9x330\n");
test(nk=21, degree=1, use.ozone=1)
test(nk=21, degree=2, use.ozone=1)
test(nk=21, degree=3, use.ozone=1)
test(nk=21, degree=10, use.ozone=1)
cat("\n")
test(nk=51, degree=1, use.ozone=1)
test(nk=51, degree=2, use.ozone=1)
test(nk=51, degree=3, use.ozone=1)
test(nk=51, degree=10, use.ozone=1)
cat("\n")
test(nk=101, degree=1, use.ozone=1)
test(nk=101, degree=2, use.ozone=1)
test(nk=101, degree=3, use.ozone=1)
test(nk=101, degree=10, use.ozone=1)
cat("\nrobot arm 30x3000\n");
test(nk=21, degree=1, use.ozone=0)
test(nk=21, degree=2, use.ozone=0)
test(nk=21, degree=3, use.ozone=0)
test(nk=21, degree=10, use.ozone=0)
cat("\n")
test(nk=51, degree=1, use.ozone=0)
test(nk=51, degree=2, use.ozone=0)
test(nk=51, degree=3, use.ozone=0)
test(nk=51, degree=10, use.ozone=0)
cat("\n")
test(nk=101, degree=1, use.ozone=0)
test(nk=101, degree=2, use.ozone=0)
test(nk=101, degree=3, use.ozone=0)
test(nk=101, degree=10, use.ozone=0)
cat("\n")
test(nk=201, degree=1, use.ozone=0)
test(nk=201, degree=2, use.ozone=0)
test(nk=201, degree=3, use.ozone=0)
test(nk=201, degree=10, use.ozone=0)
To earth homepage