library(MASS)
data(cpus)
library(rpart)

# tree, with cp=0.001, using reduction in RSS criterion
formula =  log(perf) ~ syct + mmin + mmax + cach + chmin + chmax
treeFit = rpart(formula, data=cpus, method="anova", cp = 0.001)


# calculate R^2
nullSS = sum((log(cpus$perf)-mean(log(cpus$perf)))^2)
100*(1-sum(residuals(treeFit)^2)/nullSS)

# linear model fit R^2
summary(lm(formula, data=cpus))$r.squared

# CP plot
plotcp(treeFit)
stuff=printcp(treeFit)

# Draw tree
plot(treeFit)
text(treeFit, cex=0.8)

# prune tree
treeFitPruned = prune(treeFit, cp=0.0054)
plotcp(treeFitPruned)


# Predict using tree
newdata = cpus[200:201,-c(1,8,9)]
rownames(newdata) = 1:2
predict(treeFitPruned, newdata=newdata)


# neural network
library(nnet)
# scale data 
cpu = cpus[,-1] # delete computer names
cpu$logperf = log(cpu$perf)
cpu = cpu[,-c(7,8)]  # drop perf, estperf
cpuScaled = data.frame(scale(cpu))

formula =  logperf ~ syct + mmin + mmax + cach + chmin + chmax
nnFit = nnet(formula, data=cpuScaled, size=3, linout=TRUE, 
                         decay = 0.01, maxit=500 )
# residuals vs fitted values
plot(predict(nnFit), residuals(nnFit))

# R2
nullSS = sum((cpuScaled$logperf-mean(cpuScaled$logperf))^2)
100*(1-sum(residuals(nnFit)^2)/nullSS)
summary(lm(formula, data=cpus))


summary

# Predict using neural net

newdata = cpuScaled[200:201,-c(7,8)]
rownames(newdata) = 1:2
newdata
predict(nnFit, newdata=newdata)