library(readr)
library(FNN)

##### Validation functions:
apk <- function(k, actual, predicted)
{
  score <- 0.0
  cnt <- 0.0
  predicted <- strsplit(predicted," ")[[1]]
  for (i in 1:min(k,length(predicted)))
  {
    if (predicted[i] %in% actual && !(predicted[i] %in% predicted[0:(i-1)]))
    {
      cnt <- cnt + 1
      score <- score + cnt/i 
    }
  }
  score <- score / min(length(actual), k)
  score
}

mapk <- function (k, actual, predicted)
{
  if( length(actual)==0 || length(predicted)==0 ) 
  {
    return(0.0)
  }
  
  scores <- rep(0, length(actual))
  for (i in 1:length(scores))
  {
    scores[i] <- apk(k, actual[i], predicted[i])
  }
  score <- mean(scores)
  score
}

print("...loading train data")
train_data <- read_delim('../input/train.csv', ",")

print("...manipulating data")
train_data$place_id <- as.factor(train_data$place_id)

val_days <- 7
val_rows <- train_data$time>=(546-val_days)*60*24 # latest val_days worth of records in the training data
print("Proportion of data used for validation:")
sum(val_rows)/length(val_rows)
tr_rows <- (!val_rows)
print("Proportion of data used for training:")
sum(tr_rows)/length(tr_rows)

print("...splitting data")
train_data.tr <- train_data[tr_rows,]
train_data.val <- train_data[val_rows,]

knn_vars <- c("x","y")

print("...fitting kNN to validation sample")
fit_time <- system.time(
    train_data.preds <- knn(train = train_data.tr[,knn_vars],
                            test = train_data.val[,knn_vars],
                            cl = train_data.tr$place_id,
                            algorithm = "kd_tree",
                            k = 30)
)
print("Model fit time:")
print(fit_time)
print("...calculating score")
print(paste("score =",mapk(k = 3,actual = as.character(train_data.val[["place_id"]]),predicted = as.character(train_data.preds))))

print("...loading test data")
test_data <- read_delim('../input/test.csv', ",")

print(paste("Estimated test data fit time = ",fit_time[[3]]*nrow(test_data)/sum(val_rows),"s",sep=""))

#print("...fitting kNN to test data")
#test_data.preds <- knn(train = train_data[,knn_vars],
#                        test = test_data[,knn_vars],
#                        cl = train_data$place_id,
#                        algorithm = "kd_tree",
#                        k = 30)
#
#submission <- data.frame(row_id=test_data$row_id)
#submission$place_id <- test_data.preds
#write.csv(submission,file="submission.csv",row.names=F)


