```{r}
library(data.table)
library(Matrix)
library(xgboost)
```


Create validation set and undersampled training data
```{r load data}
set.seed(1221)
train <- fread("../input/train.csv",
               showProgress = FALSE)
               
val <- which(grepl("11-09", train$click_time) == T)
val <- sample(val, 20 * 10 ^ 6)

pos <- which(train$is_attributed == 1)
pos <- setdiff(pos, val)
             
neg <- which(train$is_attributed == 0)
neg <- setdiff(neg, val)
neg <- sample(neg, length(pos))

under <- train[c(pos, neg), ]
valid <- train[val, ]

rm(train)
gc(reset = T)


```


Create sparse matrices directly from categorical values
```{r create sparse matrices}
to_sparse <- function(vec) {
  sparseMatrix(i = 1:length(vec),
               j = vec + 1,
               x = 1,
               dims = c(length(vec), 5000))
}  

create_X <- function(dt) {
  cBind(to_sparse(dt$ip),
        to_sparse(dt$app),
        to_sparse(dt$device),
        to_sparse(dt$os),
        to_sparse(dt$channel))
}

X_under <- create_X(under)
Y_under <- under$is_attributed
rm(under)

X_valid <- create_X(valid)
Y_valid <- valid$is_attributed
rm(valid)
```


Xgboost
```{r xgboost}
dunder  <- xgb.DMatrix(X_under, label = Y_under)
dvalid  <- xgb.DMatrix(X_valid, label = Y_valid)
watchlist <- list(train = dunder, valid = dvalid)

param <- list(max_depth = 10,
              eta = 1,
              objective = "binary:logistic",
              eval_metric = "auc")

bst <- xgb.train(param,
                 dunder,
                 nrounds = 1000,
                 print_every_n = 100,
                 watchlist)

rm(X_under, X_valid, Y_under, Y_valid, dunder, dvalid)
```


Apply to test
```{r predict}
test <- fread("../input/test.csv",
              select = c("click_id","ip", "app", "channel", "device", "os"),
              showProgress = FALSE)

X_test <- create_X(test)

pred <- data.table(click_id = test$click_id,
                   is_attributed = predict(bst, X_test))

head(pred)

fwrite(pred, "pred.csv")
```