library(tidyverse) 
require(lightgbm)

train <- read_csv("../input/train.csv") 
test <- read_csv("../input/test.csv") 

tid <- test$id

idx <- 1:nrow(train)

target <- train$scalar_coupling_constant

tr_te <- train %>% 
    select(-scalar_coupling_constant) %>% 
    bind_rows(test) %>% 
    left_join(read_csv('../input/structures.csv'), by = c("molecule_name", "atom_index_0" = "atom_index")) %>% 
    left_join(read_csv('../input/structures.csv'), by = c("molecule_name", "atom_index_1" = "atom_index")) %>% 
    select(-id) %>% 
    mutate(
        same_atom = as.numeric(atom.x==atom.y),
        HH = 1*(atom.x =="H" & atom.y =="H"),
        HC = 1*(atom.x =="H" & atom.y =="C"),
        HN = 1*(atom.x =="H" & atom.y =="N"),
        x_dist = x.x - x.y, 
        y_dist = y.x - y.y,  
        z_dist = z.x - z.y,
        atom_dist = sqrt(x_dist^2 + y_dist^2 + z_dist^2)
) %>% select(-atom.x, -atom.y) 

tr_te_type <- tr_te$type
types <- unique(tr_te_type)

rm(train, test); gc()

cat("tr_te ready \n")

tr_te <- tr_te %>% 
    left_join(
        tr_te %>% 
        group_by(type) %>% 
        summarise(atom_dist_type = mean(atom_dist)
    ), by = "type") %>% 
    mutate(
        atom_dist_dif = atom_dist_type - atom_dist,
        atom_dist_resid = lm(atom_dist~., tr_te %>% select(-x.y, -molecule_name)) %>% resid()
    ) 
    
scc_by_csum_a1_a2 <- read_csv("../input/scalar_coupling_contributions.csv") %>% 
  left_join(read_csv("../input/scalar_coupling_contributions.csv") %>% group_by(molecule_name) %>% summarise(csum = n())) %>% 
  select(-molecule_name) %>% 
  group_by(csum, atom_index_0,atom_index_1,type) %>%
  summarise_all(funs(mean, sum, .args = list(na.rm = TRUE))) 
  
tr_te_by_mol <- tr_te  %>% 
  select(-type) %>% 
  group_by(molecule_name) %>%
  summarise_all(funs( mean, sum,  .args = list(na.rm = TRUE)) ) 
 
tr_te <- tr_te %>% 
  left_join(tr_te %>% group_by(molecule_name) %>% summarise(csum = n())) %>% 
  left_join(scc_by_csum_a1_a2) %>%  
  left_join(tr_te_by_mol) %>% 
  mutate(C1 = 1*(type == "1JHC"),
         N1 = 1*(type == "1JHN"), 
         C2 = 1*(type == "2JHC"), 
         H2 = 1*(type == "2JHH"), 
         N2 = 1*(type == "2JHN"),
         C3 = 1*(type == "3JHC"), 
         H3 = 1*(type == "3JHH"), 
         N3 = 1*(type == "3JHN")) %>% 
  select(-molecule_name, -type) 
 
rm(scc_by_csum_a1_a2, tr_te_by_mol)
    
cat("joins ready \n")
    
rm(cnts); gc()
    
#from this kernel: https://www.kaggle.com/artgor/molecular-properties-eda-and-models
params <- list(learning_rate = 0.2,
               boosting_type = 'gbdt',
               objective = "regression",
               metric = 'mae',
               nthread = 8,
               sub_feature = 1,
               bagging_fraction = 0.85,
               bagging_freq = 1,
               num_leaves = 128, 
               min_split_gain = 0.01,
               min_data = 50,
               reg_alpha = 0.13,
               reg_lambda = 0.36,
               min_hessian = 0.001
)

pred_lgb <- as.matrix(0*(data.frame(read_csv("../input/sample_submission.csv") [,1])))
 
tr_te <- tr_te %>% 
  select(-C1,-N1,-C2,-H2,-N2,-C3,-H3,-N3) 

for (i in 1:8){
    print(i)
    tr_type <- (tr_te_type[idx] == types[i]) 
    te_type <- (tr_te_type[-idx] == types[i])
    nrounds <- round(sum(1*(tr_type==TRUE))/50)
    ltrain1 <- lgb.Dataset(data = tr_te[idx, ][tr_type,] %>% select_if(is.numeric) %>% data.matrix() , label = target[tr_type] )  
    ltest1 <- tr_te[-idx, ][te_type,] %>% select_if(is.numeric) %>% data.matrix()   

    lgb_train_oc = lgb.train(params = params, ltrain1, nrounds = nrounds, categorical_feature = c( "atom_index_0", "atom_index_1"))
    pred_lgb[te_type==T] = predict(lgb_train_oc,ltest1 )
}

read_csv("../input/sample_submission.csv") %>%  
  mutate(scalar_coupling_constant = pred_lgb) %>%
  write_csv("subm_te_pred_light_gbm.csv")