########################################################################################
# Prepare data for land use change from anything to low-density residential (i.e., code change as 1 and 0 otherwise)
########################################################################################
# library(caret)
# library(mgcv)

training_To_1$lu2006 = factor(training_To_1$lu2006)
training_To_1$lc2010 = factor(training_To_1$lc2010)
training_To_1$lc2006 = factor(training_To_1$lc2006)
training_To_1$Response = factor(training_To_1$Response)

testing_To_1$lu2006 = factor(testing_To_1$lu2006)
testing_To_1$lc2010 = factor(testing_To_1$lc2010)
testing_To_1$lc2006 = factor(testing_To_1$lc2006)
testing_To_1$Response = factor(testing_To_1$Response)

training_To_1_data = data.frame(training_To_1[,-1])
testing_To_1_data = data.frame(testing_To_1[,-1])
dim(training_To_1_data) # 609 35
dim(testing_To_1_data) # 261 35

# Remove:
# F_lu3 and F_lu4 only contain one 1 (column #:27, 28)
# F_lu5, F_lu6 and F_lu10 contain only 0's (column #:29, 30, 34)
training_To_1_data1.2 = training_To_1_data[,-c(2,3,27:30,34)]
testing_To_1_data1.2 = testing_To_1_data[,-c(2,3,27:30,34)]

############################################
# set up trainControl and grid
############################################
# using train() to conduct gam
ctrl = trainControl(method="none", savePredictions=TRUE)
grid = data.frame(method="GCV.Cp", select=FALSE)

############################################
# doing the spatial CV manually
############################################
set.seed(123)
GAM_To_1_folds = createFolds(training_To_1_data1.2$Response, k=10,list = TRUE, returnTrain = TRUE)

# fold 1
set.seed(123)
GAM_To_1_fld1 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[1]],], 
                      method="gam", family="binomial",
                      trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld1_pred <- predict(GAM_To_1_fld1, newdata=training_To_1_data1.2[-GAM_To_1_folds[[1]],])
GAM_To_1_fld1_CM = confusionMatrix(factor(GAM_To_1_fld1_pred), training_To_1_data1.2[-GAM_To_1_folds[[1]],]$Response) 
(GAM_To_1_fld1_Acc = GAM_To_1_fld1_CM$overall[[1]])

# fold 2
set.seed(123)
GAM_To_1_fld2 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[2]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld2_pred <- predict(GAM_To_1_fld2, newdata=training_To_1_data1.2[-GAM_To_1_folds[[2]],])
GAM_To_1_fld2_CM = confusionMatrix(factor(GAM_To_1_fld2_pred), training_To_1_data1.2[-GAM_To_1_folds[[2]],]$Response)
(GAM_To_1_fld2_Acc = GAM_To_1_fld2_CM$overall[[1]])

# fold 3
set.seed(123)
GAM_To_1_fld3 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[3]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld3_pred <- predict(GAM_To_1_fld3, newdata=training_To_1_data1.2[-GAM_To_1_folds[[3]],])
GAM_To_1_fld3_CM = confusionMatrix(factor(GAM_To_1_fld3_pred), training_To_1_data1.2[-GAM_To_1_folds[[3]],]$Response) 
(GAM_To_1_fld3_Acc = GAM_To_1_fld3_CM$overall[[1]])

# fold 4
set.seed(123)
GAM_To_1_fld4 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[4]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld4_pred <- predict(GAM_To_1_fld4, newdata=training_To_1_data1.2[-GAM_To_1_folds[[4]],])
GAM_To_1_fld4_CM = confusionMatrix(factor(GAM_To_1_fld4_pred), training_To_1_data1.2[-GAM_To_1_folds[[4]],]$Response)
(GAM_To_1_fld4_Acc = GAM_To_1_fld4_CM$overall[[1]])

# fold 5
set.seed(123)
GAM_To_1_fld5 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[5]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld5_pred <- predict(GAM_To_1_fld5, newdata=training_To_1_data1.2[-GAM_To_1_folds[[5]],])
GAM_To_1_fld5_CM = confusionMatrix(factor(GAM_To_1_fld5_pred), training_To_1_data1.2[-GAM_To_1_folds[[5]],]$Response)
(GAM_To_1_fld5_Acc = GAM_To_1_fld5_CM$overall[[1]])

# fold 6
set.seed(123)
GAM_To_1_fld6 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[6]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld6_pred <- predict(GAM_To_1_fld6, newdata=training_To_1_data1.2[-GAM_To_1_folds[[6]],])
GAM_To_1_fld6_CM = confusionMatrix(factor(GAM_To_1_fld6_pred), training_To_1_data1.2[-GAM_To_1_folds[[6]],]$Response) 
(GAM_To_1_fld6_Acc = GAM_To_1_fld6_CM$overall[[1]])

# fold 7
set.seed(123)
GAM_To_1_fld7 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[7]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld7_pred <- predict(GAM_To_1_fld7, newdata=training_To_1_data1.2[-GAM_To_1_folds[[7]],])
GAM_To_1_fld7_CM = confusionMatrix(factor(GAM_To_1_fld7_pred), training_To_1_data1.2[-GAM_To_1_folds[[7]],]$Response) 
(GAM_To_1_fld7_Acc = GAM_To_1_fld7_CM$overall[[1]])

# fold 8
set.seed(123)
GAM_To_1_fld8 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[8]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld8_pred <- predict(GAM_To_1_fld8, newdata=training_To_1_data1.2[-GAM_To_1_folds[[8]],])
GAM_To_1_fld8_CM = confusionMatrix(factor(GAM_To_1_fld8_pred), training_To_1_data1.2[-GAM_To_1_folds[[8]],]$Response) 
(GAM_To_1_fld8_Acc = GAM_To_1_fld8_CM$overall[[1]])

# fold 9
set.seed(123)
GAMTo_1_fld9 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[9]],], 
                         method="gam", family="binomial",
                         trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAMTo_1_fld9_pred <- predict(GAMTo_1_fld9, newdata=training_To_1_data1.2[-GAM_To_1_folds[[9]],])
GAMTo_1_fld9_CM = confusionMatrix(factor(GAMTo_1_fld9_pred), training_To_1_data1.2[-GAM_To_1_folds[[9]],]$Response) 
(GAMTo_1_fld9_Acc = GAMTo_1_fld9_CM$overall[[1]])

# fold 10
set.seed(123)
GAM_To_1_fld10 <- train(Response~., data=training_To_1_data1.2[GAM_To_1_folds[[10]],], 
                          method="gam", family="binomial",
                          trControl=ctrl, tuneGrid=grid, metric="Accuracy")
GAM_To_1_fld10_pred <- predict(GAM_To_1_fld10, newdata=training_To_1_data1.2[-GAM_To_1_folds[[10]],])
GAM_To_1_fld10_CM = confusionMatrix(factor(GAM_To_1_fld10_pred), training_To_1_data1.2[-GAM_To_1_folds[[10]],]$Response) 
(GAM_To_1_fld10_Acc = GAM_To_1_fld10_CM$overall[[1]])

GAM_To_1_Acc = c(GAM_To_1_fld1_Acc, GAM_To_1_fld2_Acc, GAM_To_1_fld3_Acc, 
                 GAM_To_1_fld4_Acc, GAM_To_1_fld5_Acc, GAM_To_1_fld6_Acc,
                 GAM_To_1_fld7_Acc, GAM_To_1_fld8_Acc, GAMTo_1_fld9_Acc, GAM_To_1_fld10_Acc)
(GAM_To_1_meanAcc = mean(GAM_To_1_Acc))
# 0.6584779

#######################################################
# find out which fold returns the highest accuracy
which(GAM_To_1_Acc == max(GAM_To_1_Acc)) # 1
# choose GAM model with fold 1
summary(GAM_To_1_fld1)
# lu2006+lc2006+lc2010+s(DA_Area)+s(lu4_dist)+s(LRoad_dist)+s(MRoad_dist)

set.seed(123)
GAM_To_1_final = gam(Response ~ lu2006+lc2006+lc2010+s(DA_Area)+s(lu4_dist)+s(LRoad_dist)+s(MRoad_dist), 
                       data = training_To_1_data1.2[GAM_To_1_folds[[1]],], family=binomial(link=logit))
summary(GAM_To_1_final)
# remove lu4_dist
GAM_To_1_final2 = gam(Response ~ lu2006+lc2006+lc2010+s(DA_Area)+s(LRoad_dist)+s(MRoad_dist), 
                      data = training_To_1_data1.2[GAM_To_1_folds[[1]],], family=binomial(link=logit))
summary(GAM_To_1_final2)

anova(GAM_To_1_final, GAM_To_1_final2, test="Chisq") # 0.09562, prefer final2

GAM_To_1_final2_pred=predict(GAM_To_1_final2,newdata=testing_To_1_data1.2, type="response")
GAM_To_1_final2_pred[which(GAM_To_1_final2_pred<0.5)] <- 0
GAM_To_1_final2_pred[which(GAM_To_1_final2_pred>=0.5)] <- 1
confusionMatrix(factor(GAM_To_1_final2_pred), testing_To_1_data1.2$Response) # 0.7011
