From dcbd8c92b5c953cddffd645f056db3afbe53fee0 Mon Sep 17 00:00:00 2001 From: Laurae Date: Sun, 21 Jan 2018 13:21:11 +0100 Subject: [PATCH 1/6] Fix demos and add vignettes --- R-package/.Rbuildignore | 1 + R-package/DESCRIPTION | 15 +- R-package/R/lgb.Booster.R | 5 + R-package/R/lgb.unloader.R | 7 +- R-package/R/readRDS.lgb.Booster.R | 5 + R-package/R/saveRDS.lgb.Booster.R | 5 + R-package/demo/00Index | 2 +- R-package/demo/basic_walkthrough.R | 27 ++- R-package/demo/boost_from_prediction.R | 3 +- R-package/demo/categorical_features_prepare.R | 2 +- R-package/demo/categorical_features_rules.R | 2 +- R-package/demo/cross_validation.R | 1 + R-package/demo/early_stopping.R | 6 +- R-package/demo/efficient_many_training.R | 13 +- R-package/demo/leaf_stability.R | 9 +- R-package/demo/multiclass.R | 6 +- R-package/man/lgb.model.dt.tree.Rd | 1 + R-package/man/lgb.train.Rd | 4 +- R-package/man/lgb.unloader.Rd | 7 +- R-package/man/predict.lgb.Booster.Rd | 5 + R-package/man/readRDS.lgb.Booster.Rd | 5 + R-package/man/saveRDS.lgb.Booster.Rd | 5 + R-package/vignettes/basic_walkthrough.Rmd | 156 ++++++++++++++++++ R-package/vignettes/boost_from_prediction.Rmd | 45 +++++ .../categorical_features_prepare.Rmd | 91 ++++++++++ .../vignettes/categorical_features_rules.Rmd | 101 ++++++++++++ R-package/vignettes/cross_validation.Rmd | 66 ++++++++ R-package/vignettes/early_stopping.Rmd | 59 +++++++ .../vignettes/efficient_many_training.Rmd | 48 ++++++ R-package/vignettes/leaf_stability.Rmd | 139 ++++++++++++++++ R-package/vignettes/multiclass.Rmd | 77 +++++++++ R-package/vignettes/weight_param.Rmd | 110 ++++++++++++ 32 files changed, 993 insertions(+), 35 deletions(-) create mode 100644 R-package/.Rbuildignore create mode 100644 R-package/vignettes/basic_walkthrough.Rmd create mode 100644 R-package/vignettes/boost_from_prediction.Rmd create mode 100644 R-package/vignettes/categorical_features_prepare.Rmd create mode 100644 R-package/vignettes/categorical_features_rules.Rmd create mode 100644 R-package/vignettes/cross_validation.Rmd create mode 100644 R-package/vignettes/early_stopping.Rmd create mode 100644 R-package/vignettes/efficient_many_training.Rmd create mode 100644 R-package/vignettes/leaf_stability.Rmd create mode 100644 R-package/vignettes/multiclass.Rmd create mode 100644 R-package/vignettes/weight_param.Rmd diff --git a/R-package/.Rbuildignore b/R-package/.Rbuildignore new file mode 100644 index 000000000000..9ad5b5ec3b57 --- /dev/null +++ b/R-package/.Rbuildignore @@ -0,0 +1 @@ +^docs$ \ No newline at end of file diff --git a/R-package/DESCRIPTION b/R-package/DESCRIPTION index 66ca7dec6496..7404278744d8 100755 --- a/R-package/DESCRIPTION +++ b/R-package/DESCRIPTION @@ -2,8 +2,13 @@ Package: lightgbm Type: Package Title: Light Gradient Boosting Machine Version: 2.0.12 -Date: 2017-12-26 -Author: Guolin Ke +Date: 2018-01-21 +Authors@R: c(person("Guolin", "Ke", , "guolin.ke@microsoft.com", role = c("aut", "cre")), + person("Damien", "Soukhavong", , "damien.soukhavong@skema.edu", role = c("ctb")), + person("Yachen", "Yan", , "to_be_added_later@mail.com", role = c("ctb"))) +Author: Guolin Ke [aut, cre], + Damien Soukhavong [ctb], + Yachen Yan [ctb] Maintainer: Guolin Ke Description: LightGBM is a gradient boosting framework that uses tree based learning algorithms. It is designed to be distributed and efficient with the following advantages: @@ -28,10 +33,10 @@ Suggests: stringi (>= 0.5.2) Depends: R (>= 3.0), - R6 (>= 2.0) -Imports: + R6 (>= 2.0), methods, - Matrix (>= 1.1-0), + Matrix (>= 1.1-0) +Imports: data.table (>= 1.9.6), magrittr (>= 1.5), jsonlite (>= 1.0) diff --git a/R-package/R/lgb.Booster.R b/R-package/R/lgb.Booster.R index 1774d4e3874e..e3b965f76abe 100644 --- a/R-package/R/lgb.Booster.R +++ b/R-package/R/lgb.Booster.R @@ -625,6 +625,9 @@ Booster <- R6Class( #' #' @examples #' \dontrun{ +#' # It crashes the documentation generation, skipping +#' if (!(pkgdown::in_pkgdown())) { +#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -644,6 +647,8 @@ Booster <- R6Class( #' preds <- predict(model, test$data) #' } #' +#' } +#' #' @rdname predict.lgb.Booster #' @export predict.lgb.Booster <- function(object, data, diff --git a/R-package/R/lgb.unloader.R b/R-package/R/lgb.unloader.R index 0624e7847eec..991ba5c0ed3e 100644 --- a/R-package/R/lgb.unloader.R +++ b/R-package/R/lgb.unloader.R @@ -26,11 +26,14 @@ #' min_data = 1, #' learning_rate = 1, #' early_stopping_rounds = 10) -#' lgb.unloader(restore = FALSE, wipe = FALSE, envir = .GlobalEnv) +#' +#' # Disabled the following line as it crashes the documentation generator +#' # lgb.unloader(restore = FALSE, wipe = FALSE, envir = .GlobalEnv) #' rm(model, dtrain, dtest) # Not needed if wipe = TRUE #' gc() # Not needed if wipe = TRUE #' -#' library(lightgbm) +#' # Disabled the following line as it crashes the documentation generator +#' # library(lightgbm) #' # Do whatever you want again with LightGBM without object clashing #' } #' diff --git a/R-package/R/readRDS.lgb.Booster.R b/R-package/R/readRDS.lgb.Booster.R index e001800dea97..52a3dd16c3d8 100644 --- a/R-package/R/readRDS.lgb.Booster.R +++ b/R-package/R/readRDS.lgb.Booster.R @@ -9,6 +9,9 @@ #' #' @examples #' \dontrun{ +#' # It crashes the documentation generation, skipping +#' if (!(pkgdown::in_pkgdown())) { +#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -29,6 +32,8 @@ #' new_model <- readRDS.lgb.Booster("model.rds") #' } #' +#' } +#' #' @export readRDS.lgb.Booster <- function(file = "", refhook = NULL) { diff --git a/R-package/R/saveRDS.lgb.Booster.R b/R-package/R/saveRDS.lgb.Booster.R index 97083763bff8..6e2f25503904 100644 --- a/R-package/R/saveRDS.lgb.Booster.R +++ b/R-package/R/saveRDS.lgb.Booster.R @@ -14,6 +14,9 @@ #' #' @examples #' \dontrun{ +#' # It crashes the documentation generation, skipping +#' if (!(pkgdown::in_pkgdown())) { +#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -33,6 +36,8 @@ #' saveRDS.lgb.Booster(model, "model.rds") #' } #' +#' } +#' #' @export saveRDS.lgb.Booster <- function(object, file = "", diff --git a/R-package/demo/00Index b/R-package/demo/00Index index 9eb5d45a58f1..dea564f3ec8c 100644 --- a/R-package/demo/00Index +++ b/R-package/demo/00Index @@ -5,6 +5,6 @@ categorical_feature_rules Categorical Feature Preparation with Rules cross_validation Cross Validation early_stopping Early Stop in training efficient_many_training Efficiency for Many Model Trainings -multiclass Multiclass training/prediction leaf_stability Leaf (in)Stability example +multiclass Multiclass training/prediction weight_param Weight-Parameter adjustment relationship diff --git a/R-package/demo/basic_walkthrough.R b/R-package/demo/basic_walkthrough.R index a6f6c0639b5c..d799b839a4fb 100644 --- a/R-package/demo/basic_walkthrough.R +++ b/R-package/demo/basic_walkthrough.R @@ -22,6 +22,7 @@ bst <- lightgbm(data = train$data, num_leaves = 4, learning_rate = 1, nrounds = 2, + nthread = 1, objective = "binary") # Alternatively, you can put in dense matrix, i.e. basic R-matrix @@ -31,6 +32,7 @@ bst <- lightgbm(data = as.matrix(train$data), num_leaves = 4, learning_rate = 1, nrounds = 2, + nthread = 1, objective = "binary") # You can also put in lgb.Dataset object, which stores label, data and other meta datas needed for advanced features @@ -41,6 +43,7 @@ bst <- lightgbm(data = dtrain, num_leaves = 4, learning_rate = 1, nrounds = 2, + nthread = 1, objective = "binary") # Verbose = 0,1,2 @@ -49,6 +52,7 @@ bst <- lightgbm(data = dtrain, num_leaves = 4, learning_rate = 1, nrounds = 2, + nthread = 1, objective = "binary", verbose = 0) @@ -57,7 +61,7 @@ bst <- lightgbm(data = dtrain, num_leaves = 4, learning_rate = 1, nrounds = 2, - nthread = 2, + nthread = 1, objective = "binary", verbose = 1) @@ -66,7 +70,7 @@ bst <- lightgbm(data = dtrain, num_leaves = 4, learning_rate = 1, nrounds = 2, - nthread = 2, + nthread = 1, objective = "binary", verbose = 2) @@ -82,11 +86,16 @@ err <- mean(as.numeric(pred > 0.5) != test$label) print(paste("test-error=", err)) #--------------------Save and load models------------------------- -# Save model to binary local file -lgb.save(bst, "lightgbm.model") -# Load binary model to R -bst2 <- lgb.load("lightgbm.model") +if (!(pkgdown::in_pkgdown())) { + # Save model to binary local file + lgb.save(bst, "lightgbm.model") + + # Load binary model to R + bst2 <- lgb.load("lightgbm.model") +} else { + bst2 <- bst +} pred2 <- predict(bst2, test$data) # pred2 should be identical to pred @@ -109,7 +118,7 @@ bst <- lgb.train(data = dtrain, learning_rate = 1, nrounds = 2, valids = valids, - nthread = 2, + nthread = 1, objective = "binary") # We can change evaluation metrics, or use multiple evaluation metrics @@ -120,7 +129,7 @@ bst <- lgb.train(data = dtrain, nrounds = 2, valids = valids, eval = c("binary_error", "binary_logloss"), - nthread = 2, + nthread = 1, objective = "binary") # lgb.Dataset can also be saved using lgb.Dataset.save @@ -133,7 +142,7 @@ bst <- lgb.train(data = dtrain2, learning_rate = 1, nrounds = 2, valids = valids, - nthread = 2, + nthread = 1, objective = "binary") # information can be extracted from lgb.Dataset using getinfo diff --git a/R-package/demo/boost_from_prediction.R b/R-package/demo/boost_from_prediction.R index bd2b30e892c4..3429fb717b48 100644 --- a/R-package/demo/boost_from_prediction.R +++ b/R-package/demo/boost_from_prediction.R @@ -15,7 +15,7 @@ print("Start running example to start from a initial prediction") # Train lightgbm for 1 round param <- list(num_leaves = 4, learning_rate = 1, - nthread = 2, + nthread = 1, objective = "binary") bst <- lgb.train(param, dtrain, 1, valids = valids) @@ -32,4 +32,5 @@ print("This is result of boost from initial prediction") bst <- lgb.train(params = param, data = dtrain, nrounds = 5, + nthread = 1, valids = valids) diff --git a/R-package/demo/categorical_features_prepare.R b/R-package/demo/categorical_features_prepare.R index 236e88784042..576d845ae550 100644 --- a/R-package/demo/categorical_features_prepare.R +++ b/R-package/demo/categorical_features_prepare.R @@ -67,9 +67,9 @@ lgb_data <- lgb.Dataset(data = my_data, # We can now train a model model <- lgb.train(list(objective = "binary", metric = "l2", + nthread = 1, min_data = 1, learning_rate = 0.1, - min_data = 0, min_hessian = 1, max_depth = 2), lgb_data, diff --git a/R-package/demo/categorical_features_rules.R b/R-package/demo/categorical_features_rules.R index 6dd913600178..6db2ba4d7298 100644 --- a/R-package/demo/categorical_features_rules.R +++ b/R-package/demo/categorical_features_rules.R @@ -76,9 +76,9 @@ dtest <- lgb.Dataset(data = my_data_test, # We can now train a model model <- lgb.train(list(objective = "binary", metric = "l2", + nthread = 1, min_data = 1, learning_rate = 0.1, - min_data = 0, min_hessian = 1, max_depth = 2, categorical_feature = c(2, 3, 4, 5, 7, 8, 9, 11, 16)), diff --git a/R-package/demo/cross_validation.R b/R-package/demo/cross_validation.R index 90a965004068..8dbb76cae445 100644 --- a/R-package/demo/cross_validation.R +++ b/R-package/demo/cross_validation.R @@ -8,6 +8,7 @@ dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label) nrounds <- 2 param <- list(num_leaves = 4, learning_rate = 1, + nthread = 1, objective = "binary") print("Running cross validation") diff --git a/R-package/demo/early_stopping.R b/R-package/demo/early_stopping.R index 7e213cf478eb..26cd1378baf4 100644 --- a/R-package/demo/early_stopping.R +++ b/R-package/demo/early_stopping.R @@ -12,7 +12,8 @@ dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label) # Note: what we are getting is margin value in prediction # You must know what you are doing param <- list(num_leaves = 4, - learning_rate = 1) + learning_rate = 1, + nthread = 1) valids <- list(eval = dtest) num_round <- 20 @@ -45,4 +46,5 @@ bst <- lgb.train(param, valids, objective = logregobj, eval = evalerror, - early_stopping_round = 3) + early_stopping_round = 3, + nthread = 1) diff --git a/R-package/demo/efficient_many_training.R b/R-package/demo/efficient_many_training.R index 6a63797e4ae8..f7eed2077ca8 100644 --- a/R-package/demo/efficient_many_training.R +++ b/R-package/demo/efficient_many_training.R @@ -8,13 +8,17 @@ # Just doing reset=TRUE will already improve things: OS reports 4.6GB. # Doing reset=TRUE and calling gc() in the loop will have OS 1.3GB. Thanks for the latest tip." +# 2017-12-25 example patch: use the "small" switch to make it bigger. + +small <- TRUE + # Load library library(lightgbm) # Generate fictive data of size 1M x 100 set.seed(11111) -x_data <- matrix(rnorm(n = 100000000, mean = 0, sd = 100), nrow = 1000000, ncol = 100) -y_data <- rnorm(n = 1000000, mean = 0, sd = 5) +x_data <- matrix(rnorm(n = ifelse(small, 1000000, 100000000), mean = 0, sd = 100), nrow = ifelse(small, 10000, 1000000), ncol = 100) +y_data <- rnorm(n = ifelse(small, 10000, 1000000), mean = 0, sd = 5) # Create lgb.Dataset for training data <- lgb.Dataset(x_data, label = y_data) @@ -24,9 +28,10 @@ data$construct() # It MUST remain constant (if not increasing very slightly) gbm <- list() -for (i in 1:1000) { +for (i in 1:(ifelse(small, 100, 1000)) { print(i) - gbm[[i]] <- lgb.train(params = list(objective = "regression"), + gbm[[i]] <- lgb.train(params = list(objective = "regression", + nthread = 1), data = data, 1, reset_data = TRUE) diff --git a/R-package/demo/leaf_stability.R b/R-package/demo/leaf_stability.R index 8d7982ff4dff..6a1eed3ac76b 100644 --- a/R-package/demo/leaf_stability.R +++ b/R-package/demo/leaf_stability.R @@ -25,7 +25,8 @@ model <- lgb.train(params, learning_rate = 0.1, bagging_fraction = 0.1, bagging_freq = 1, - bagging_seed = 1) + bagging_seed = 1, + nthread = 1) # We create a data.frame with the following structure: # X = average leaf of the observation throughout all trees @@ -63,7 +64,8 @@ model2 <- lgb.train(params, 100, valids, min_data = 1, - learning_rate = 1) + learning_rate = 1, + nthread = 1) # We create the data structure, but for model2 new_data2 <- data.frame(X = rowMeans(predict(model2, @@ -98,7 +100,8 @@ model3 <- lgb.train(params, 1000, valids, min_data = 1, - learning_rate = 1) + learning_rate = 1, + nthread = 1) # We create the data structure, but for model3 new_data3 <- data.frame(X = rowMeans(predict(model3, diff --git a/R-package/demo/multiclass.R b/R-package/demo/multiclass.R index f1d14691ab89..bcca549a0f1d 100644 --- a/R-package/demo/multiclass.R +++ b/R-package/demo/multiclass.R @@ -25,7 +25,8 @@ model <- lgb.train(params, valids, min_data = 1, learning_rate = 1, - early_stopping_rounds = 10) + early_stopping_rounds = 10, + nthread = 1) # We can predict on test data, outputs a 90-length vector # Order: obs1 class1, obs1 class2, obs1 class3, obs2 class1, obs2 class2, obs2 class3... @@ -41,7 +42,8 @@ model <- lgb.train(list(), early_stopping_rounds = 10, objective = "multiclass", metric = "multi_error", - num_class = 3) + num_class = 3, + nthread = 1) # We can predict on test data, identical my_preds <- predict(model, test[, 1:4]) diff --git a/R-package/man/lgb.model.dt.tree.Rd b/R-package/man/lgb.model.dt.tree.Rd index 21d1a0a9c32d..23ce158d1d04 100644 --- a/R-package/man/lgb.model.dt.tree.Rd +++ b/R-package/man/lgb.model.dt.tree.Rd @@ -25,6 +25,7 @@ The columns of the \code{data.table} are: \item \code{split_gain}: Split gain of a node \item \code{threshold}: Spliting threshold value of a node \item \code{decision_type}: Decision type of a node + \item \code{default_left}: Determine how to handle NA value, TRUE -> Left, FALSE -> Right \item \code{internal_value}: Node value \item \code{internal_count}: The number of observation collected by a node \item \code{leaf_value}: Leaf value diff --git a/R-package/man/lgb.train.Rd b/R-package/man/lgb.train.Rd index b72384935e19..f6bc33e34901 100644 --- a/R-package/man/lgb.train.Rd +++ b/R-package/man/lgb.train.Rd @@ -75,7 +75,7 @@ If early stopping occurs, the model will have 'best_iter' field} \item{callbacks}{list of callback functions List of callback functions that are applied at each iteration.} -\item{...}{other parameters, see parameters.md for more informations} +\item{...}{other parameters, see Parameters.rst for more informations} \item{valids}{a list of \code{lgb.Dataset} objects, used for validation} @@ -135,7 +135,7 @@ If early stopping occurs, the model will have 'best_iter' field} \item{callbacks}{list of callback functions List of callback functions that are applied at each iteration.} -\item{...}{other parameters, see parameters.md for more informations} +\item{...}{other parameters, see Parameters.rst for more informations} } \value{ a trained model \code{lgb.CVBooster}. diff --git a/R-package/man/lgb.unloader.Rd b/R-package/man/lgb.unloader.Rd index 391462ece19e..039245b93542 100644 --- a/R-package/man/lgb.unloader.Rd +++ b/R-package/man/lgb.unloader.Rd @@ -37,11 +37,14 @@ model <- lgb.train(params, min_data = 1, learning_rate = 1, early_stopping_rounds = 10) -lgb.unloader(restore = FALSE, wipe = FALSE, envir = .GlobalEnv) + +# Disabled the following line as it crashes the documentation generator +# lgb.unloader(restore = FALSE, wipe = FALSE, envir = .GlobalEnv) rm(model, dtrain, dtest) # Not needed if wipe = TRUE gc() # Not needed if wipe = TRUE -library(lightgbm) +# Disabled the following line as it crashes the documentation generator +# library(lightgbm) # Do whatever you want again with LightGBM without object clashing } diff --git a/R-package/man/predict.lgb.Booster.Rd b/R-package/man/predict.lgb.Booster.Rd index 820fa18a02b9..b0d7f3656d84 100644 --- a/R-package/man/predict.lgb.Booster.Rd +++ b/R-package/man/predict.lgb.Booster.Rd @@ -40,6 +40,9 @@ Predicted values based on class \code{lgb.Booster} } \examples{ \dontrun{ +# It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + library(lightgbm) data(agaricus.train, package = "lightgbm") train <- agaricus.train @@ -60,3 +63,5 @@ preds <- predict(model, test$data) } } + +} diff --git a/R-package/man/readRDS.lgb.Booster.Rd b/R-package/man/readRDS.lgb.Booster.Rd index 8158ad2a1d83..1651b708a904 100644 --- a/R-package/man/readRDS.lgb.Booster.Rd +++ b/R-package/man/readRDS.lgb.Booster.Rd @@ -19,6 +19,9 @@ Attemps to load a model using RDS. } \examples{ \dontrun{ +# It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + library(lightgbm) data(agaricus.train, package = "lightgbm") train <- agaricus.train @@ -40,3 +43,5 @@ new_model <- readRDS.lgb.Booster("model.rds") } } + +} diff --git a/R-package/man/saveRDS.lgb.Booster.Rd b/R-package/man/saveRDS.lgb.Booster.Rd index eac224ebe77a..4eee63443fe8 100644 --- a/R-package/man/saveRDS.lgb.Booster.Rd +++ b/R-package/man/saveRDS.lgb.Booster.Rd @@ -30,6 +30,9 @@ Attemps to save a model using RDS. Has an additional parameter (\code{raw}) whic } \examples{ \dontrun{ +# It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + library(lightgbm) data(agaricus.train, package = "lightgbm") train <- agaricus.train @@ -50,3 +53,5 @@ saveRDS.lgb.Booster(model, "model.rds") } } + +} diff --git a/R-package/vignettes/basic_walkthrough.Rmd b/R-package/vignettes/basic_walkthrough.Rmd new file mode 100644 index 000000000000..865e7d5191cb --- /dev/null +++ b/R-package/vignettes/basic_walkthrough.Rmd @@ -0,0 +1,156 @@ +--- +title: "basic_walkthrough" +output: html_document +--- + +```{r} +require(lightgbm) +require(methods) + +# We load in the agaricus dataset +# In this example, we are aiming to predict whether a mushroom is edible +data(agaricus.train, package = "lightgbm") +data(agaricus.test, package = "lightgbm") +train <- agaricus.train +test <- agaricus.test + +# The loaded data is stored in sparseMatrix, and label is a numeric vector in {0,1} +class(train$label) +class(train$data) + +#--------------------Basic Training using lightgbm---------------- +# This is the basic usage of lightgbm you can put matrix in data field +# Note: we are putting in sparse matrix here, lightgbm naturally handles sparse input +# Use sparse matrix when your feature is sparse (e.g. when you are using one-hot encoding vector) +print("Training lightgbm with sparseMatrix") +bst <- lightgbm(data = train$data, + label = train$label, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + nthread = 1, + objective = "binary") + +# Alternatively, you can put in dense matrix, i.e. basic R-matrix +print("Training lightgbm with Matrix") +bst <- lightgbm(data = as.matrix(train$data), + label = train$label, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + nthread = 1, + objective = "binary") + +# You can also put in lgb.Dataset object, which stores label, data and other meta datas needed for advanced features +print("Training lightgbm with lgb.Dataset") +dtrain <- lgb.Dataset(data = train$data, + label = train$label) +bst <- lightgbm(data = dtrain, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + nthread = 1, + objective = "binary") + +# Verbose = 0,1,2 +print("Train lightgbm with verbose 0, no message") +bst <- lightgbm(data = dtrain, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + nthread = 1, + objective = "binary", + verbose = 0) + +print("Train lightgbm with verbose 1, print evaluation metric") +bst <- lightgbm(data = dtrain, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + nthread = 1, + objective = "binary", + verbose = 1) + +print("Train lightgbm with verbose 2, also print information about tree") +bst <- lightgbm(data = dtrain, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + nthread = 1, + objective = "binary", + verbose = 2) + +# You can also specify data as file path to a LibSVM/TCV/CSV format input +# Since we do not have this file with us, the following line is just for illustration +# bst <- lightgbm(data = "agaricus.train.svm", num_leaves = 4, learning_rate = 1, nrounds = 2,objective = "binary") + +#--------------------Basic prediction using lightgbm-------------- +# You can do prediction using the following line +# You can put in Matrix, sparseMatrix, or lgb.Dataset +pred <- predict(bst, test$data) +err <- mean(as.numeric(pred > 0.5) != test$label) +print(paste("test-error=", err)) + +#--------------------Save and load models------------------------- +# Save model to binary local file +lgb.save(bst, "lightgbm.model") + +# Load binary model to R +bst2 <- lgb.load("lightgbm.model") +pred2 <- predict(bst2, test$data) + +# pred2 should be identical to pred +print(paste("sum(abs(pred2-pred))=", sum(abs(pred2 - pred)))) + +#--------------------Advanced features --------------------------- +# To use advanced features, we need to put data in lgb.Dataset +dtrain <- lgb.Dataset(data = train$data, label = train$label, free_raw_data = FALSE) +dtest <- lgb.Dataset(data = test$data, label = test$label, free_raw_data = FALSE) + +#--------------------Using validation set------------------------- +# valids is a list of lgb.Dataset, each of them is tagged with name +valids <- list(train = dtrain, test = dtest) + +# To train with valids, use lgb.train, which contains more advanced features +# valids allows us to monitor the evaluation result on all data in the list +print("Train lightgbm using lgb.train with valids") +bst <- lgb.train(data = dtrain, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + valids = valids, + nthread = 1, + objective = "binary") + +# We can change evaluation metrics, or use multiple evaluation metrics +print("Train lightgbm using lgb.train with valids, watch logloss and error") +bst <- lgb.train(data = dtrain, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + valids = valids, + eval = c("binary_error", "binary_logloss"), + nthread = 1, + objective = "binary") + +# lgb.Dataset can also be saved using lgb.Dataset.save +lgb.Dataset.save(dtrain, "dtrain.buffer") + +# To load it in, simply call lgb.Dataset +dtrain2 <- lgb.Dataset("dtrain.buffer") +bst <- lgb.train(data = dtrain2, + num_leaves = 4, + learning_rate = 1, + nrounds = 2, + valids = valids, + nthread = 1, + objective = "binary") + +# information can be extracted from lgb.Dataset using getinfo +label = getinfo(dtest, "label") +pred <- predict(bst, test$data) +err <- as.numeric(sum(as.integer(pred > 0.5) != label)) / length(label) +print(paste("test-error=", err)) + +``` + diff --git a/R-package/vignettes/boost_from_prediction.Rmd b/R-package/vignettes/boost_from_prediction.Rmd new file mode 100644 index 000000000000..bee556edb3f4 --- /dev/null +++ b/R-package/vignettes/boost_from_prediction.Rmd @@ -0,0 +1,45 @@ +--- +title: "Boosting from existing prediction" +output: html_document +--- + +```{r} +require(lightgbm) +require(methods) + +# Load in the agaricus dataset +data(agaricus.train, package = "lightgbm") +data(agaricus.test, package = "lightgbm") +dtrain <- lgb.Dataset(agaricus.train$data, label = agaricus.train$label) +dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label) + +valids <- list(eval = dtest, train = dtrain) +#--------------------Advanced features --------------------------- +# advanced: start from a initial base prediction +print("Start running example to start from a initial prediction") + +# Train lightgbm for 1 round +param <- list(num_leaves = 4, + learning_rate = 1, + nthread = 1, + objective = "binary") +bst <- lgb.train(param, dtrain, 1, valids = valids) + +# Note: we need the margin value instead of transformed prediction in set_init_score +ptrain <- predict(bst, agaricus.train$data, rawscore = TRUE) +ptest <- predict(bst, agaricus.test$data, rawscore = TRUE) + +# set the init_score property of dtrain and dtest +# base margin is the base prediction we will boost from +setinfo(dtrain, "init_score", ptrain) +setinfo(dtest, "init_score", ptest) + +print("This is result of boost from initial prediction") +bst <- lgb.train(params = param, + data = dtrain, + nrounds = 5, + nthread = 1, + valids = valids) + +``` + diff --git a/R-package/vignettes/categorical_features_prepare.Rmd b/R-package/vignettes/categorical_features_prepare.Rmd new file mode 100644 index 000000000000..9968a9eea304 --- /dev/null +++ b/R-package/vignettes/categorical_features_prepare.Rmd @@ -0,0 +1,91 @@ +--- +title: "Categorical Feature Preparation" +output: html_document +--- + +```{r} +# Here we are going to try training a model with categorical features + +# Load libraries +library(data.table) +library(lightgbm) + +# Load data and look at the structure +# +# Classes 'data.table' and 'data.frame': 4521 obs. of 17 variables: +# $ age : int 30 33 35 30 59 35 36 39 41 43 ... +# $ job : chr "unemployed" "services" "management" "management" ... +# $ marital : chr "married" "married" "single" "married" ... +# $ education: chr "primary" "secondary" "tertiary" "tertiary" ... +# $ default : chr "no" "no" "no" "no" ... +# $ balance : int 1787 4789 1350 1476 0 747 307 147 221 -88 ... +# $ housing : chr "no" "yes" "yes" "yes" ... +# $ loan : chr "no" "yes" "no" "yes" ... +# $ contact : chr "cellular" "cellular" "cellular" "unknown" ... +# $ day : int 19 11 16 3 5 23 14 6 14 17 ... +# $ month : chr "oct" "may" "apr" "jun" ... +# $ duration : int 79 220 185 199 226 141 341 151 57 313 ... +# $ campaign : int 1 1 1 4 1 2 1 2 2 1 ... +# $ pdays : int -1 339 330 -1 -1 176 330 -1 -1 147 ... +# $ previous : int 0 4 1 0 0 3 2 0 0 2 ... +# $ poutcome : chr "unknown" "failure" "failure" "unknown" ... +# $ y : chr "no" "no" "no" "no" ... +data(bank, package = "lightgbm") +str(bank) + +# We must now transform the data to fit in LightGBM +# For this task, we use lgb.prepare +# The function transforms the data into a fittable data +# +# Classes 'data.table' and 'data.frame': 4521 obs. of 17 variables: +# $ age : int 30 33 35 30 59 35 36 39 41 43 ... +# $ job : chr "unemployed" "services" "management" "management" ... +# $ marital : chr "married" "married" "single" "married" ... +# $ education: chr "primary" "secondary" "tertiary" "tertiary" ... +# $ default : chr "no" "no" "no" "no" ... +# $ balance : int 1787 4789 1350 1476 0 747 307 147 221 -88 ... +# $ housing : chr "no" "yes" "yes" "yes" ... +# $ loan : chr "no" "yes" "no" "yes" ... +# $ contact : chr "cellular" "cellular" "cellular" "unknown" ... +# $ day : int 19 11 16 3 5 23 14 6 14 17 ... +# $ month : chr "oct" "may" "apr" "jun" ... +# $ duration : int 79 220 185 199 226 141 341 151 57 313 ... +# $ campaign : int 1 1 1 4 1 2 1 2 2 1 ... +# $ pdays : int -1 339 330 -1 -1 176 330 -1 -1 147 ... +# $ previous : int 0 4 1 0 0 3 2 0 0 2 ... +# $ poutcome : chr "unknown" "failure" "failure" "unknown" ... +# $ y : chr "no" "no" "no" "no" ... +bank <- lgb.prepare(data = bank) +str(bank) + +# Remove 1 to label because it must be between 0 and 1 +bank$y <- bank$y - 1 + +# Data input to LightGBM must be a matrix, without the label +my_data <- as.matrix(bank[, 1:16, with = FALSE]) + +# Creating the LightGBM dataset with categorical features +# The categorical features must be indexed like in R (1-indexed, not 0-indexed) +lgb_data <- lgb.Dataset(data = my_data, + label = bank$y, + categorical_feature = c(2, 3, 4, 5, 7, 8, 9, 11, 16)) + +# We can now train a model +model <- lgb.train(list(objective = "binary", + metric = "l2", + nthread = 1, + min_data = 1, + learning_rate = 0.1, + min_hessian = 1, + max_depth = 2), + lgb_data, + 100, + valids = list(train = lgb_data)) + +# Try to find split_feature: 2 +# If you find it, it means it used a categorical feature in the first tree +lgb.dump(model, num_iteration = 1) + + +``` + diff --git a/R-package/vignettes/categorical_features_rules.Rmd b/R-package/vignettes/categorical_features_rules.Rmd new file mode 100644 index 000000000000..739feca799ef --- /dev/null +++ b/R-package/vignettes/categorical_features_rules.Rmd @@ -0,0 +1,101 @@ +--- +title: "Categorical Feature Preparation with Rule" +output: html_document +--- + +```{r} +# Here we are going to try training a model with categorical features + +# Load libraries +library(data.table) +library(lightgbm) + +# Load data and look at the structure +# +# Classes 'data.table' and 'data.frame': 4521 obs. of 17 variables: +# $ age : int 30 33 35 30 59 35 36 39 41 43 ... +# $ job : chr "unemployed" "services" "management" "management" ... +# $ marital : chr "married" "married" "single" "married" ... +# $ education: chr "primary" "secondary" "tertiary" "tertiary" ... +# $ default : chr "no" "no" "no" "no" ... +# $ balance : int 1787 4789 1350 1476 0 747 307 147 221 -88 ... +# $ housing : chr "no" "yes" "yes" "yes" ... +# $ loan : chr "no" "yes" "no" "yes" ... +# $ contact : chr "cellular" "cellular" "cellular" "unknown" ... +# $ day : int 19 11 16 3 5 23 14 6 14 17 ... +# $ month : chr "oct" "may" "apr" "jun" ... +# $ duration : int 79 220 185 199 226 141 341 151 57 313 ... +# $ campaign : int 1 1 1 4 1 2 1 2 2 1 ... +# $ pdays : int -1 339 330 -1 -1 176 330 -1 -1 147 ... +# $ previous : int 0 4 1 0 0 3 2 0 0 2 ... +# $ poutcome : chr "unknown" "failure" "failure" "unknown" ... +# $ y : chr "no" "no" "no" "no" ... +data(bank, package = "lightgbm") +str(bank) + +# We are dividing the dataset into two: one train, one validation +bank_train <- bank[1:4000, ] +bank_test <- bank[4001:4521, ] + +# We must now transform the data to fit in LightGBM +# For this task, we use lgb.prepare +# The function transforms the data into a fittable data +# +# Classes 'data.table' and 'data.frame': 521 obs. of 17 variables: +# $ age : int 53 36 58 26 34 55 55 34 41 38 ... +# $ job : num 1 10 10 9 10 2 2 3 3 4 ... +# $ marital : num 1 2 1 3 3 2 2 2 1 1 ... +# $ education: num 2 2 2 2 2 1 2 3 2 2 ... +# $ default : num 1 1 1 1 1 1 1 1 1 1 ... +# $ balance : int 26 191 -123 -147 179 1086 471 105 1588 70 ... +# $ housing : num 2 1 1 1 1 2 2 2 2 1 ... +# $ loan : num 1 1 1 1 1 1 1 1 2 1 ... +# $ contact : num 1 1 1 3 1 1 3 3 3 1 ... +# $ day : int 7 31 5 4 19 6 30 28 20 27 ... +# $ month : num 9 2 2 7 2 9 9 9 7 11 ... +# $ duration : int 56 69 131 95 294 146 58 249 10 255 ... +# $ campaign : int 1 1 2 2 3 1 2 2 8 3 ... +# $ pdays : int 359 -1 -1 -1 -1 272 -1 -1 -1 148 ... +# $ previous : int 1 0 0 0 0 2 0 0 0 1 ... +# $ poutcome : num 1 4 4 4 4 1 4 4 4 3 ... +# $ y : num 1 1 1 1 1 1 1 1 1 2 ... +bank_rules <- lgb.prepare_rules(data = bank_train) +bank_train <- bank_rules$data +bank_test <- lgb.prepare_rules(data = bank_test, rules = bank_rules$rules)$data +str(bank_test) + +# Remove 1 to label because it must be between 0 and 1 +bank_train$y <- bank_train$y - 1 +bank_test$y <- bank_test$y - 1 + +# Data input to LightGBM must be a matrix, without the label +my_data_train <- as.matrix(bank_train[, 1:16, with = FALSE]) +my_data_test <- as.matrix(bank_test[, 1:16, with = FALSE]) + +# Creating the LightGBM dataset with categorical features +# The categorical features can be passed to lgb.train to not copy and paste a lot +dtrain <- lgb.Dataset(data = my_data_train, + label = bank_train$y) +dtest <- lgb.Dataset(data = my_data_test, + label = bank_test$y) + +# We can now train a model +model <- lgb.train(list(objective = "binary", + metric = "l2", + nthread = 1, + min_data = 1, + learning_rate = 0.1, + min_hessian = 1, + max_depth = 2, + categorical_feature = c(2, 3, 4, 5, 7, 8, 9, 11, 16)), + dtrain, + 100, + valids = list(train = dtrain, valid = dtest)) + +# Try to find split_feature: 11 +# If you find it, it means it used a categorical feature in the first tree +lgb.dump(model, num_iteration = 1) + + +``` + diff --git a/R-package/vignettes/cross_validation.Rmd b/R-package/vignettes/cross_validation.Rmd new file mode 100644 index 000000000000..a0a91e2a640e --- /dev/null +++ b/R-package/vignettes/cross_validation.Rmd @@ -0,0 +1,66 @@ +--- +title: "Cross Validation" +output: html_document +--- + +```{r} +require(lightgbm) +# load in the agaricus dataset +data(agaricus.train, package = "lightgbm") +data(agaricus.test, package = "lightgbm") +dtrain <- lgb.Dataset(agaricus.train$data, label = agaricus.train$label) +dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label) + +nrounds <- 2 +param <- list(num_leaves = 4, + learning_rate = 1, + nthread = 1, + objective = "binary") + +print("Running cross validation") +# Do cross validation, this will print result out as +# [iteration] metric_name:mean_value+std_value +# std_value is standard deviation of the metric +lgb.cv(param, + dtrain, + nrounds, + nfold = 5, + eval = "binary_error") + +print("Running cross validation, disable standard deviation display") +# do cross validation, this will print result out as +# [iteration] metric_name:mean_value+std_value +# std_value is standard deviation of the metric +lgb.cv(param, + dtrain, + nrounds, + nfold = 5, + eval = "binary_error", + showsd = FALSE) + +# You can also do cross validation with cutomized loss function +print("Running cross validation, with cutomsized loss function") + +logregobj <- function(preds, dtrain) { + labels <- getinfo(dtrain, "label") + preds <- 1 / (1 + exp(-preds)) + grad <- preds - labels + hess <- preds * (1 - preds) + return(list(grad = grad, hess = hess)) +} +evalerror <- function(preds, dtrain) { + labels <- getinfo(dtrain, "label") + err <- as.numeric(sum(labels != (preds > 0))) / length(labels) + return(list(name = "error", value = err, higher_better = FALSE)) +} + +# train with customized objective +lgb.cv(params = param, + data = dtrain, + nrounds = nrounds, + obj = logregobj, + eval = evalerror, + nfold = 5) + +``` + diff --git a/R-package/vignettes/early_stopping.Rmd b/R-package/vignettes/early_stopping.Rmd new file mode 100644 index 000000000000..5a169958a1a0 --- /dev/null +++ b/R-package/vignettes/early_stopping.Rmd @@ -0,0 +1,59 @@ +--- +title: "Early Stop in training" +output: html_document +--- + +```{r} +require(lightgbm) +require(methods) + +# Load in the agaricus dataset +data(agaricus.train, package = "lightgbm") +data(agaricus.test, package = "lightgbm") + +dtrain <- lgb.Dataset(agaricus.train$data, label = agaricus.train$label) +dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label) + +# Note: for customized objective function, we leave objective as default +# Note: what we are getting is margin value in prediction +# You must know what you are doing +param <- list(num_leaves = 4, + learning_rate = 1, + nthread = 1) +valids <- list(eval = dtest) +num_round <- 20 + +# User define objective function, given prediction, return gradient and second order gradient +# This is loglikelihood loss +logregobj <- function(preds, dtrain) { + labels <- getinfo(dtrain, "label") + preds <- 1 / (1 + exp(-preds)) + grad <- preds - labels + hess <- preds * (1 - preds) + return(list(grad = grad, hess = hess)) +} + +# User defined evaluation function, return a pair metric_name, result, higher_better +# NOTE: when you do customized loss function, the default prediction value is margin +# This may make buildin evalution metric not function properly +# For example, we are doing logistic loss, the prediction is score before logistic transformation +# The buildin evaluation error assumes input is after logistic transformation +# Take this in mind when you use the customization, and maybe you need write customized evaluation function +evalerror <- function(preds, dtrain) { + labels <- getinfo(dtrain, "label") + err <- as.numeric(sum(labels != (preds > 0.5))) / length(labels) + return(list(name = "error", value = err, higher_better = FALSE)) +} +print("Start training with early Stopping setting") + +bst <- lgb.train(param, + dtrain, + num_round, + valids, + objective = logregobj, + eval = evalerror, + early_stopping_round = 3, + nthread = 1) + +``` + diff --git a/R-package/vignettes/efficient_many_training.Rmd b/R-package/vignettes/efficient_many_training.Rmd new file mode 100644 index 000000000000..5ba837b2bb7f --- /dev/null +++ b/R-package/vignettes/efficient_many_training.Rmd @@ -0,0 +1,48 @@ +--- +title: "Efficiency for Many Model Trainings" +output: html_document +--- + +```{r} +# Efficient training means training without giving up too much RAM +# In the case of many trainings (like 100+ models), RAM will be eaten very quickly +# Therefore, it is essential to know a strategy to deal with such issue + +# More results can be found here: https://github.com/Microsoft/LightGBM/issues/879#issuecomment-326656580 +# Quote: "@Laurae2 Thanks for nice easily reproducible example (unlike mine). +# With reset=FALSE you get after 500 iterations (not 1000): OS reports 27GB usage, while R gc() reports 1.5GB. +# Just doing reset=TRUE will already improve things: OS reports 4.6GB. +# Doing reset=TRUE and calling gc() in the loop will have OS 1.3GB. Thanks for the latest tip." + +# 2017-12-25 example patch: use the "small" switch to make it bigger. + +small <- TRUE + +# Load library +library(lightgbm) + +# Generate fictive data of size 1M x 100 +set.seed(11111) +x_data <- matrix(rnorm(n = ifelse(small, 1000000, 100000000), mean = 0, sd = 100), nrow = ifelse(small, 10000, 1000000), ncol = 100) +y_data <- rnorm(n = ifelse(small, 10000, 1000000), mean = 0, sd = 5) + +# Create lgb.Dataset for training +data <- lgb.Dataset(x_data, label = y_data) +data$construct() + +# Loop through a training of 1000 models, please check your RAM on your task manager +# It MUST remain constant (if not increasing very slightly) +gbm <- list() + +for (i in 1:(ifelse(small, 100, 1000)) { + print(i) + gbm[[i]] <- lgb.train(params = list(objective = "regression", + nthread = 1), + data = data, + 1, + reset_data = TRUE) + gc(verbose = FALSE) +} + +``` + diff --git a/R-package/vignettes/leaf_stability.Rmd b/R-package/vignettes/leaf_stability.Rmd new file mode 100644 index 000000000000..e53ce56315a3 --- /dev/null +++ b/R-package/vignettes/leaf_stability.Rmd @@ -0,0 +1,139 @@ +--- +title: "Leaf (in)Stability example" +output: html_document +--- + +```{r} +# We are going to look at how iterating too much might generate observation instability. +# Obviously, we are in a controlled environment, without issues (real rules). +# Do not do this in a real scenario. + +# First, we load our libraries +library(lightgbm) +library(ggplot2) + +# Second, we load our data +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) + +# Third, we setup parameters and we train a model +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 50, + valids, + min_data = 1, + learning_rate = 0.1, + bagging_fraction = 0.1, + bagging_freq = 1, + bagging_seed = 1, + nthread = 1) + +# We create a data.frame with the following structure: +# X = average leaf of the observation throughout all trees +# Y = prediction probability (clamped to [1e-15, 1-1e-15]) +# Z = logloss +# binned = binned quantile of average leaf +new_data <- data.frame(X = rowMeans(predict(model, + agaricus.test$data, + predleaf = TRUE)), + Y = pmin(pmax(predict(model, + agaricus.test$data), 1e-15), 1 - 1e-15)) +new_data$Z <- -(agaricus.test$label * log(new_data$Y) + (1 - agaricus.test$label) * log(1 - new_data$Y)) +new_data$binned <- .bincode(x = new_data$X, + breaks = quantile(x = new_data$X, + probs = (1:9)/10), + right = TRUE, + include.lowest = TRUE) +new_data$binned[is.na(new_data$binned)] <- 0 +new_data$binned <- as.factor(new_data$binned) + +# We can check the binned content +table(new_data$binned) + +# We can plot the binned content +# On the second plot, we clearly notice the lower the bin (the lower the leaf value), the higher the loss +# On the third plot, it is smooth! +ggplot(data = new_data, mapping = aes(x = X, y = Y, color = binned)) + geom_point() + theme_bw() + labs(title = "Prediction Depth", x = "Leaf Bin", y = "Prediction Probability") +ggplot(data = new_data, mapping = aes(x = binned, y = Z, fill = binned, group = binned)) + geom_boxplot() + theme_bw() + labs(title = "Prediction Depth Spread", x = "Leaf Bin", y = "Logloss") +ggplot(data = new_data, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density") + + +# Now, let's show with other parameters +model2 <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + nthread = 1) + +# We create the data structure, but for model2 +new_data2 <- data.frame(X = rowMeans(predict(model2, + agaricus.test$data, + predleaf = TRUE)), + Y = pmin(pmax(predict(model2, + agaricus.test$data), 1e-15), 1 - 1e-15)) +new_data2$Z <- -(agaricus.test$label * log(new_data2$Y) + (1 - agaricus.test$label) * log(1 - new_data2$Y)) +new_data2$binned <- .bincode(x = new_data2$X, + breaks = quantile(x = new_data2$X, + probs = (1:9)/10), + right = TRUE, + include.lowest = TRUE) +new_data2$binned[is.na(new_data2$binned)] <- 0 +new_data2$binned <- as.factor(new_data2$binned) + +# We can check the binned content +table(new_data2$binned) + +# We can plot the binned content +# On the second plot, we clearly notice the lower the bin (the lower the leaf value), the higher the loss +# On the third plot, it is clearly not smooth! We are severely overfitting the data, but the rules are real thus it is not an issue +# However, if the rules were not true, the loss would explode. +ggplot(data = new_data2, mapping = aes(x = X, y = Y, color = binned)) + geom_point() + theme_bw() + labs(title = "Prediction Depth", x = "Leaf Bin", y = "Prediction Probability") +ggplot(data = new_data2, mapping = aes(x = binned, y = Z, fill = binned, group = binned)) + geom_boxplot() + theme_bw() + labs(title = "Prediction Depth Spread", x = "Leaf Bin", y = "Logloss") +ggplot(data = new_data2, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density") + + +# Now, try with very severe overfitting +model3 <- lgb.train(params, + dtrain, + 1000, + valids, + min_data = 1, + learning_rate = 1, + nthread = 1) + +# We create the data structure, but for model3 +new_data3 <- data.frame(X = rowMeans(predict(model3, + agaricus.test$data, + predleaf = TRUE)), + Y = pmin(pmax(predict(model3, + agaricus.test$data), 1e-15), 1 - 1e-15)) +new_data3$Z <- -(agaricus.test$label * log(new_data3$Y) + (1 - agaricus.test$label) * log(1 - new_data3$Y)) +new_data3$binned <- .bincode(x = new_data3$X, + breaks = quantile(x = new_data3$X, + probs = (1:9)/10), + right = TRUE, + include.lowest = TRUE) +new_data3$binned[is.na(new_data3$binned)] <- 0 +new_data3$binned <- as.factor(new_data3$binned) + +# We can check the binned content +table(new_data3$binned) + +# We can plot the binned content +# On the third plot, it is clearly not smooth! We are severely overfitting the data, but the rules are real thus it is not an issue. +# However, if the rules were not true, the loss would explode. See the sudden spikes? +ggplot(data = new_data3, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density") + +# Compare with our second model, the difference is severe. This is smooth. +ggplot(data = new_data2, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density") + +``` + diff --git a/R-package/vignettes/multiclass.Rmd b/R-package/vignettes/multiclass.Rmd new file mode 100644 index 000000000000..bf66cc8fd798 --- /dev/null +++ b/R-package/vignettes/multiclass.Rmd @@ -0,0 +1,77 @@ +--- +title: "Multiclass training/prediction" +output: html_document +--- + +```{r} +require(lightgbm) + +# We load the default iris dataset shipped with R +data(iris) + +# We must convert factors to numeric +# They must be starting from number 0 to use multiclass +# For instance: 0, 1, 2, 3, 4, 5... +iris$Species <- as.numeric(as.factor(iris$Species)) - 1 + +# We cut the data set into 80% train and 20% validation +# The 10 last samples of each class are for validation + +train <- as.matrix(iris[c(1:40, 51:90, 101:140), ]) +test <- as.matrix(iris[c(41:50, 91:100, 141:150), ]) +dtrain <- lgb.Dataset(data = train[, 1:4], label = train[, 5]) +dtest <- lgb.Dataset.create.valid(dtrain, data = test[, 1:4], label = test[, 5]) +valids <- list(test = dtest) + +# Method 1 of training +params <- list(objective = "multiclass", metric = "multi_error", num_class = 3) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10, + nthread = 1) + +# We can predict on test data, outputs a 90-length vector +# Order: obs1 class1, obs1 class2, obs1 class3, obs2 class1, obs2 class2, obs2 class3... +my_preds <- predict(model, test[, 1:4]) + +# Method 2 of training, identical +model <- lgb.train(list(), + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10, + objective = "multiclass", + metric = "multi_error", + num_class = 3, + nthread = 1) + +# We can predict on test data, identical +my_preds <- predict(model, test[, 1:4]) + +# A (30x3) matrix with the predictions, use parameter reshape +# class1 class2 class3 +# obs1 obs1 obs1 +# obs2 obs2 obs2 +# .... .... .... +my_preds <- predict(model, test[, 1:4], reshape = TRUE) + +# We can also get the predicted scores before the Sigmoid/Softmax application +my_preds <- predict(model, test[, 1:4], rawscore = TRUE) + +# Raw score predictions as matrix instead of vector +my_preds <- predict(model, test[, 1:4], rawscore = TRUE, reshape = TRUE) + +# We can also get the leaf index +my_preds <- predict(model, test[, 1:4], predleaf = TRUE) + +# Predict leaf index as matrix instead of vector +my_preds <- predict(model, test[, 1:4], predleaf = TRUE, reshape = TRUE) + +``` + diff --git a/R-package/vignettes/weight_param.Rmd b/R-package/vignettes/weight_param.Rmd new file mode 100644 index 000000000000..c248e56f4c51 --- /dev/null +++ b/R-package/vignettes/weight_param.Rmd @@ -0,0 +1,110 @@ +--- +title: "Weight-Parameter adjustment relationship" +output: html_document +--- + +```{r} +# This demo R code is to provide a demonstration of hyperparameter adjustment +# when scaling weights for appropriate learning +# As with any optimizers, bad parameters can impair performance + +# Load library +library(lightgbm) + +# We will train a model with the following scenarii: +# - Run 1: sum of weights equal to 0.06513 without adjusted regularization (not learning) +# - Run 2: sum of weights equal to 0.06513 with adjusted regularization (learning) +# - Run 3: sum of weights equal to 6513 (x 1e5) with adjusted regularization (learning) + +# Setup small weights +weights1 <- rep(1/100000, 6513) +weights2 <- rep(1/100000, 1611) + +# Load data and create datasets +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label, weight = weights1) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label, weight = weights2) +valids <- list(test = dtest) + +# Run 1: sum of weights equal to 0.06513 without adjusted regularization (not learning) +# It cannot learn because regularization is too large! +# min_sum_hessian alone is bigger than the sum of weights, thus you will never learn anything +params <- list(objective = "regression", + metric = "l2", + device = "cpu", + min_sum_hessian = 10, + num_leaves = 7, + max_depth = 3, + nthread = 1) +model <- lgb.train(params, + dtrain, + 50, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +weight_loss <- as.numeric(model$record_evals$test$l2$eval) +plot(weight_loss) # Shows how poor the learning was: a straight line! + +# Run 2: sum of weights equal to 0.06513 with adjusted regularization (learning) +# Adjusted regularization just consisting in multiplicating results by 1e4 (x10000) +# Notice how it learns, there is no issue as we adjusted regularization ourselves +params <- list(objective = "regression", + metric = "l2", + device = "cpu", + min_sum_hessian = 1e-4, + num_leaves = 7, + max_depth = 3, + nthread = 1) +model <- lgb.train(params, + dtrain, + 50, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +small_weight_loss <- as.numeric(model$record_evals$test$l2$eval) +plot(small_weight_loss) # It learns! + +# Run 3: sum of weights equal to 6513 (x 1e5) with adjusted regularization (learning) +# To make it better, we are first cleaning the environment and reloading LightGBM +lgb.unloader(wipe = TRUE) + +# And now, we are doing as usual +library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +valids <- list(test = dtest) + +# Setup parameters and run model... +params <- list(objective = "regression", + metric = "l2", + device = "cpu", + min_sum_hessian = 10, + num_leaves = 7, + max_depth = 3, + nthread = 1) +model <- lgb.train(params, + dtrain, + 50, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +large_weight_loss <- as.numeric(model$record_evals$test$l2$eval) +plot(large_weight_loss) # It learns! + + +# Do you want to compare the learning? They both converge. +plot(small_weight_loss, large_weight_loss) +curve(1*x, from = 0, to = 0.02, add = TRUE) + +``` + From 43d4fb4b444cda93f01cbe3672b38ad5d10a83ca Mon Sep 17 00:00:00 2001 From: Laurae Date: Sun, 21 Jan 2018 13:36:40 +0100 Subject: [PATCH 2/6] Vignette crash temporary workaround --- R-package/vignettes/basic_walkthrough.Rmd | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/R-package/vignettes/basic_walkthrough.Rmd b/R-package/vignettes/basic_walkthrough.Rmd index 865e7d5191cb..06cc279e1a48 100644 --- a/R-package/vignettes/basic_walkthrough.Rmd +++ b/R-package/vignettes/basic_walkthrough.Rmd @@ -93,14 +93,17 @@ print(paste("test-error=", err)) #--------------------Save and load models------------------------- # Save model to binary local file -lgb.save(bst, "lightgbm.model") - -# Load binary model to R -bst2 <- lgb.load("lightgbm.model") -pred2 <- predict(bst2, test$data) - -# pred2 should be identical to pred -print(paste("sum(abs(pred2-pred))=", sum(abs(pred2 - pred)))) +# Crash temporary workaround for pkgdown +if (!(pkgdown::in_pkgdown())) { + lgb.save(bst, "lightgbm.model") + + # Load binary model to R + bst2 <- lgb.load("lightgbm.model") + pred2 <- predict(bst2, test$data) + + # pred2 should be identical to pred + print(paste("sum(abs(pred2-pred))=", sum(abs(pred2 - pred)))) +} #--------------------Advanced features --------------------------- # To use advanced features, we need to put data in lgb.Dataset From fc130aa5546996b8215536c538a21ee7aa22928e Mon Sep 17 00:00:00 2001 From: Laurae Date: Sun, 21 Jan 2018 13:49:24 +0100 Subject: [PATCH 3/6] Remove load/save crash from pkgdown --- R-package/R/lgb.Booster.R | 10 ++++++++++ R-package/man/lgb.load.Rd | 5 +++++ R-package/man/lgb.save.Rd | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/R-package/R/lgb.Booster.R b/R-package/R/lgb.Booster.R index e3b965f76abe..f5536abccc74 100644 --- a/R-package/R/lgb.Booster.R +++ b/R-package/R/lgb.Booster.R @@ -685,6 +685,9 @@ predict.lgb.Booster <- function(object, data, #' #' @examples #' \dontrun{ +#' # It crashes the documentation generation, skipping +#' if (!(pkgdown::in_pkgdown())) { +#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -707,6 +710,8 @@ predict.lgb.Booster <- function(object, data, #' load_booster_from_str <- lgb.load(model_str = model_string) #' } #' +#' } +#' #' @rdname lgb.load #' @export lgb.load <- function(filename = NULL, model_str = NULL){ @@ -745,6 +750,9 @@ lgb.load <- function(filename = NULL, model_str = NULL){ #' #' @examples #' \dontrun{ +#' # It crashes the documentation generation, skipping +#' if (!(pkgdown::in_pkgdown())) { +#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -764,6 +772,8 @@ lgb.load <- function(filename = NULL, model_str = NULL){ #' lgb.save(model, "model.txt") #' } #' +#' } +#' #' @rdname lgb.save #' @export lgb.save <- function(booster, filename, num_iteration = NULL){ diff --git a/R-package/man/lgb.load.Rd b/R-package/man/lgb.load.Rd index 2dd117a6cd20..92c5d7325ab3 100644 --- a/R-package/man/lgb.load.Rd +++ b/R-package/man/lgb.load.Rd @@ -21,6 +21,9 @@ If both are provided, Load will default to loading from file } \examples{ \dontrun{ +# It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + library(lightgbm) data(agaricus.train, package = "lightgbm") train <- agaricus.train @@ -44,3 +47,5 @@ load_booster_from_str <- lgb.load(model_str = model_string) } } + +} diff --git a/R-package/man/lgb.save.Rd b/R-package/man/lgb.save.Rd index 45514f10a00c..34d5a3e1e85a 100644 --- a/R-package/man/lgb.save.Rd +++ b/R-package/man/lgb.save.Rd @@ -21,6 +21,9 @@ Save LightGBM model } \examples{ \dontrun{ +# It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + library(lightgbm) data(agaricus.train, package = "lightgbm") train <- agaricus.train @@ -41,3 +44,5 @@ lgb.save(model, "model.txt") } } + +} From 81d42731fe73a48d77919d74e2632fedf227b854 Mon Sep 17 00:00:00 2001 From: Laurae Date: Sun, 21 Jan 2018 15:58:14 +0100 Subject: [PATCH 4/6] Major R package documentation changes and crashfixes --- R-package/.Rbuildignore | 4 +- R-package/DESCRIPTION | 12 +- R-package/README.md | 125 +- R-package/demo/efficient_many_training.R | 6 +- R-package/docs/LICENSE.html | 167 ++ .../docs/articles/basic_walkthrough.html | 300 ++++ .../docs/articles/boost_from_prediction.html | 172 ++ .../categorical_features_prepare.html | 344 ++++ .../articles/categorical_features_rules.html | 354 +++++ R-package/docs/articles/cross_validation.html | 217 +++ R-package/docs/articles/dtrain.buffer | Bin 0 -> 105975 bytes R-package/docs/articles/early_stopping.html | 187 +++ .../articles/efficient_many_training.html | 266 ++++ R-package/docs/articles/index.html | 158 ++ R-package/docs/articles/leaf_stability.html | 1415 +++++++++++++++++ .../figure-html/unnamed-chunk-1-1.png | Bin 0 -> 19800 bytes .../figure-html/unnamed-chunk-1-2.png | Bin 0 -> 13762 bytes .../figure-html/unnamed-chunk-1-3.png | Bin 0 -> 14509 bytes .../figure-html/unnamed-chunk-1-4.png | Bin 0 -> 19570 bytes .../figure-html/unnamed-chunk-1-5.png | Bin 0 -> 14461 bytes .../figure-html/unnamed-chunk-1-6.png | Bin 0 -> 18147 bytes .../figure-html/unnamed-chunk-1-7.png | Bin 0 -> 18147 bytes .../figure-html/unnamed-chunk-1-8.png | Bin 0 -> 18147 bytes R-package/docs/articles/multiclass.html | 216 +++ R-package/docs/articles/weight_param.html | 340 ++++ .../figure-html/unnamed-chunk-1-1.png | Bin 0 -> 7602 bytes .../figure-html/unnamed-chunk-1-2.png | Bin 0 -> 9104 bytes .../figure-html/unnamed-chunk-1-3.png | Bin 0 -> 9402 bytes .../figure-html/unnamed-chunk-1-4.png | Bin 0 -> 11120 bytes R-package/docs/authors.html | 158 ++ R-package/docs/index.html | 357 +++++ R-package/docs/jquery.sticky-kit.min.js | 9 + R-package/docs/link.svg | 12 + R-package/docs/pkgdown.css | 163 ++ R-package/docs/pkgdown.js | 45 + R-package/docs/reference/agaricus.test.html | 180 +++ R-package/docs/reference/agaricus.train.html | 180 +++ R-package/docs/reference/bank.html | 176 ++ R-package/docs/reference/data.bin | Bin 0 -> 105975 bytes R-package/docs/reference/dim.html | 194 +++ .../docs/reference/dimnames.lgb.Dataset.html | 349 ++++ R-package/docs/reference/getinfo.html | 207 +++ R-package/docs/reference/index.html | 407 +++++ .../docs/reference/lgb.Dataset.construct.html | 173 ++ .../reference/lgb.Dataset.create.valid.html | 193 +++ R-package/docs/reference/lgb.Dataset.data | Bin 0 -> 105975 bytes R-package/docs/reference/lgb.Dataset.html | 211 +++ .../docs/reference/lgb.Dataset.save.html | 184 +++ .../lgb.Dataset.set.categorical.html | 185 +++ .../reference/lgb.Dataset.set.reference.html | 186 +++ R-package/docs/reference/lgb.dump.html | 206 +++ .../docs/reference/lgb.get.eval.result.html | 221 +++ R-package/docs/reference/lgb.importance.html | 197 +++ R-package/docs/reference/lgb.interprete.html | 206 +++ R-package/docs/reference/lgb.load.html | 204 +++ .../docs/reference/lgb.model.dt.tree.html | 205 +++ .../docs/reference/lgb.plot.importance-2.png | Bin 0 -> 13062 bytes .../docs/reference/lgb.plot.importance-3.png | Bin 0 -> 13062 bytes .../docs/reference/lgb.plot.importance.html | 211 +++ .../reference/lgb.plot.interpretation-2.png | Bin 0 -> 9500 bytes .../reference/lgb.plot.interpretation-3.png | Bin 0 -> 9500 bytes .../reference/lgb.plot.interpretation.html | 216 +++ R-package/docs/reference/lgb.prepare.html | 216 +++ R-package/docs/reference/lgb.prepare2.html | 217 +++ .../docs/reference/lgb.prepare_rules.html | 246 +++ .../docs/reference/lgb.prepare_rules2.html | 246 +++ R-package/docs/reference/lgb.save.html | 203 +++ R-package/docs/reference/lgb.train.html | 438 +++++ R-package/docs/reference/lgb.unloader.html | 220 +++ .../docs/reference/predict.lgb.Booster.html | 230 +++ .../docs/reference/readRDS.lgb.Booster.html | 200 +++ .../docs/reference/saveRDS.lgb.Booster.html | 220 +++ R-package/docs/reference/setinfo.html | 211 +++ R-package/docs/reference/slice.html | 193 +++ R-package/pkgdown/_pkgdown.yml | 120 ++ R-package/pkgdown/doc_gen.R | 19 + R-package/vignettes/basic_walkthrough.Rmd | 2 +- .../vignettes/efficient_many_training.Rmd | 6 +- 78 files changed, 12482 insertions(+), 23 deletions(-) create mode 100644 R-package/docs/LICENSE.html create mode 100644 R-package/docs/articles/basic_walkthrough.html create mode 100644 R-package/docs/articles/boost_from_prediction.html create mode 100644 R-package/docs/articles/categorical_features_prepare.html create mode 100644 R-package/docs/articles/categorical_features_rules.html create mode 100644 R-package/docs/articles/cross_validation.html create mode 100644 R-package/docs/articles/dtrain.buffer create mode 100644 R-package/docs/articles/early_stopping.html create mode 100644 R-package/docs/articles/efficient_many_training.html create mode 100644 R-package/docs/articles/index.html create mode 100644 R-package/docs/articles/leaf_stability.html create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-1.png create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-2.png create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-3.png create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-4.png create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-5.png create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-6.png create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-7.png create mode 100644 R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-8.png create mode 100644 R-package/docs/articles/multiclass.html create mode 100644 R-package/docs/articles/weight_param.html create mode 100644 R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-1.png create mode 100644 R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-2.png create mode 100644 R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-3.png create mode 100644 R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-4.png create mode 100644 R-package/docs/authors.html create mode 100644 R-package/docs/index.html create mode 100644 R-package/docs/jquery.sticky-kit.min.js create mode 100644 R-package/docs/link.svg create mode 100644 R-package/docs/pkgdown.css create mode 100644 R-package/docs/pkgdown.js create mode 100644 R-package/docs/reference/agaricus.test.html create mode 100644 R-package/docs/reference/agaricus.train.html create mode 100644 R-package/docs/reference/bank.html create mode 100644 R-package/docs/reference/data.bin create mode 100644 R-package/docs/reference/dim.html create mode 100644 R-package/docs/reference/dimnames.lgb.Dataset.html create mode 100644 R-package/docs/reference/getinfo.html create mode 100644 R-package/docs/reference/index.html create mode 100644 R-package/docs/reference/lgb.Dataset.construct.html create mode 100644 R-package/docs/reference/lgb.Dataset.create.valid.html create mode 100644 R-package/docs/reference/lgb.Dataset.data create mode 100644 R-package/docs/reference/lgb.Dataset.html create mode 100644 R-package/docs/reference/lgb.Dataset.save.html create mode 100644 R-package/docs/reference/lgb.Dataset.set.categorical.html create mode 100644 R-package/docs/reference/lgb.Dataset.set.reference.html create mode 100644 R-package/docs/reference/lgb.dump.html create mode 100644 R-package/docs/reference/lgb.get.eval.result.html create mode 100644 R-package/docs/reference/lgb.importance.html create mode 100644 R-package/docs/reference/lgb.interprete.html create mode 100644 R-package/docs/reference/lgb.load.html create mode 100644 R-package/docs/reference/lgb.model.dt.tree.html create mode 100644 R-package/docs/reference/lgb.plot.importance-2.png create mode 100644 R-package/docs/reference/lgb.plot.importance-3.png create mode 100644 R-package/docs/reference/lgb.plot.importance.html create mode 100644 R-package/docs/reference/lgb.plot.interpretation-2.png create mode 100644 R-package/docs/reference/lgb.plot.interpretation-3.png create mode 100644 R-package/docs/reference/lgb.plot.interpretation.html create mode 100644 R-package/docs/reference/lgb.prepare.html create mode 100644 R-package/docs/reference/lgb.prepare2.html create mode 100644 R-package/docs/reference/lgb.prepare_rules.html create mode 100644 R-package/docs/reference/lgb.prepare_rules2.html create mode 100644 R-package/docs/reference/lgb.save.html create mode 100644 R-package/docs/reference/lgb.train.html create mode 100644 R-package/docs/reference/lgb.unloader.html create mode 100644 R-package/docs/reference/predict.lgb.Booster.html create mode 100644 R-package/docs/reference/readRDS.lgb.Booster.html create mode 100644 R-package/docs/reference/saveRDS.lgb.Booster.html create mode 100644 R-package/docs/reference/setinfo.html create mode 100644 R-package/docs/reference/slice.html create mode 100644 R-package/pkgdown/_pkgdown.yml create mode 100644 R-package/pkgdown/doc_gen.R diff --git a/R-package/.Rbuildignore b/R-package/.Rbuildignore index 9ad5b5ec3b57..443a918af322 100644 --- a/R-package/.Rbuildignore +++ b/R-package/.Rbuildignore @@ -1 +1,3 @@ -^docs$ \ No newline at end of file +^docs$ +^_pkgdown\.yml$ +^pkgdown$ diff --git a/R-package/DESCRIPTION b/R-package/DESCRIPTION index 7404278744d8..063db73ad7f2 100755 --- a/R-package/DESCRIPTION +++ b/R-package/DESCRIPTION @@ -3,13 +3,11 @@ Type: Package Title: Light Gradient Boosting Machine Version: 2.0.12 Date: 2018-01-21 -Authors@R: c(person("Guolin", "Ke", , "guolin.ke@microsoft.com", role = c("aut", "cre")), - person("Damien", "Soukhavong", , "damien.soukhavong@skema.edu", role = c("ctb")), - person("Yachen", "Yan", , "to_be_added_later@mail.com", role = c("ctb"))) -Author: Guolin Ke [aut, cre], - Damien Soukhavong [ctb], - Yachen Yan [ctb] -Maintainer: Guolin Ke +Authors@R: c( + person("Guolin", "Ke", email = "guolin.ke@microsoft.com", role = c("aut", "cre")), + person("Damien", "Soukhavong", email = "damien.soukhavong@skema.edu", role = c("ctb")), + person("Yachen", "Yan", role = c("ctb")) + ) Description: LightGBM is a gradient boosting framework that uses tree based learning algorithms. It is designed to be distributed and efficient with the following advantages: 1. Faster training speed and higher efficiency. diff --git a/R-package/README.md b/R-package/README.md index f13cc576cdbc..2001ff939dc7 100644 --- a/R-package/README.md +++ b/R-package/README.md @@ -1,6 +1,115 @@ LightGBM R Package ================== +[![Build Status](https://travis-ci.org/Microsoft/LightGBM.svg?branch=master)](https://travis-ci.org/Microsoft/LightGBM) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/1ys5ot401m0fep6l/branch/master?svg=true)](https://ci.appveyor.com/project/guolinke/lightgbm/branch/master) +[![Documentation Status](https://readthedocs.org/projects/lightgbm/badge/?version=latest)](https://lightgbm.readthedocs.io/) +[![GitHub Issues](https://img.shields.io/github/issues/Microsoft/LightGBM.svg)](https://github.com/Microsoft/LightGBM/issues) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Microsoft/LightGBM/blob/master/LICENSE) +[![Python Versions](https://img.shields.io/pypi/pyversions/lightgbm.svg)](https://pypi.python.org/pypi/lightgbm) +[![PyPI Version](https://badge.fury.io/py/lightgbm.svg)](https://badge.fury.io/py/lightgbm) +[![Join the chat at https://gitter.im/Microsoft/LightGBM](https://badges.gitter.im/Microsoft/LightGBM.svg)](https://gitter.im/Microsoft/LightGBM?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Slack](https://lightgbm-slack-autojoin.herokuapp.com/badge.svg)](https://lightgbm-slack-autojoin.herokuapp.com/) + +LightGBM, Light Gradient Boosting Machine +========================================= + +LightGBM is a gradient boosting framework that uses tree based learning algorithms. It is designed to be distributed and efficient with the following advantages: + +- Faster training speed and higher efficiency +- Lower memory usage +- Better accuracy +- Parallel and GPU learning supported +- Capable of handling large-scale data + +For more details, please refer to [Features](https://github.com/Microsoft/LightGBM/blob/master/docs/Features.rst). + +[Comparison experiments](https://github.com/Microsoft/LightGBM/blob/master/docs/Experiments.rst#comparison-experiment) on public datasets show that LightGBM can outperform existing boosting frameworks on both efficiency and accuracy, with significantly lower memory consumption. What's more, the [parallel experiments](https://github.com/Microsoft/LightGBM/blob/master/docs/Experiments.rst#parallel-experiment) show that LightGBM can achieve a linear speed-up by using multiple machines for training in specific settings. + +News +---- + +08/15/2017 : Optimal split for categorical features. + +07/13/2017 : [Gitter](https://gitter.im/Microsoft/LightGBM) is available. + +06/20/2017 : Python-package is on [PyPI](https://pypi.python.org/pypi/lightgbm) now. + +06/09/2017 : [LightGBM Slack team](https://lightgbm.slack.com) is available. + +05/03/2017 : LightGBM v2 stable release. + +04/10/2017 : LightGBM supports GPU-accelerated tree learning now. Please read our [GPU Tutorial](./docs/GPU-Tutorial.rst) and [Performance Comparison](./docs/GPU-Performance.rst). + +02/20/2017 : Update to LightGBM v2. + +02/12/2017: LightGBM v1 stable release. + +01/08/2017 : Release [**R-package**](https://github.com/Microsoft/LightGBM/tree/master/R-package) beta version, welcome to have a try and provide feedback. + +12/05/2016 : **Categorical Features as input directly** (without one-hot coding). + +12/02/2016 : Release [**Python-package**](https://github.com/Microsoft/LightGBM/tree/master/python-package) beta version, welcome to have a try and provide feedback. + +More detailed update logs : [Key Events](https://github.com/Microsoft/LightGBM/blob/master/docs/Key-Events.md). + +External (unofficial) Repositories +---------------------------------- + +Julia Package: https://github.com/Allardvm/LightGBM.jl + +JPMML: https://github.com/jpmml/jpmml-lightgbm + +Get Started and Documentation +----------------------------- + +Install by following the [guide](https://github.com/Microsoft/LightGBM/blob/master/docs/Installation-Guide.rst) for the command line program, [Python-package](https://github.com/Microsoft/LightGBM/tree/master/python-package) or [R-package](https://github.com/Microsoft/LightGBM/tree/master/R-package). Then please see the [Quick Start](https://github.com/Microsoft/LightGBM/blob/master/docs/Quick-Start.rst) guide. + +Our primary documentation is at https://lightgbm.readthedocs.io/ and is generated from this repository. + +Next you may want to read: + +* [**Examples**](https://github.com/Microsoft/LightGBM/tree/master/examples) showing command line usage of common tasks +* [**Features**](https://github.com/Microsoft/LightGBM/blob/master/docs/Features.rst) and algorithms supported by LightGBM +* [**Parameters**](https://github.com/Microsoft/LightGBM/blob/master/docs/Parameters.rst) is an exhaustive list of customization you can make +* [**Parallel Learning**](https://github.com/Microsoft/LightGBM/blob/master/docs/Parallel-Learning-Guide.rst) and [**GPU Learning**](https://github.com/Microsoft/LightGBM/blob/master/docs/GPU-Tutorial.rst) can speed up computation +* [**Laurae++ interactive documentation**](https://sites.google.com/view/lauraepp/parameters) is a detailed guide for hyperparameters + +Documentation for contributors: + +* [**How we update readthedocs.io**](https://github.com/Microsoft/LightGBM/blob/master/docs/README.rst) +* Check out the [**Development Guide**](https://github.com/Microsoft/LightGBM/blob/master/docs/Development-Guide.rst). + +Support +------- + +* Ask a question [on Stack Overflow with the `lightgbm` tag](https://stackoverflow.com/questions/ask?tags=lightgbm), we monitor this for new questions. +* Discuss on the [LightGBM Gitter](https://gitter.im/Microsoft/LightGBM). +* Discuss on the [LightGBM Slack team](https://lightgbm.slack.com). + * Use [this invite link](https://lightgbm-slack-autojoin.herokuapp.com/) to join the team. +* Open **bug reports** and **feature requests** (not questions) on [GitHub issues](https://github.com/Microsoft/LightGBM/issues). + +How to Contribute +----------------- + +LightGBM has been developed and used by many active community members. Your help is very valuable to make it better for everyone. + +- Check out [call for contributions](https://github.com/Microsoft/LightGBM/issues?q=is%3Aissue+is%3Aopen+label%3Acall-for-contribution) to see what can be improved, or open an issue if you want something. +- Contribute to the [tests](https://github.com/Microsoft/LightGBM/tree/master/tests) to make it more reliable. +- Contribute to the [documents](https://github.com/Microsoft/LightGBM/tree/master/docs) to make it clearer for everyone. +- Contribute to the [examples](https://github.com/Microsoft/LightGBM/tree/master/examples) to share your experience with other users. +- Open issue if you met problems during development. + +Microsoft Open Source Code of Conduct +------------------------------------- + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +Reference Paper +--------------- + +Guolin Ke, Qi Meng, Thomas Finley, Taifeng Wang, Wei Chen, Weidong Ma, Qiwei Ye, and Tie-Yan Liu. [LightGBM: A Highly Efficient Gradient Boosting Decision Tree](https://papers.nips.cc/paper/6907-lightgbm-a-highly-efficient-gradient-boosting-decision-tree). In Advances in Neural Information Processing Systems (NIPS), pp. 3149-3157. 2017. + Installation ------------ @@ -128,12 +237,12 @@ You may also read [Microsoft/LightGBM#912](https://github.com/Microsoft/LightGBM Examples -------- -Please visit [demo](demo): +Please visit [demo](https://github.com/Microsoft/LightGBM/tree/master/R-package/demo): -* [Basic walkthrough of wrappers](demo/basic_walkthrough.R) -* [Boosting from existing prediction](demo/boost_from_prediction.R) -* [Early Stopping](demo/early_stopping.R) -* [Cross Validation](demo/cross_validation.R) -* [Multiclass Training/Prediction](demo/multiclass.R) -* [Leaf (in)Stability](demo/leaf_stability.R) -* [Weight-Parameter Adjustment Relationship](demo/weight_param.R) +* [Basic walkthrough of wrappers](articles/basic_walkthrough.html) +* [Boosting from existing prediction](articles/boost_from_prediction.html) +* [Early Stopping](articles/early_stopping.html) +* [Cross Validation](articles/cross_validation.html) +* [Multiclass Training/Prediction](articles/multiclass.html) +* [Leaf (in)Stability](articles/leaf_stability.html) +* [Weight-Parameter Adjustment Relationship](articles/weight_param.html) diff --git a/R-package/demo/efficient_many_training.R b/R-package/demo/efficient_many_training.R index f7eed2077ca8..28e22b5c02e9 100644 --- a/R-package/demo/efficient_many_training.R +++ b/R-package/demo/efficient_many_training.R @@ -8,7 +8,7 @@ # Just doing reset=TRUE will already improve things: OS reports 4.6GB. # Doing reset=TRUE and calling gc() in the loop will have OS 1.3GB. Thanks for the latest tip." -# 2017-12-25 example patch: use the "small" switch to make it bigger. +# 2018-01-21 example patch: use the "small" switch to make it bigger. small <- TRUE @@ -28,8 +28,8 @@ data$construct() # It MUST remain constant (if not increasing very slightly) gbm <- list() -for (i in 1:(ifelse(small, 100, 1000)) { - print(i) +for (i in 1:(ifelse(small, 100, 1000))) { + cat(format(Sys.time(), "%a %b %d %Y %X"), ": ", i, "\n", sep = "") gbm[[i]] <- lgb.train(params = list(objective = "regression", nthread = 1), data = data, diff --git a/R-package/docs/LICENSE.html b/R-package/docs/LICENSE.html new file mode 100644 index 000000000000..b60c54a7c806 --- /dev/null +++ b/R-package/docs/LICENSE.html @@ -0,0 +1,167 @@ + + + + + + + + +License • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation 
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+ +
+ +
+ + + +
+ + + diff --git a/R-package/docs/articles/basic_walkthrough.html b/R-package/docs/articles/basic_walkthrough.html new file mode 100644 index 000000000000..6dee21a57a31 --- /dev/null +++ b/R-package/docs/articles/basic_walkthrough.html @@ -0,0 +1,300 @@ + + + + + + + +Basic Walkthrough • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
require(lightgbm)
+
## Loading required package: lightgbm
+
## Loading required package: R6
+
require(methods)
+
+# We load in the agaricus dataset
+# In this example, we are aiming to predict whether a mushroom is edible
+data(agaricus.train, package = "lightgbm")
+data(agaricus.test, package = "lightgbm")
+train <- agaricus.train
+test <- agaricus.test
+
+# The loaded data is stored in sparseMatrix, and label is a numeric vector in {0,1}
+class(train$label)
+
## [1] "numeric"
+
class(train$data)
+
## [1] "dgCMatrix"
+## attr(,"package")
+## [1] "Matrix"
+
#--------------------Basic Training using lightgbm----------------
+# This is the basic usage of lightgbm you can put matrix in data field
+# Note: we are putting in sparse matrix here, lightgbm naturally handles sparse input
+# Use sparse matrix when your feature is sparse (e.g. when you are using one-hot encoding vector)
+print("Training lightgbm with sparseMatrix")
+
## [1] "Training lightgbm with sparseMatrix"
+
bst <- lightgbm(data = train$data,
+                label = train$label,
+                num_leaves = 4,
+                learning_rate = 1,
+                nrounds = 2,
+                nthread = 1,
+                objective = "binary")
+
## Loading required package: Matrix
+
## [1]: train's binary_logloss:0.198843 
+## [2]: train's binary_logloss:0.11168
+
# Alternatively, you can put in dense matrix, i.e. basic R-matrix
+print("Training lightgbm with Matrix")
+
## [1] "Training lightgbm with Matrix"
+
bst <- lightgbm(data = as.matrix(train$data),
+                label = train$label,
+                num_leaves = 4,
+                learning_rate = 1,
+                nrounds = 2,
+                nthread = 1,
+                objective = "binary")
+
## [1]: train's binary_logloss:0.198843 
+## [2]: train's binary_logloss:0.11168
+
# You can also put in lgb.Dataset object, which stores label, data and other meta datas needed for advanced features
+print("Training lightgbm with lgb.Dataset")
+
## [1] "Training lightgbm with lgb.Dataset"
+
dtrain <- lgb.Dataset(data = train$data,
+                      label = train$label)
+bst <- lightgbm(data = dtrain,
+                num_leaves = 4,
+                learning_rate = 1,
+                nrounds = 2,
+                nthread = 1,
+                objective = "binary")
+
## [1]: train's binary_logloss:0.198843 
+## [2]: train's binary_logloss:0.11168
+
# Verbose = 0,1,2
+print("Train lightgbm with verbose 0, no message")
+
## [1] "Train lightgbm with verbose 0, no message"
+
bst <- lightgbm(data = dtrain,
+                num_leaves = 4,
+                learning_rate = 1,
+                nrounds = 2,
+                nthread = 1,
+                objective = "binary",
+                verbose = 0)
+
+print("Train lightgbm with verbose 1, print evaluation metric")
+
## [1] "Train lightgbm with verbose 1, print evaluation metric"
+
bst <- lightgbm(data = dtrain,
+                num_leaves = 4,
+                learning_rate = 1,
+                nrounds = 2,
+                nthread = 1,
+                objective = "binary",
+                verbose = 1)
+
## [1]: train's binary_logloss:0.198843 
+## [2]: train's binary_logloss:0.11168
+
print("Train lightgbm with verbose 2, also print information about tree")
+
## [1] "Train lightgbm with verbose 2, also print information about tree"
+
bst <- lightgbm(data = dtrain,
+                num_leaves = 4,
+                learning_rate = 1,
+                nrounds = 2,
+                nthread = 1,
+                objective = "binary",
+                verbose = 2)
+
## [1]: train's binary_logloss:0.198843 
+## [2]: train's binary_logloss:0.11168
+
# You can also specify data as file path to a LibSVM/TCV/CSV format input
+# Since we do not have this file with us, the following line is just for illustration
+# bst <- lightgbm(data = "agaricus.train.svm", num_leaves = 4, learning_rate = 1, nrounds = 2,objective = "binary")
+
+#--------------------Basic prediction using lightgbm--------------
+# You can do prediction using the following line
+# You can put in Matrix, sparseMatrix, or lgb.Dataset
+pred <- predict(bst, test$data)
+err <- mean(as.numeric(pred > 0.5) != test$label)
+print(paste("test-error=", err))
+
## [1] "test-error= 0.0217256362507759"
+
#--------------------Save and load models-------------------------
+# Save model to binary local file
+# Crash temporary workaround for pkgdown
+if (!(pkgdown::in_pkgdown())) {
+  lgb.save(bst, "lightgbm.model")
+  
+  # Load binary model to R
+  bst2 <- lgb.load("lightgbm.model")
+  pred2 <- predict(bst2, test$data)
+  
+  # pred2 should be identical to pred
+  print(paste("sum(abs(pred2-pred))=", sum(abs(pred2 - pred))))
+}
+
+#--------------------Advanced features ---------------------------
+# To use advanced features, we need to put data in lgb.Dataset
+dtrain <- lgb.Dataset(data = train$data, label = train$label, free_raw_data = FALSE)
+dtest <- lgb.Dataset(data = test$data, label = test$label, free_raw_data = FALSE)
+
+#--------------------Using validation set-------------------------
+# valids is a list of lgb.Dataset, each of them is tagged with name
+valids <- list(train = dtrain, test = dtest)
+
+# To train with valids, use lgb.train, which contains more advanced features
+# valids allows us to monitor the evaluation result on all data in the list
+print("Train lightgbm using lgb.train with valids")
+
## [1] "Train lightgbm using lgb.train with valids"
+
bst <- lgb.train(data = dtrain,
+                 num_leaves = 4,
+                 learning_rate = 1,
+                 nrounds = 2,
+                 valids = valids,
+                 nthread = 1,
+                 objective = "binary")
+
## [1]: train's binary_logloss:0.198843 test's binary_logloss:0.204992 
+## [2]: train's binary_logloss:0.11168  test's binary_logloss:0.113243
+
# We can change evaluation metrics, or use multiple evaluation metrics
+print("Train lightgbm using lgb.train with valids, watch logloss and error")
+
## [1] "Train lightgbm using lgb.train with valids, watch logloss and error"
+
bst <- lgb.train(data = dtrain,
+                 num_leaves = 4,
+                 learning_rate = 1,
+                 nrounds = 2,
+                 valids = valids,
+                 eval = c("binary_error", "binary_logloss"),
+                 nthread = 1,
+                 objective = "binary")
+
## [1]: train's binary_error:0.0304007  train's binary_logloss:0.198843 test's binary_error:0.0335196   test's binary_logloss:0.204992 
+## [2]: train's binary_error:0.0222632  train's binary_logloss:0.11168  test's binary_error:0.0217256   test's binary_logloss:0.113243
+
# lgb.Dataset can also be saved using lgb.Dataset.save
+lgb.Dataset.save(dtrain, "dtrain.buffer")
+
+# To load it in, simply call lgb.Dataset
+dtrain2 <- lgb.Dataset("dtrain.buffer")
+bst <- lgb.train(data = dtrain2,
+                 num_leaves = 4,
+                 learning_rate = 1,
+                 nrounds = 2,
+                 valids = valids,
+                 nthread = 1,
+                 objective = "binary")
+
## [1]: train's binary_logloss:0.198843 test's binary_logloss:0.204992 
+## [2]: train's binary_logloss:0.11168  test's binary_logloss:0.113243
+
# information can be extracted from lgb.Dataset using getinfo
+label = getinfo(dtest, "label")
+pred <- predict(bst, test$data)
+err <- as.numeric(sum(as.integer(pred > 0.5) != label)) / length(label)
+print(paste("test-error=", err))
+
## [1] "test-error= 0.0217256362507759"
+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/boost_from_prediction.html b/R-package/docs/articles/boost_from_prediction.html new file mode 100644 index 000000000000..5181de7c0482 --- /dev/null +++ b/R-package/docs/articles/boost_from_prediction.html @@ -0,0 +1,172 @@ + + + + + + + +Boosting from existing prediction • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
require(lightgbm)
+
## Loading required package: lightgbm
+
## Loading required package: R6
+
require(methods)
+
+# Load in the agaricus dataset
+data(agaricus.train, package = "lightgbm")
+data(agaricus.test, package = "lightgbm")
+dtrain <- lgb.Dataset(agaricus.train$data, label = agaricus.train$label)
+dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label)
+
+valids <- list(eval = dtest, train = dtrain)
+#--------------------Advanced features ---------------------------
+# advanced: start from a initial base prediction
+print("Start running example to start from a initial prediction")
+
## [1] "Start running example to start from a initial prediction"
+
# Train lightgbm for 1 round
+param <- list(num_leaves = 4,
+              learning_rate = 1,
+              nthread = 1,
+              objective = "binary")
+bst <- lgb.train(param, dtrain, 1, valids = valids)
+
## Loading required package: Matrix
+
## [1]: train's binary_logloss:0.198843 eval's binary_logloss:0.204992
+
# Note: we need the margin value instead of transformed prediction in set_init_score
+ptrain <- predict(bst, agaricus.train$data, rawscore = TRUE)
+ptest  <- predict(bst, agaricus.test$data, rawscore = TRUE)
+
+# set the init_score property of dtrain and dtest
+# base margin is the base prediction we will boost from
+setinfo(dtrain, "init_score", ptrain)
+setinfo(dtest, "init_score", ptest)
+
+print("This is result of boost from initial prediction")
+
## [1] "This is result of boost from initial prediction"
+
bst <- lgb.train(params = param,
+                 data = dtrain,
+                 nrounds = 5,
+                 nthread = 1,
+                 valids = valids)
+
## [1]: train's binary_logloss:0.11168  eval's binary_logloss:0.113243 
+## [2]: train's binary_logloss:0.0481094    eval's binary_logloss:0.0476983 
+## [3]: train's binary_logloss:0.0279468    eval's binary_logloss:0.0234973 
+## [4]: train's binary_logloss:0.0174926    eval's binary_logloss:0.0137969 
+## [5]: train's binary_logloss:0.0624553    eval's binary_logloss:0.105701
+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/categorical_features_prepare.html b/R-package/docs/articles/categorical_features_prepare.html new file mode 100644 index 000000000000..d34523847cc4 --- /dev/null +++ b/R-package/docs/articles/categorical_features_prepare.html @@ -0,0 +1,344 @@ + + + + + + + +Categorical Feature Preparation • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
# Here we are going to try training a model with categorical features
+
+# Load libraries
+library(data.table)
+library(lightgbm)
+
## Loading required package: R6
+
# Load data and look at the structure
+# 
+# Classes 'data.table' and 'data.frame':    4521 obs. of  17 variables:
+# $ age      : int  30 33 35 30 59 35 36 39 41 43 ...
+# $ job      : chr  "unemployed" "services" "management" "management" ...
+# $ marital  : chr  "married" "married" "single" "married" ...
+# $ education: chr  "primary" "secondary" "tertiary" "tertiary" ...
+# $ default  : chr  "no" "no" "no" "no" ...
+# $ balance  : int  1787 4789 1350 1476 0 747 307 147 221 -88 ...
+# $ housing  : chr  "no" "yes" "yes" "yes" ...
+# $ loan     : chr  "no" "yes" "no" "yes" ...
+# $ contact  : chr  "cellular" "cellular" "cellular" "unknown" ...
+# $ day      : int  19 11 16 3 5 23 14 6 14 17 ...
+# $ month    : chr  "oct" "may" "apr" "jun" ...
+# $ duration : int  79 220 185 199 226 141 341 151 57 313 ...
+# $ campaign : int  1 1 1 4 1 2 1 2 2 1 ...
+# $ pdays    : int  -1 339 330 -1 -1 176 330 -1 -1 147 ...
+# $ previous : int  0 4 1 0 0 3 2 0 0 2 ...
+# $ poutcome : chr  "unknown" "failure" "failure" "unknown" ...
+# $ y        : chr  "no" "no" "no" "no" ...
+data(bank, package = "lightgbm")
+str(bank)
+
## Classes 'data.table' and 'data.frame':   4521 obs. of  17 variables:
+##  $ age      : int  30 33 35 30 59 35 36 39 41 43 ...
+##  $ job      : chr  "unemployed" "services" "management" "management" ...
+##  $ marital  : chr  "married" "married" "single" "married" ...
+##  $ education: chr  "primary" "secondary" "tertiary" "tertiary" ...
+##  $ default  : chr  "no" "no" "no" "no" ...
+##  $ balance  : int  1787 4789 1350 1476 0 747 307 147 221 -88 ...
+##  $ housing  : chr  "no" "yes" "yes" "yes" ...
+##  $ loan     : chr  "no" "yes" "no" "yes" ...
+##  $ contact  : chr  "cellular" "cellular" "cellular" "unknown" ...
+##  $ day      : int  19 11 16 3 5 23 14 6 14 17 ...
+##  $ month    : chr  "oct" "may" "apr" "jun" ...
+##  $ duration : int  79 220 185 199 226 141 341 151 57 313 ...
+##  $ campaign : int  1 1 1 4 1 2 1 2 2 1 ...
+##  $ pdays    : int  -1 339 330 -1 -1 176 330 -1 -1 147 ...
+##  $ previous : int  0 4 1 0 0 3 2 0 0 2 ...
+##  $ poutcome : chr  "unknown" "failure" "failure" "unknown" ...
+##  $ y        : chr  "no" "no" "no" "no" ...
+##  - attr(*, ".internal.selfref")=<externalptr>
+
# We must now transform the data to fit in LightGBM
+# For this task, we use lgb.prepare
+# The function transforms the data into a fittable data
+# 
+# Classes 'data.table' and 'data.frame':    4521 obs. of  17 variables:
+# $ age      : int  30 33 35 30 59 35 36 39 41 43 ...
+# $ job      : chr  "unemployed" "services" "management" "management" ...
+# $ marital  : chr  "married" "married" "single" "married" ...
+# $ education: chr  "primary" "secondary" "tertiary" "tertiary" ...
+# $ default  : chr  "no" "no" "no" "no" ...
+# $ balance  : int  1787 4789 1350 1476 0 747 307 147 221 -88 ...
+# $ housing  : chr  "no" "yes" "yes" "yes" ...
+# $ loan     : chr  "no" "yes" "no" "yes" ...
+# $ contact  : chr  "cellular" "cellular" "cellular" "unknown" ...
+# $ day      : int  19 11 16 3 5 23 14 6 14 17 ...
+# $ month    : chr  "oct" "may" "apr" "jun" ...
+# $ duration : int  79 220 185 199 226 141 341 151 57 313 ...
+# $ campaign : int  1 1 1 4 1 2 1 2 2 1 ...
+# $ pdays    : int  -1 339 330 -1 -1 176 330 -1 -1 147 ...
+# $ previous : int  0 4 1 0 0 3 2 0 0 2 ...
+# $ poutcome : chr  "unknown" "failure" "failure" "unknown" ...
+# $ y        : chr  "no" "no" "no" "no" ...
+bank <- lgb.prepare(data = bank)
+str(bank)
+
## Classes 'data.table' and 'data.frame':   4521 obs. of  17 variables:
+##  $ age      : int  30 33 35 30 59 35 36 39 41 43 ...
+##  $ job      : num  11 8 5 5 2 5 7 10 3 8 ...
+##  $ marital  : num  2 2 3 2 2 3 2 2 2 2 ...
+##  $ education: num  1 2 3 3 2 3 3 2 3 1 ...
+##  $ default  : num  1 1 1 1 1 1 1 1 1 1 ...
+##  $ balance  : int  1787 4789 1350 1476 0 747 307 147 221 -88 ...
+##  $ housing  : num  1 2 2 2 2 1 2 2 2 2 ...
+##  $ loan     : num  1 2 1 2 1 1 1 1 1 2 ...
+##  $ contact  : num  1 1 1 3 3 1 1 1 3 1 ...
+##  $ day      : int  19 11 16 3 5 23 14 6 14 17 ...
+##  $ month    : num  11 9 1 7 9 4 9 9 9 1 ...
+##  $ duration : int  79 220 185 199 226 141 341 151 57 313 ...
+##  $ campaign : int  1 1 1 4 1 2 1 2 2 1 ...
+##  $ pdays    : int  -1 339 330 -1 -1 176 330 -1 -1 147 ...
+##  $ previous : int  0 4 1 0 0 3 2 0 0 2 ...
+##  $ poutcome : num  4 1 1 4 4 1 2 4 4 1 ...
+##  $ y        : num  1 1 1 1 1 1 1 1 1 1 ...
+##  - attr(*, ".internal.selfref")=<externalptr>
+
# Remove 1 to label because it must be between 0 and 1
+bank$y <- bank$y - 1
+
+# Data input to LightGBM must be a matrix, without the label
+my_data <- as.matrix(bank[, 1:16, with = FALSE])
+
+# Creating the LightGBM dataset with categorical features
+# The categorical features must be indexed like in R (1-indexed, not 0-indexed)
+lgb_data <- lgb.Dataset(data = my_data,
+                        label = bank$y,
+                        categorical_feature = c(2, 3, 4, 5, 7, 8, 9, 11, 16))
+
+# We can now train a model
+model <- lgb.train(list(objective = "binary",
+                        metric = "l2",
+                        nthread = 1,
+                        min_data = 1,
+                        learning_rate = 0.1,
+                        min_hessian = 1,
+                        max_depth = 2),
+                   lgb_data,
+                   100,
+                   valids = list(train = lgb_data))
+
## [1]: train's l2:0.217736 
+## [2]: train's l2:0.191678 
+## [3]: train's l2:0.170597 
+## [4]: train's l2:0.153499 
+## [5]: train's l2:0.139624 
+## [6]: train's l2:0.128409 
+## [7]: train's l2:0.119125 
+## [8]: train's l2:0.111578 
+## [9]: train's l2:0.10539 
+## [10]:    train's l2:0.100182 
+## [11]:    train's l2:0.0959854 
+## [12]:    train's l2:0.0925037 
+## [13]:    train's l2:0.0894105 
+## [14]:    train's l2:0.0870018 
+## [15]:    train's l2:0.0850329 
+## [16]:    train's l2:0.0832162 
+## [17]:    train's l2:0.0817969 
+## [18]:    train's l2:0.0805792 
+## [19]:    train's l2:0.0794556 
+## [20]:    train's l2:0.078615 
+## [21]:    train's l2:0.0778916 
+## [22]:    train's l2:0.0770496 
+## [23]:    train's l2:0.0764825 
+## [24]:    train's l2:0.0760338 
+## [25]:    train's l2:0.075266 
+## [26]:    train's l2:0.0748611 
+## [27]:    train's l2:0.0744663 
+## [28]:    train's l2:0.074148 
+## [29]:    train's l2:0.0738167 
+## [30]:    train's l2:0.0732869 
+## [31]:    train's l2:0.0730472 
+## [32]:    train's l2:0.0725745 
+## [33]:    train's l2:0.0721689 
+## [34]:    train's l2:0.0719837 
+## [35]:    train's l2:0.0716568 
+## [36]:    train's l2:0.0714165 
+## [37]:    train's l2:0.0712889 
+## [38]:    train's l2:0.0711586 
+## [39]:    train's l2:0.0708194 
+## [40]:    train's l2:0.0705857 
+## [41]:    train's l2:0.0702503 
+## [42]:    train's l2:0.0700202 
+## [43]:    train's l2:0.0698951 
+## [44]:    train's l2:0.0696913 
+## [45]:    train's l2:0.0695681 
+## [46]:    train's l2:0.0694261 
+## [47]:    train's l2:0.0692232 
+## [48]:    train's l2:0.0690527 
+## [49]:    train's l2:0.0689585 
+## [50]:    train's l2:0.0687556 
+## [51]:    train's l2:0.0685764 
+## [52]:    train's l2:0.0685009 
+## [53]:    train's l2:0.0683634 
+## [54]:    train's l2:0.0681724 
+## [55]:    train's l2:0.0679939 
+## [56]:    train's l2:0.0678073 
+## [57]:    train's l2:0.067689 
+## [58]:    train's l2:0.0675343 
+## [59]:    train's l2:0.0673871 
+## [60]:    train's l2:0.0672275 
+## [61]:    train's l2:0.0671656 
+## [62]:    train's l2:0.0670863 
+## [63]:    train's l2:0.0669049 
+## [64]:    train's l2:0.0667991 
+## [65]:    train's l2:0.0667414 
+## [66]:    train's l2:0.0665912 
+## [67]:    train's l2:0.0664871 
+## [68]:    train's l2:0.0663864 
+## [69]:    train's l2:0.0662678 
+## [70]:    train's l2:0.0662279 
+## [71]:    train's l2:0.0660886 
+## [72]:    train's l2:0.065937 
+## [73]:    train's l2:0.0659013 
+## [74]:    train's l2:0.0657467 
+## [75]:    train's l2:0.0655841 
+## [76]:    train's l2:0.0654689 
+## [77]:    train's l2:0.0653655 
+## [78]:    train's l2:0.0653227 
+## [79]:    train's l2:0.0651911 
+## [80]:    train's l2:0.0650897 
+## [81]:    train's l2:0.0650003 
+## [82]:    train's l2:0.0648883 
+## [83]:    train's l2:0.0647997 
+## [84]:    train's l2:0.0646982 
+## [85]:    train's l2:0.0646623 
+## [86]:    train's l2:0.0645255 
+## [87]:    train's l2:0.0644004 
+## [88]:    train's l2:0.0642746 
+## [89]:    train's l2:0.0641889 
+## [90]:    train's l2:0.0640877 
+## [91]:    train's l2:0.0638363 
+## [92]:    train's l2:0.0637582 
+## [93]:    train's l2:0.0637263 
+## [94]:    train's l2:0.0636626 
+## [95]:    train's l2:0.0635542 
+## [96]:    train's l2:0.0634245 
+## [97]:    train's l2:0.0633328 
+## [98]:    train's l2:0.063234 
+## [99]:    train's l2:0.0630126 
+## [100]:   train's l2:0.0629891
+
# Try to find split_feature: 2
+# If you find it, it means it used a categorical feature in the first tree
+lgb.dump(model, num_iteration = 1)
+
## [1] "{\"name\":\"tree\",\n\"version\":\"v2\",\n\"num_class\":1,\n\"num_tree_per_iteration\":1,\n\"label_index\":0,\n\"max_feature_idx\":15,\n\"feature_names\":[\"age\",\"job\",\"marital\",\"education\",\"default\",\"balance\",\"housing\",\"loan\",\"contact\",\"day\",\"month\",\"duration\",\"campaign\",\"pdays\",\"previous\",\"poutcome\"],\n\"tree_info\":[{\"tree_index\":0,\"num_leaves\":4,\n\"num_cat\":2,\n\"shrinkage\":0.10000000000000001,\n\"tree_structure\":{\n\"split_index\":0,\n\"split_feature\":11,\n\"split_gain\":229.80378723144531,\n\"threshold\":647.00000000000011,\n\"decision_type\":\"<=\",\n\"default_left\":true,\n\"missing_type\":\"None\",\n\"internal_value\":0,\n\"internal_count\":4521,\n\"left_child\":{\n\"split_index\":1,\n\"split_feature\":15,\n\"split_gain\":156.62019348144531,\n\"threshold\":\"3\",\n\"decision_type\":\"==\",\n\"default_left\":false,\n\"missing_type\":\"None\",\n\"internal_value\":-1.6706673067690831,\n\"internal_count\":4166,\n\"left_child\":{\n\"leaf_index\":0,\n\"leaf_value\":0.062068965517241385,\n\"leaf_count\":116\n},\n\"right_child\":{\n\"leaf_index\":2,\n\"leaf_value\":-0.17362962962962963,\n\"leaf_count\":4050\n}\n},\n\"right_child\":{\n\"split_index\":2,\n\"split_feature\":2,\n\"split_gain\":14.507294654846191,\n\"threshold\":\"2\",\n\"decision_type\":\"==\",\n\"default_left\":false,\n\"missing_type\":\"None\",\n\"internal_value\":0.0056338028169014088,\n\"internal_count\":355,\n\"left_child\":{\n\"leaf_index\":1,\n\"leaf_value\":-0.03482587064676617,\n\"leaf_count\":201\n},\n\"right_child\":{\n\"leaf_index\":3,\n\"leaf_value\":0.046753246753246755,\n\"leaf_count\":154\n}\n}\n}\n}]\n}\n"
+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/categorical_features_rules.html b/R-package/docs/articles/categorical_features_rules.html new file mode 100644 index 000000000000..c1c3f16ecb6f --- /dev/null +++ b/R-package/docs/articles/categorical_features_rules.html @@ -0,0 +1,354 @@ + + + + + + + +Categorical Feature Preparation with Rule • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
# Here we are going to try training a model with categorical features
+
+# Load libraries
+library(data.table)
+library(lightgbm)
+
## Loading required package: R6
+
# Load data and look at the structure
+# 
+# Classes 'data.table' and 'data.frame':    4521 obs. of  17 variables:
+# $ age      : int  30 33 35 30 59 35 36 39 41 43 ...
+# $ job      : chr  "unemployed" "services" "management" "management" ...
+# $ marital  : chr  "married" "married" "single" "married" ...
+# $ education: chr  "primary" "secondary" "tertiary" "tertiary" ...
+# $ default  : chr  "no" "no" "no" "no" ...
+# $ balance  : int  1787 4789 1350 1476 0 747 307 147 221 -88 ...
+# $ housing  : chr  "no" "yes" "yes" "yes" ...
+# $ loan     : chr  "no" "yes" "no" "yes" ...
+# $ contact  : chr  "cellular" "cellular" "cellular" "unknown" ...
+# $ day      : int  19 11 16 3 5 23 14 6 14 17 ...
+# $ month    : chr  "oct" "may" "apr" "jun" ...
+# $ duration : int  79 220 185 199 226 141 341 151 57 313 ...
+# $ campaign : int  1 1 1 4 1 2 1 2 2 1 ...
+# $ pdays    : int  -1 339 330 -1 -1 176 330 -1 -1 147 ...
+# $ previous : int  0 4 1 0 0 3 2 0 0 2 ...
+# $ poutcome : chr  "unknown" "failure" "failure" "unknown" ...
+# $ y        : chr  "no" "no" "no" "no" ...
+data(bank, package = "lightgbm")
+str(bank)
+
## Classes 'data.table' and 'data.frame':   4521 obs. of  17 variables:
+##  $ age      : int  30 33 35 30 59 35 36 39 41 43 ...
+##  $ job      : chr  "unemployed" "services" "management" "management" ...
+##  $ marital  : chr  "married" "married" "single" "married" ...
+##  $ education: chr  "primary" "secondary" "tertiary" "tertiary" ...
+##  $ default  : chr  "no" "no" "no" "no" ...
+##  $ balance  : int  1787 4789 1350 1476 0 747 307 147 221 -88 ...
+##  $ housing  : chr  "no" "yes" "yes" "yes" ...
+##  $ loan     : chr  "no" "yes" "no" "yes" ...
+##  $ contact  : chr  "cellular" "cellular" "cellular" "unknown" ...
+##  $ day      : int  19 11 16 3 5 23 14 6 14 17 ...
+##  $ month    : chr  "oct" "may" "apr" "jun" ...
+##  $ duration : int  79 220 185 199 226 141 341 151 57 313 ...
+##  $ campaign : int  1 1 1 4 1 2 1 2 2 1 ...
+##  $ pdays    : int  -1 339 330 -1 -1 176 330 -1 -1 147 ...
+##  $ previous : int  0 4 1 0 0 3 2 0 0 2 ...
+##  $ poutcome : chr  "unknown" "failure" "failure" "unknown" ...
+##  $ y        : chr  "no" "no" "no" "no" ...
+##  - attr(*, ".internal.selfref")=<externalptr>
+
# We are dividing the dataset into two: one train, one validation
+bank_train <- bank[1:4000, ]
+bank_test <- bank[4001:4521, ]
+
+# We must now transform the data to fit in LightGBM
+# For this task, we use lgb.prepare
+# The function transforms the data into a fittable data
+# 
+# Classes 'data.table' and 'data.frame':    521 obs. of  17 variables:
+# $ age      : int  53 36 58 26 34 55 55 34 41 38 ...
+# $ job      : num  1 10 10 9 10 2 2 3 3 4 ...
+# $ marital  : num  1 2 1 3 3 2 2 2 1 1 ...
+# $ education: num  2 2 2 2 2 1 2 3 2 2 ...
+# $ default  : num  1 1 1 1 1 1 1 1 1 1 ...
+# $ balance  : int  26 191 -123 -147 179 1086 471 105 1588 70 ...
+# $ housing  : num  2 1 1 1 1 2 2 2 2 1 ...
+# $ loan     : num  1 1 1 1 1 1 1 1 2 1 ...
+# $ contact  : num  1 1 1 3 1 1 3 3 3 1 ...
+# $ day      : int  7 31 5 4 19 6 30 28 20 27 ...
+# $ month    : num  9 2 2 7 2 9 9 9 7 11 ...
+# $ duration : int  56 69 131 95 294 146 58 249 10 255 ...
+# $ campaign : int  1 1 2 2 3 1 2 2 8 3 ...
+# $ pdays    : int  359 -1 -1 -1 -1 272 -1 -1 -1 148 ...
+# $ previous : int  1 0 0 0 0 2 0 0 0 1 ...
+# $ poutcome : num  1 4 4 4 4 1 4 4 4 3 ...
+# $ y        : num  1 1 1 1 1 1 1 1 1 2 ...
+bank_rules <- lgb.prepare_rules(data = bank_train)
+bank_train <- bank_rules$data
+bank_test <- lgb.prepare_rules(data = bank_test, rules = bank_rules$rules)$data
+str(bank_test)
+
## Classes 'data.table' and 'data.frame':   521 obs. of  17 variables:
+##  $ age      : int  53 36 58 26 34 55 55 34 41 38 ...
+##  $ job      : num  1 10 10 9 10 2 2 3 3 4 ...
+##  $ marital  : num  1 2 1 3 3 2 2 2 1 1 ...
+##  $ education: num  2 2 2 2 2 1 2 3 2 2 ...
+##  $ default  : num  1 1 1 1 1 1 1 1 1 1 ...
+##  $ balance  : int  26 191 -123 -147 179 1086 471 105 1588 70 ...
+##  $ housing  : num  2 1 1 1 1 2 2 2 2 1 ...
+##  $ loan     : num  1 1 1 1 1 1 1 1 2 1 ...
+##  $ contact  : num  1 1 1 3 1 1 3 3 3 1 ...
+##  $ day      : int  7 31 5 4 19 6 30 28 20 27 ...
+##  $ month    : num  9 2 2 7 2 9 9 9 7 11 ...
+##  $ duration : int  56 69 131 95 294 146 58 249 10 255 ...
+##  $ campaign : int  1 1 2 2 3 1 2 2 8 3 ...
+##  $ pdays    : int  359 -1 -1 -1 -1 272 -1 -1 -1 148 ...
+##  $ previous : int  1 0 0 0 0 2 0 0 0 1 ...
+##  $ poutcome : num  1 4 4 4 4 1 4 4 4 3 ...
+##  $ y        : num  1 1 1 1 1 1 1 1 1 2 ...
+##  - attr(*, ".internal.selfref")=<externalptr>
+
# Remove 1 to label because it must be between 0 and 1
+bank_train$y <- bank_train$y - 1
+bank_test$y <- bank_test$y - 1
+
+# Data input to LightGBM must be a matrix, without the label
+my_data_train <- as.matrix(bank_train[, 1:16, with = FALSE])
+my_data_test <- as.matrix(bank_test[, 1:16, with = FALSE])
+
+# Creating the LightGBM dataset with categorical features
+# The categorical features can be passed to lgb.train to not copy and paste a lot
+dtrain <- lgb.Dataset(data = my_data_train,
+                      label = bank_train$y)
+dtest <- lgb.Dataset(data = my_data_test,
+                     label = bank_test$y)
+
+# We can now train a model
+model <- lgb.train(list(objective = "binary",
+                        metric = "l2",
+                        nthread = 1,
+                        min_data = 1,
+                        learning_rate = 0.1,
+                        min_hessian = 1,
+                        max_depth = 2,
+                        categorical_feature = c(2, 3, 4, 5, 7, 8, 9, 11, 16)),
+                   dtrain,
+                   100,
+                   valids = list(train = dtrain, valid = dtest))
+
## [1]: train's l2:0.218547 valid's l2:0.219319 
+## [2]: train's l2:0.193199 valid's l2:0.194746 
+## [3]: train's l2:0.172641 valid's l2:0.17521 
+## [4]: train's l2:0.155786 valid's l2:0.15914 
+## [5]: train's l2:0.14213  valid's l2:0.145937 
+## [6]: train's l2:0.131005 valid's l2:0.135395 
+## [7]: train's l2:0.12174  valid's l2:0.126573 
+## [8]: train's l2:0.114305 valid's l2:0.119354 
+## [9]: train's l2:0.1081   valid's l2:0.113633 
+## [10]:    train's l2:0.102941 valid's l2:0.107969 
+## [11]:    train's l2:0.0987159    valid's l2:0.103675 
+## [12]:    train's l2:0.0952544    valid's l2:0.100598 
+## [13]:    train's l2:0.0923753    valid's l2:0.0973981 
+## [14]:    train's l2:0.0900202    valid's l2:0.0949834 
+## [15]:    train's l2:0.0879191    valid's l2:0.0931068 
+## [16]:    train's l2:0.0863022    valid's l2:0.0914335 
+## [17]:    train's l2:0.0849219    valid's l2:0.0901021 
+## [18]:    train's l2:0.0835936    valid's l2:0.0888896 
+## [19]:    train's l2:0.0826468    valid's l2:0.0878815 
+## [20]:    train's l2:0.081797 valid's l2:0.0866827 
+## [21]:    train's l2:0.0809775    valid's l2:0.0860839 
+## [22]:    train's l2:0.0803427    valid's l2:0.0854876 
+## [23]:    train's l2:0.0797951    valid's l2:0.0853016 
+## [24]:    train's l2:0.0791358    valid's l2:0.0850711 
+## [25]:    train's l2:0.0786815    valid's l2:0.0843546 
+## [26]:    train's l2:0.0782522    valid's l2:0.0841719 
+## [27]:    train's l2:0.077961 valid's l2:0.08392 
+## [28]:    train's l2:0.0776035    valid's l2:0.0835606 
+## [29]:    train's l2:0.0770722    valid's l2:0.0831014 
+## [30]:    train's l2:0.0768721    valid's l2:0.0829624 
+## [31]:    train's l2:0.0765371    valid's l2:0.0827473 
+## [32]:    train's l2:0.0763328    valid's l2:0.0826138 
+## [33]:    train's l2:0.0761409    valid's l2:0.0821803 
+## [34]:    train's l2:0.0758711    valid's l2:0.0820529 
+## [35]:    train's l2:0.0757279    valid's l2:0.0819736 
+## [36]:    train's l2:0.0755947    valid's l2:0.0818789 
+## [37]:    train's l2:0.0753168    valid's l2:0.0817608 
+## [38]:    train's l2:0.0751867    valid's l2:0.0814168 
+## [39]:    train's l2:0.0748237    valid's l2:0.0814926 
+## [40]:    train's l2:0.0745276    valid's l2:0.0810787 
+## [41]:    train's l2:0.0742475    valid's l2:0.0807388 
+## [42]:    train's l2:0.0740241    valid's l2:0.0806229 
+## [43]:    train's l2:0.0739098    valid's l2:0.0806254 
+## [44]:    train's l2:0.073664 valid's l2:0.080449 
+## [45]:    train's l2:0.0736108    valid's l2:0.0804152 
+## [46]:    train's l2:0.0733494    valid's l2:0.0804195 
+## [47]:    train's l2:0.0730964    valid's l2:0.0798332 
+## [48]:    train's l2:0.0730014    valid's l2:0.0799223 
+## [49]:    train's l2:0.0728088    valid's l2:0.0799888 
+## [50]:    train's l2:0.0725185    valid's l2:0.0799877 
+## [51]:    train's l2:0.0724482    valid's l2:0.0799518 
+## [52]:    train's l2:0.0722151    valid's l2:0.0800195 
+## [53]:    train's l2:0.0719814    valid's l2:0.079813 
+## [54]:    train's l2:0.0718549    valid's l2:0.0797692 
+## [55]:    train's l2:0.0716643    valid's l2:0.0796802 
+## [56]:    train's l2:0.0715891    valid's l2:0.0796772 
+## [57]:    train's l2:0.0713858    valid's l2:0.0797784 
+## [58]:    train's l2:0.0711216    valid's l2:0.0799199 
+## [59]:    train's l2:0.070894 valid's l2:0.0797905 
+## [60]:    train's l2:0.0705351    valid's l2:0.0794658 
+## [61]:    train's l2:0.0704668    valid's l2:0.0794671 
+## [62]:    train's l2:0.0703246    valid's l2:0.079374 
+## [63]:    train's l2:0.0701194    valid's l2:0.0789409 
+## [64]:    train's l2:0.0698633    valid's l2:0.078693 
+## [65]:    train's l2:0.0698044    valid's l2:0.0786952 
+## [66]:    train's l2:0.0696808    valid's l2:0.078649 
+## [67]:    train's l2:0.0695161    valid's l2:0.0782809 
+## [68]:    train's l2:0.0692527    valid's l2:0.0780414 
+## [69]:    train's l2:0.0687731    valid's l2:0.0774695 
+## [70]:    train's l2:0.0686329    valid's l2:0.0776007 
+## [71]:    train's l2:0.0684736    valid's l2:0.0774359 
+## [72]:    train's l2:0.0684289    valid's l2:0.0774821 
+## [73]:    train's l2:0.0682447    valid's l2:0.077642 
+## [74]:    train's l2:0.0678441    valid's l2:0.0771838 
+## [75]:    train's l2:0.067732 valid's l2:0.0771857 
+## [76]:    train's l2:0.067545 valid's l2:0.0769763 
+## [77]:    train's l2:0.0673388    valid's l2:0.0769291 
+## [78]:    train's l2:0.0672337    valid's l2:0.0768385 
+## [79]:    train's l2:0.0671938    valid's l2:0.0768484 
+## [80]:    train's l2:0.0670772    valid's l2:0.0767856 
+## [81]:    train's l2:0.0669279    valid's l2:0.0767355 
+## [82]:    train's l2:0.0668174    valid's l2:0.0768689 
+## [83]:    train's l2:0.0667102    valid's l2:0.0767268 
+## [84]:    train's l2:0.0665359    valid's l2:0.0767133 
+## [85]:    train's l2:0.0664498    valid's l2:0.0767154 
+## [86]:    train's l2:0.0661474    valid's l2:0.0763899 
+## [87]:    train's l2:0.0661185    valid's l2:0.0763743 
+## [88]:    train's l2:0.0660187    valid's l2:0.0765239 
+## [89]:    train's l2:0.065929 valid's l2:0.0764648 
+## [90]:    train's l2:0.0658001    valid's l2:0.0764113 
+## [91]:    train's l2:0.0656409    valid's l2:0.0763919 
+## [92]:    train's l2:0.0655088    valid's l2:0.0765255 
+## [93]:    train's l2:0.0652731    valid's l2:0.0762637 
+## [94]:    train's l2:0.0651455    valid's l2:0.076341 
+## [95]:    train's l2:0.0650616    valid's l2:0.0763153 
+## [96]:    train's l2:0.0649726    valid's l2:0.076439 
+## [97]:    train's l2:0.0649336    valid's l2:0.0763692 
+## [98]:    train's l2:0.0648688    valid's l2:0.0763461 
+## [99]:    train's l2:0.0647634    valid's l2:0.0763314 
+## [100]:   train's l2:0.0646546    valid's l2:0.0764209
+
# Try to find split_feature: 11
+# If you find it, it means it used a categorical feature in the first tree
+lgb.dump(model, num_iteration = 1)
+
## [1] "{\"name\":\"tree\",\n\"version\":\"v2\",\n\"num_class\":1,\n\"num_tree_per_iteration\":1,\n\"label_index\":0,\n\"max_feature_idx\":15,\n\"feature_names\":[\"age\",\"job\",\"marital\",\"education\",\"default\",\"balance\",\"housing\",\"loan\",\"contact\",\"day\",\"month\",\"duration\",\"campaign\",\"pdays\",\"previous\",\"poutcome\"],\n\"tree_info\":[{\"tree_index\":0,\"num_leaves\":4,\n\"num_cat\":0,\n\"shrinkage\":0.10000000000000001,\n\"tree_structure\":{\n\"split_index\":0,\n\"split_feature\":11,\n\"split_gain\":206.50007629394531,\n\"threshold\":645.00000000000011,\n\"decision_type\":\"<=\",\n\"default_left\":true,\n\"missing_type\":\"None\",\n\"internal_value\":0,\n\"internal_count\":4000,\n\"left_child\":{\n\"split_index\":1,\n\"split_feature\":11,\n\"split_gain\":63.834861755371094,\n\"threshold\":211.50000000000003,\n\"decision_type\":\"<=\",\n\"default_left\":true,\n\"missing_type\":\"None\",\n\"internal_value\":-1.6737127371273712,\n\"internal_count\":3690,\n\"left_child\":{\n\"leaf_index\":0,\n\"leaf_value\":-0.18818862935213754,\n\"leaf_count\":2269\n},\n\"right_child\":{\n\"leaf_index\":2,\n\"leaf_value\":-0.13413089373680506,\n\"leaf_count\":1421\n}\n},\n\"right_child\":{\n\"split_index\":2,\n\"split_feature\":8,\n\"split_gain\":7.1037116050720215,\n\"threshold\":1.5000000000000002,\n\"decision_type\":\"<=\",\n\"default_left\":true,\n\"missing_type\":\"None\",\n\"internal_value\":0.025806451612903226,\n\"internal_count\":310,\n\"left_child\":{\n\"leaf_index\":1,\n\"leaf_value\":0.024875621890547265,\n\"leaf_count\":201\n},\n\"right_child\":{\n\"leaf_index\":3,\n\"leaf_value\":-0.038532110091743121,\n\"leaf_count\":109\n}\n}\n}\n}]\n}\n"
+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/cross_validation.html b/R-package/docs/articles/cross_validation.html new file mode 100644 index 000000000000..14c35274583a --- /dev/null +++ b/R-package/docs/articles/cross_validation.html @@ -0,0 +1,217 @@ + + + + + + + +Cross Validation • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
require(lightgbm)
+
## Loading required package: lightgbm
+
## Loading required package: R6
+
# load in the agaricus dataset
+data(agaricus.train, package = "lightgbm")
+data(agaricus.test, package = "lightgbm")
+dtrain <- lgb.Dataset(agaricus.train$data, label = agaricus.train$label)
+dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label)
+
+nrounds <- 2
+param <- list(num_leaves = 4,
+              learning_rate = 1,
+              nthread = 1,
+              objective = "binary")
+
+print("Running cross validation")
+
## [1] "Running cross validation"
+
# Do cross validation, this will print result out as
+# [iteration]  metric_name:mean_value+std_value
+# std_value is standard deviation of the metric
+lgb.cv(param,
+       dtrain,
+       nrounds,
+       nfold = 5,
+       eval = "binary_error")
+
## Loading required package: Matrix
+
## [1]: valid's binary_error:0.0304007+0.00390108 
+## [2]: valid's binary_error:0.0222629+0.00431306
+
## <lgb.CVBooster>
+##   Public:
+##     best_iter: -1
+##     best_score: -1
+##     boosters: list
+##     initialize: function (x) 
+##     record_evals: list
+##     reset_parameter: function (new_params)
+
print("Running cross validation, disable standard deviation display")
+
## [1] "Running cross validation, disable standard deviation display"
+
# do cross validation, this will print result out as
+# [iteration]  metric_name:mean_value+std_value
+# std_value is standard deviation of the metric
+lgb.cv(param,
+       dtrain,
+       nrounds,
+       nfold = 5,
+       eval = "binary_error",
+       showsd = FALSE)
+
## [1]: valid's binary_error:0.0304012 
+## [2]: valid's binary_error:0.0222635
+
## <lgb.CVBooster>
+##   Public:
+##     best_iter: -1
+##     best_score: -1
+##     boosters: list
+##     initialize: function (x) 
+##     record_evals: list
+##     reset_parameter: function (new_params)
+
# You can also do cross validation with cutomized loss function
+print("Running cross validation, with cutomsized loss function")
+
## [1] "Running cross validation, with cutomsized loss function"
+
logregobj <- function(preds, dtrain) {
+  labels <- getinfo(dtrain, "label")
+  preds <- 1 / (1 + exp(-preds))
+  grad <- preds - labels
+  hess <- preds * (1 - preds)
+  return(list(grad = grad, hess = hess))
+}
+evalerror <- function(preds, dtrain) {
+  labels <- getinfo(dtrain, "label")
+  err <- as.numeric(sum(labels != (preds > 0))) / length(labels)
+  return(list(name = "error", value = err, higher_better = FALSE))
+}
+
+# train with customized objective
+lgb.cv(params = param,
+       data = dtrain,
+       nrounds = nrounds,
+       obj = logregobj,
+       eval = evalerror,
+       nfold = 5)
+
## [1]: valid's error:0.0304005+0.0036178 
+## [2]: valid's error:0.0222632+0.00431487
+
## <lgb.CVBooster>
+##   Public:
+##     best_iter: -1
+##     best_score: -1
+##     boosters: list
+##     initialize: function (x) 
+##     record_evals: list
+##     reset_parameter: function (new_params)
+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/dtrain.buffer b/R-package/docs/articles/dtrain.buffer new file mode 100644 index 0000000000000000000000000000000000000000..836fab9305c3043d5e2f73cab19751cd7a3f5acc GIT binary patch literal 105975 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 F{}&SwxNQIc literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/early_stopping.html b/R-package/docs/articles/early_stopping.html new file mode 100644 index 000000000000..8460b5c93181 --- /dev/null +++ b/R-package/docs/articles/early_stopping.html @@ -0,0 +1,187 @@ + + + + + + + +Early Stop in training • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
require(lightgbm)
+
## Loading required package: lightgbm
+
## Loading required package: R6
+
require(methods)
+
+# Load in the agaricus dataset
+data(agaricus.train, package = "lightgbm")
+data(agaricus.test, package = "lightgbm")
+
+dtrain <- lgb.Dataset(agaricus.train$data, label = agaricus.train$label)
+dtest <- lgb.Dataset(agaricus.test$data, label = agaricus.test$label)
+
+# Note: for customized objective function, we leave objective as default
+# Note: what we are getting is margin value in prediction
+# You must know what you are doing
+param <- list(num_leaves = 4,
+              learning_rate = 1,
+              nthread = 1)
+valids <- list(eval = dtest)
+num_round <- 20
+
+# User define objective function, given prediction, return gradient and second order gradient
+# This is loglikelihood loss
+logregobj <- function(preds, dtrain) {
+  labels <- getinfo(dtrain, "label")
+  preds <- 1 / (1 + exp(-preds))
+  grad <- preds - labels
+  hess <- preds * (1 - preds)
+  return(list(grad = grad, hess = hess))
+}
+
+# User defined evaluation function, return a pair metric_name, result, higher_better
+# NOTE: when you do customized loss function, the default prediction value is margin
+# This may make buildin evalution metric not function properly
+# For example, we are doing logistic loss, the prediction is score before logistic transformation
+# The buildin evaluation error assumes input is after logistic transformation
+# Take this in mind when you use the customization, and maybe you need write customized evaluation function
+evalerror <- function(preds, dtrain) {
+  labels <- getinfo(dtrain, "label")
+  err <- as.numeric(sum(labels != (preds > 0.5))) / length(labels)
+  return(list(name = "error", value = err, higher_better = FALSE))
+}
+print("Start training with early Stopping setting")
+
## [1] "Start training with early Stopping setting"
+
bst <- lgb.train(param,
+                 dtrain,
+                 num_round,
+                 valids,
+                 objective = logregobj,
+                 eval = evalerror,
+                 early_stopping_round = 3,
+                 nthread = 1)
+
## Loading required package: Matrix
+
## [1]: eval's error:0.0335196 
+## [2]: eval's error:0.0217256 
+## [3]: eval's error:0.00558659 
+## [4]: eval's error:0 
+## [5]: eval's error:0 
+## [6]: eval's error:0.00620732 
+## [7]: eval's error:0
+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/efficient_many_training.html b/R-package/docs/articles/efficient_many_training.html new file mode 100644 index 000000000000..c84b9d246d13 --- /dev/null +++ b/R-package/docs/articles/efficient_many_training.html @@ -0,0 +1,266 @@ + + + + + + + +Efficiency for Many Model Trainings • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
# Efficient training means training without giving up too much RAM
+# In the case of many trainings (like 100+ models), RAM will be eaten very quickly
+# Therefore, it is essential to know a strategy to deal with such issue
+
+# More results can be found here: https://github.com/Microsoft/LightGBM/issues/879#issuecomment-326656580
+# Quote: "@Laurae2 Thanks for nice easily reproducible example (unlike mine).
+# With reset=FALSE you get after 500 iterations (not 1000): OS reports 27GB usage, while R gc() reports 1.5GB.
+# Just doing reset=TRUE will already improve things: OS reports 4.6GB.
+# Doing reset=TRUE and calling gc() in the loop will have OS 1.3GB. Thanks for the latest tip."
+
+# 2018-01-21 example patch: use the "small" switch to make it bigger.
+
+small <- TRUE
+
+# Load library
+library(lightgbm)
+
## Loading required package: R6
+
# Generate fictive data of size 1M x 100
+set.seed(11111)
+x_data <- matrix(rnorm(n = ifelse(small, 1000000, 100000000), mean = 0, sd = 100), nrow = ifelse(small, 10000, 1000000), ncol = 100)
+y_data <- rnorm(n = ifelse(small, 10000, 1000000), mean = 0, sd = 5)
+
+# Create lgb.Dataset for training
+data <- lgb.Dataset(x_data, label = y_data)
+data$construct()
+
+# Loop through a training of 1000 models, please check your RAM on your task manager
+# It MUST remain constant (if not increasing very slightly)
+gbm <- list()
+
+for (i in 1:(ifelse(small, 100, 1000))) {
+  cat(format(Sys.time(), "%a %b %d %Y %X"), ": ", i, "\n", sep = "")
+  gbm[[i]] <- lgb.train(params = list(objective = "regression",
+                                      nthread = 1),
+                        data = data,
+                        1,
+                        reset_data = TRUE)
+  gc(verbose = FALSE)
+}
+
## Sun Jan 21 2018 03:49:55 PM: 1
+## Sun Jan 21 2018 03:49:55 PM: 2
+## Sun Jan 21 2018 03:49:55 PM: 3
+## Sun Jan 21 2018 03:49:55 PM: 4
+## Sun Jan 21 2018 03:49:55 PM: 5
+## Sun Jan 21 2018 03:49:55 PM: 6
+## Sun Jan 21 2018 03:49:55 PM: 7
+## Sun Jan 21 2018 03:49:55 PM: 8
+## Sun Jan 21 2018 03:49:55 PM: 9
+## Sun Jan 21 2018 03:49:55 PM: 10
+## Sun Jan 21 2018 03:49:55 PM: 11
+## Sun Jan 21 2018 03:49:56 PM: 12
+## Sun Jan 21 2018 03:49:56 PM: 13
+## Sun Jan 21 2018 03:49:56 PM: 14
+## Sun Jan 21 2018 03:49:56 PM: 15
+## Sun Jan 21 2018 03:49:56 PM: 16
+## Sun Jan 21 2018 03:49:56 PM: 17
+## Sun Jan 21 2018 03:49:56 PM: 18
+## Sun Jan 21 2018 03:49:56 PM: 19
+## Sun Jan 21 2018 03:49:56 PM: 20
+## Sun Jan 21 2018 03:49:56 PM: 21
+## Sun Jan 21 2018 03:49:56 PM: 22
+## Sun Jan 21 2018 03:49:56 PM: 23
+## Sun Jan 21 2018 03:49:56 PM: 24
+## Sun Jan 21 2018 03:49:56 PM: 25
+## Sun Jan 21 2018 03:49:56 PM: 26
+## Sun Jan 21 2018 03:49:56 PM: 27
+## Sun Jan 21 2018 03:49:56 PM: 28
+## Sun Jan 21 2018 03:49:56 PM: 29
+## Sun Jan 21 2018 03:49:56 PM: 30
+## Sun Jan 21 2018 03:49:57 PM: 31
+## Sun Jan 21 2018 03:49:57 PM: 32
+## Sun Jan 21 2018 03:49:57 PM: 33
+## Sun Jan 21 2018 03:49:57 PM: 34
+## Sun Jan 21 2018 03:49:57 PM: 35
+## Sun Jan 21 2018 03:49:57 PM: 36
+## Sun Jan 21 2018 03:49:57 PM: 37
+## Sun Jan 21 2018 03:49:57 PM: 38
+## Sun Jan 21 2018 03:49:57 PM: 39
+## Sun Jan 21 2018 03:49:57 PM: 40
+## Sun Jan 21 2018 03:49:57 PM: 41
+## Sun Jan 21 2018 03:49:57 PM: 42
+## Sun Jan 21 2018 03:49:57 PM: 43
+## Sun Jan 21 2018 03:49:57 PM: 44
+## Sun Jan 21 2018 03:49:57 PM: 45
+## Sun Jan 21 2018 03:49:57 PM: 46
+## Sun Jan 21 2018 03:49:57 PM: 47
+## Sun Jan 21 2018 03:49:57 PM: 48
+## Sun Jan 21 2018 03:49:57 PM: 49
+## Sun Jan 21 2018 03:49:57 PM: 50
+## Sun Jan 21 2018 03:49:58 PM: 51
+## Sun Jan 21 2018 03:49:58 PM: 52
+## Sun Jan 21 2018 03:49:58 PM: 53
+## Sun Jan 21 2018 03:49:58 PM: 54
+## Sun Jan 21 2018 03:49:58 PM: 55
+## Sun Jan 21 2018 03:49:58 PM: 56
+## Sun Jan 21 2018 03:49:58 PM: 57
+## Sun Jan 21 2018 03:49:58 PM: 58
+## Sun Jan 21 2018 03:49:58 PM: 59
+## Sun Jan 21 2018 03:49:58 PM: 60
+## Sun Jan 21 2018 03:49:58 PM: 61
+## Sun Jan 21 2018 03:49:58 PM: 62
+## Sun Jan 21 2018 03:49:58 PM: 63
+## Sun Jan 21 2018 03:49:58 PM: 64
+## Sun Jan 21 2018 03:49:58 PM: 65
+## Sun Jan 21 2018 03:49:58 PM: 66
+## Sun Jan 21 2018 03:49:58 PM: 67
+## Sun Jan 21 2018 03:49:58 PM: 68
+## Sun Jan 21 2018 03:49:59 PM: 69
+## Sun Jan 21 2018 03:49:59 PM: 70
+## Sun Jan 21 2018 03:49:59 PM: 71
+## Sun Jan 21 2018 03:49:59 PM: 72
+## Sun Jan 21 2018 03:49:59 PM: 73
+## Sun Jan 21 2018 03:49:59 PM: 74
+## Sun Jan 21 2018 03:49:59 PM: 75
+## Sun Jan 21 2018 03:49:59 PM: 76
+## Sun Jan 21 2018 03:49:59 PM: 77
+## Sun Jan 21 2018 03:49:59 PM: 78
+## Sun Jan 21 2018 03:49:59 PM: 79
+## Sun Jan 21 2018 03:49:59 PM: 80
+## Sun Jan 21 2018 03:49:59 PM: 81
+## Sun Jan 21 2018 03:49:59 PM: 82
+## Sun Jan 21 2018 03:49:59 PM: 83
+## Sun Jan 21 2018 03:49:59 PM: 84
+## Sun Jan 21 2018 03:49:59 PM: 85
+## Sun Jan 21 2018 03:49:59 PM: 86
+## Sun Jan 21 2018 03:49:59 PM: 87
+## Sun Jan 21 2018 03:50:00 PM: 88
+## Sun Jan 21 2018 03:50:00 PM: 89
+## Sun Jan 21 2018 03:50:00 PM: 90
+## Sun Jan 21 2018 03:50:00 PM: 91
+## Sun Jan 21 2018 03:50:00 PM: 92
+## Sun Jan 21 2018 03:50:00 PM: 93
+## Sun Jan 21 2018 03:50:00 PM: 94
+## Sun Jan 21 2018 03:50:00 PM: 95
+## Sun Jan 21 2018 03:50:00 PM: 96
+## Sun Jan 21 2018 03:50:00 PM: 97
+## Sun Jan 21 2018 03:50:00 PM: 98
+## Sun Jan 21 2018 03:50:00 PM: 99
+## Sun Jan 21 2018 03:50:00 PM: 100
+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/index.html b/R-package/docs/articles/index.html new file mode 100644 index 000000000000..7eb7f6617f9d --- /dev/null +++ b/R-package/docs/articles/index.html @@ -0,0 +1,158 @@ + + + + + + + + +Articles • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/R-package/docs/articles/leaf_stability.html b/R-package/docs/articles/leaf_stability.html new file mode 100644 index 000000000000..fb819cc1a1e3 --- /dev/null +++ b/R-package/docs/articles/leaf_stability.html @@ -0,0 +1,1415 @@ + + + + + + + +Leaf (in)Stability example • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
# We are going to look at how iterating too much might generate observation instability.
+# Obviously, we are in a controlled environment, without issues (real rules).
+# Do not do this in a real scenario.
+
+# First, we load our libraries
+library(lightgbm)
+
## Loading required package: R6
+
library(ggplot2)
+
+# Second, we load our data
+data(agaricus.train, package = "lightgbm")
+train <- agaricus.train
+dtrain <- lgb.Dataset(train$data, label = train$label)
+data(agaricus.test, package = "lightgbm")
+test <- agaricus.test
+dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label)
+
+# Third, we setup parameters and we train a model
+params <- list(objective = "regression", metric = "l2")
+valids <- list(test = dtest)
+model <- lgb.train(params,
+                   dtrain,
+                   50,
+                   valids,
+                   min_data = 1,
+                   learning_rate = 0.1,
+                   bagging_fraction = 0.1,
+                   bagging_freq = 1,
+                   bagging_seed = 1,
+                   nthread = 1)
+
## Loading required package: Matrix
+
## [1]: test's l2:0.202293 
+## [2]: test's l2:0.164342 
+## [3]: test's l2:0.133283 
+## [4]: test's l2:0.1084 
+## [5]: test's l2:0.0877367 
+## [6]: test's l2:0.0710476 
+## [7]: test's l2:0.0575632 
+## [8]: test's l2:0.0466222 
+## [9]: test's l2:0.0379134 
+## [10]:    test's l2:0.0307555 
+## [11]:    test's l2:0.0248963 
+## [12]:    test's l2:0.0201392 
+## [13]:    test's l2:0.0163162 
+## [14]:    test's l2:0.0132696 
+## [15]:    test's l2:0.0107514 
+## [16]:    test's l2:0.00882604 
+## [17]:    test's l2:0.00724468 
+## [18]:    test's l2:0.00589563 
+## [19]:    test's l2:0.00478529 
+## [20]:    test's l2:0.00389577 
+## [21]:    test's l2:0.00317115 
+## [22]:    test's l2:0.00264432 
+## [23]:    test's l2:0.0021541 
+## [24]:    test's l2:0.00179906 
+## [25]:    test's l2:0.00150985 
+## [26]:    test's l2:0.00129508 
+## [27]:    test's l2:0.00108426 
+## [28]:    test's l2:0.000956892 
+## [29]:    test's l2:0.000856905 
+## [30]:    test's l2:0.000729517 
+## [31]:    test's l2:0.000613605 
+## [32]:    test's l2:0.000523628 
+## [33]:    test's l2:0.000449206 
+## [34]:    test's l2:0.000378496 
+## [35]:    test's l2:0.000312651 
+## [36]:    test's l2:0.000259974 
+## [37]:    test's l2:0.000222764 
+## [38]:    test's l2:0.000207567 
+## [39]:    test's l2:0.000201502 
+## [40]:    test's l2:0.000170301 
+## [41]:    test's l2:0.000155593 
+## [42]:    test's l2:0.000134624 
+## [43]:    test's l2:0.000120277 
+## [44]:    test's l2:0.000111736 
+## [45]:    test's l2:9.5131e-05 
+## [46]:    test's l2:9.03253e-05 
+## [47]:    test's l2:8.87863e-05 
+## [48]:    test's l2:8.38359e-05 
+## [49]:    test's l2:8.21905e-05 
+## [50]:    test's l2:7.20829e-05
+
# We create a data.frame with the following structure:
+# X = average leaf of the observation throughout all trees
+# Y = prediction probability (clamped to [1e-15, 1-1e-15])
+# Z = logloss
+# binned = binned quantile of average leaf
+new_data <- data.frame(X = rowMeans(predict(model,
+                                            agaricus.test$data,
+                                            predleaf = TRUE)),
+                       Y = pmin(pmax(predict(model,
+                                             agaricus.test$data), 1e-15), 1 - 1e-15))
+new_data$Z <- -(agaricus.test$label * log(new_data$Y) + (1 - agaricus.test$label) * log(1 - new_data$Y))
+new_data$binned <- .bincode(x = new_data$X,
+                            breaks = quantile(x = new_data$X,
+                                              probs = (1:9)/10),
+                            right = TRUE,
+                            include.lowest = TRUE)
+new_data$binned[is.na(new_data$binned)] <- 0
+new_data$binned <- as.factor(new_data$binned)
+
+# We can check the binned content
+table(new_data$binned)
+
## 
+##   0   1   2   3   4   5   6   7   8 
+## 292 188 164 147 159 166 180 138 177
+
# We can plot the binned content
+# On the second plot, we clearly notice the lower the bin (the lower the leaf value), the higher the loss
+# On the third plot, it is smooth!
+ggplot(data = new_data, mapping = aes(x = X, y = Y, color = binned)) + geom_point() + theme_bw() + labs(title = "Prediction Depth", x = "Leaf Bin", y = "Prediction Probability")
+

+
ggplot(data = new_data, mapping = aes(x = binned, y = Z, fill = binned, group = binned)) + geom_boxplot() + theme_bw() + labs(title = "Prediction Depth Spread", x = "Leaf Bin", y = "Logloss")
+

+
ggplot(data = new_data, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density")
+

+
# Now, let's show with other parameters
+model2 <- lgb.train(params,
+                    dtrain,
+                    100,
+                    valids,
+                    min_data = 1,
+                    learning_rate = 1,
+                    nthread = 1)
+
## [1]: test's l2:6.44165e-17 
+## [2]: test's l2:1.97215e-31 
+## [3]: test's l2:0 
+## [4]: test's l2:0 
+## [5]: test's l2:0 
+## [6]: test's l2:0 
+## [7]: test's l2:0 
+## [8]: test's l2:0 
+## [9]: test's l2:0 
+## [10]:    test's l2:0 
+## [11]:    test's l2:0 
+## [12]:    test's l2:0 
+## [13]:    test's l2:0 
+## [14]:    test's l2:0 
+## [15]:    test's l2:0 
+## [16]:    test's l2:0 
+## [17]:    test's l2:0 
+## [18]:    test's l2:0 
+## [19]:    test's l2:0 
+## [20]:    test's l2:0 
+## [21]:    test's l2:0 
+## [22]:    test's l2:0 
+## [23]:    test's l2:0 
+## [24]:    test's l2:0 
+## [25]:    test's l2:0 
+## [26]:    test's l2:0 
+## [27]:    test's l2:0 
+## [28]:    test's l2:0 
+## [29]:    test's l2:0 
+## [30]:    test's l2:0 
+## [31]:    test's l2:0 
+## [32]:    test's l2:0 
+## [33]:    test's l2:0 
+## [34]:    test's l2:0 
+## [35]:    test's l2:0 
+## [36]:    test's l2:0 
+## [37]:    test's l2:0 
+## [38]:    test's l2:0 
+## [39]:    test's l2:0 
+## [40]:    test's l2:0 
+## [41]:    test's l2:0 
+## [42]:    test's l2:0 
+## [43]:    test's l2:0 
+## [44]:    test's l2:0 
+## [45]:    test's l2:0 
+## [46]:    test's l2:0 
+## [47]:    test's l2:0 
+## [48]:    test's l2:0 
+## [49]:    test's l2:0 
+## [50]:    test's l2:0 
+## [51]:    test's l2:0 
+## [52]:    test's l2:0 
+## [53]:    test's l2:0 
+## [54]:    test's l2:0 
+## [55]:    test's l2:0 
+## [56]:    test's l2:0 
+## [57]:    test's l2:0 
+## [58]:    test's l2:0 
+## [59]:    test's l2:0 
+## [60]:    test's l2:0 
+## [61]:    test's l2:0 
+## [62]:    test's l2:0 
+## [63]:    test's l2:0 
+## [64]:    test's l2:0 
+## [65]:    test's l2:0 
+## [66]:    test's l2:0 
+## [67]:    test's l2:0 
+## [68]:    test's l2:0 
+## [69]:    test's l2:0 
+## [70]:    test's l2:0 
+## [71]:    test's l2:0 
+## [72]:    test's l2:0 
+## [73]:    test's l2:0 
+## [74]:    test's l2:0 
+## [75]:    test's l2:0 
+## [76]:    test's l2:0 
+## [77]:    test's l2:0 
+## [78]:    test's l2:0 
+## [79]:    test's l2:0 
+## [80]:    test's l2:0 
+## [81]:    test's l2:0 
+## [82]:    test's l2:0 
+## [83]:    test's l2:0 
+## [84]:    test's l2:0 
+## [85]:    test's l2:0 
+## [86]:    test's l2:0 
+## [87]:    test's l2:0 
+## [88]:    test's l2:0 
+## [89]:    test's l2:0 
+## [90]:    test's l2:0 
+## [91]:    test's l2:0 
+## [92]:    test's l2:0 
+## [93]:    test's l2:0 
+## [94]:    test's l2:0 
+## [95]:    test's l2:0 
+## [96]:    test's l2:0 
+## [97]:    test's l2:0 
+## [98]:    test's l2:0 
+## [99]:    test's l2:0 
+## [100]:   test's l2:0
+
# We create the data structure, but for model2
+new_data2 <- data.frame(X = rowMeans(predict(model2,
+                                             agaricus.test$data,
+                                             predleaf = TRUE)),
+                        Y = pmin(pmax(predict(model2,
+                                              agaricus.test$data), 1e-15), 1 - 1e-15))
+new_data2$Z <- -(agaricus.test$label * log(new_data2$Y) + (1 - agaricus.test$label) * log(1 - new_data2$Y))
+new_data2$binned <- .bincode(x = new_data2$X,
+                             breaks = quantile(x = new_data2$X,
+                                               probs = (1:9)/10),
+                             right = TRUE,
+                             include.lowest = TRUE)
+new_data2$binned[is.na(new_data2$binned)] <- 0
+new_data2$binned <- as.factor(new_data2$binned)
+
+# We can check the binned content
+table(new_data2$binned)
+
## 
+##   0   1   2   4   5   6   8 
+##  25 440 337  31 159 339 280
+
# We can plot the binned content
+# On the second plot, we clearly notice the lower the bin (the lower the leaf value), the higher the loss
+# On the third plot, it is clearly not smooth! We are severely overfitting the data, but the rules are real thus it is not an issue
+# However, if the rules were not true, the loss would explode.
+ggplot(data = new_data2, mapping = aes(x = X, y = Y, color = binned)) + geom_point() + theme_bw() + labs(title = "Prediction Depth", x = "Leaf Bin", y = "Prediction Probability")
+

+
ggplot(data = new_data2, mapping = aes(x = binned, y = Z, fill = binned, group = binned)) + geom_boxplot() + theme_bw() + labs(title = "Prediction Depth Spread", x = "Leaf Bin", y = "Logloss")
+

+
ggplot(data = new_data2, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density")
+

+
# Now, try with very severe overfitting
+model3 <- lgb.train(params,
+                    dtrain,
+                    1000,
+                    valids,
+                    min_data = 1,
+                    learning_rate = 1,
+                    nthread = 1)
+
## [1]: test's l2:6.44165e-17 
+## [2]: test's l2:1.97215e-31 
+## [3]: test's l2:0 
+## [4]: test's l2:0 
+## [5]: test's l2:0 
+## [6]: test's l2:0 
+## [7]: test's l2:0 
+## [8]: test's l2:0 
+## [9]: test's l2:0 
+## [10]:    test's l2:0 
+## [11]:    test's l2:0 
+## [12]:    test's l2:0 
+## [13]:    test's l2:0 
+## [14]:    test's l2:0 
+## [15]:    test's l2:0 
+## [16]:    test's l2:0 
+## [17]:    test's l2:0 
+## [18]:    test's l2:0 
+## [19]:    test's l2:0 
+## [20]:    test's l2:0 
+## [21]:    test's l2:0 
+## [22]:    test's l2:0 
+## [23]:    test's l2:0 
+## [24]:    test's l2:0 
+## [25]:    test's l2:0 
+## [26]:    test's l2:0 
+## [27]:    test's l2:0 
+## [28]:    test's l2:0 
+## [29]:    test's l2:0 
+## [30]:    test's l2:0 
+## [31]:    test's l2:0 
+## [32]:    test's l2:0 
+## [33]:    test's l2:0 
+## [34]:    test's l2:0 
+## [35]:    test's l2:0 
+## [36]:    test's l2:0 
+## [37]:    test's l2:0 
+## [38]:    test's l2:0 
+## [39]:    test's l2:0 
+## [40]:    test's l2:0 
+## [41]:    test's l2:0 
+## [42]:    test's l2:0 
+## [43]:    test's l2:0 
+## [44]:    test's l2:0 
+## [45]:    test's l2:0 
+## [46]:    test's l2:0 
+## [47]:    test's l2:0 
+## [48]:    test's l2:0 
+## [49]:    test's l2:0 
+## [50]:    test's l2:0 
+## [51]:    test's l2:0 
+## [52]:    test's l2:0 
+## [53]:    test's l2:0 
+## [54]:    test's l2:0 
+## [55]:    test's l2:0 
+## [56]:    test's l2:0 
+## [57]:    test's l2:0 
+## [58]:    test's l2:0 
+## [59]:    test's l2:0 
+## [60]:    test's l2:0 
+## [61]:    test's l2:0 
+## [62]:    test's l2:0 
+## [63]:    test's l2:0 
+## [64]:    test's l2:0 
+## [65]:    test's l2:0 
+## [66]:    test's l2:0 
+## [67]:    test's l2:0 
+## [68]:    test's l2:0 
+## [69]:    test's l2:0 
+## [70]:    test's l2:0 
+## [71]:    test's l2:0 
+## [72]:    test's l2:0 
+## [73]:    test's l2:0 
+## [74]:    test's l2:0 
+## [75]:    test's l2:0 
+## [76]:    test's l2:0 
+## [77]:    test's l2:0 
+## [78]:    test's l2:0 
+## [79]:    test's l2:0 
+## [80]:    test's l2:0 
+## [81]:    test's l2:0 
+## [82]:    test's l2:0 
+## [83]:    test's l2:0 
+## [84]:    test's l2:0 
+## [85]:    test's l2:0 
+## [86]:    test's l2:0 
+## [87]:    test's l2:0 
+## [88]:    test's l2:0 
+## [89]:    test's l2:0 
+## [90]:    test's l2:0 
+## [91]:    test's l2:0 
+## [92]:    test's l2:0 
+## [93]:    test's l2:0 
+## [94]:    test's l2:0 
+## [95]:    test's l2:0 
+## [96]:    test's l2:0 
+## [97]:    test's l2:0 
+## [98]:    test's l2:0 
+## [99]:    test's l2:0 
+## [100]:   test's l2:0 
+## [101]:   test's l2:0 
+## [102]:   test's l2:0 
+## [103]:   test's l2:0 
+## [104]:   test's l2:0 
+## [105]:   test's l2:0 
+## [106]:   test's l2:0 
+## [107]:   test's l2:0 
+## [108]:   test's l2:0 
+## [109]:   test's l2:0 
+## [110]:   test's l2:0 
+## [111]:   test's l2:0 
+## [112]:   test's l2:0 
+## [113]:   test's l2:0 
+## [114]:   test's l2:0 
+## [115]:   test's l2:0 
+## [116]:   test's l2:0 
+## [117]:   test's l2:0 
+## [118]:   test's l2:0 
+## [119]:   test's l2:0 
+## [120]:   test's l2:0 
+## [121]:   test's l2:0 
+## [122]:   test's l2:0 
+## [123]:   test's l2:0 
+## [124]:   test's l2:0 
+## [125]:   test's l2:0 
+## [126]:   test's l2:0 
+## [127]:   test's l2:0 
+## [128]:   test's l2:0 
+## [129]:   test's l2:0 
+## [130]:   test's l2:0 
+## [131]:   test's l2:0 
+## [132]:   test's l2:0 
+## [133]:   test's l2:0 
+## [134]:   test's l2:0 
+## [135]:   test's l2:0 
+## [136]:   test's l2:0 
+## [137]:   test's l2:0 
+## [138]:   test's l2:0 
+## [139]:   test's l2:0 
+## [140]:   test's l2:0 
+## [141]:   test's l2:0 
+## [142]:   test's l2:0 
+## [143]:   test's l2:0 
+## [144]:   test's l2:0 
+## [145]:   test's l2:0 
+## [146]:   test's l2:0 
+## [147]:   test's l2:0 
+## [148]:   test's l2:0 
+## [149]:   test's l2:0 
+## [150]:   test's l2:0 
+## [151]:   test's l2:0 
+## [152]:   test's l2:0 
+## [153]:   test's l2:0 
+## [154]:   test's l2:0 
+## [155]:   test's l2:0 
+## [156]:   test's l2:0 
+## [157]:   test's l2:0 
+## [158]:   test's l2:0 
+## [159]:   test's l2:0 
+## [160]:   test's l2:0 
+## [161]:   test's l2:0 
+## [162]:   test's l2:0 
+## [163]:   test's l2:0 
+## [164]:   test's l2:0 
+## [165]:   test's l2:0 
+## [166]:   test's l2:0 
+## [167]:   test's l2:0 
+## [168]:   test's l2:0 
+## [169]:   test's l2:0 
+## [170]:   test's l2:0 
+## [171]:   test's l2:0 
+## [172]:   test's l2:0 
+## [173]:   test's l2:0 
+## [174]:   test's l2:0 
+## [175]:   test's l2:0 
+## [176]:   test's l2:0 
+## [177]:   test's l2:0 
+## [178]:   test's l2:0 
+## [179]:   test's l2:0 
+## [180]:   test's l2:0 
+## [181]:   test's l2:0 
+## [182]:   test's l2:0 
+## [183]:   test's l2:0 
+## [184]:   test's l2:0 
+## [185]:   test's l2:0 
+## [186]:   test's l2:0 
+## [187]:   test's l2:0 
+## [188]:   test's l2:0 
+## [189]:   test's l2:0 
+## [190]:   test's l2:0 
+## [191]:   test's l2:0 
+## [192]:   test's l2:0 
+## [193]:   test's l2:0 
+## [194]:   test's l2:0 
+## [195]:   test's l2:0 
+## [196]:   test's l2:0 
+## [197]:   test's l2:0 
+## [198]:   test's l2:0 
+## [199]:   test's l2:0 
+## [200]:   test's l2:0 
+## [201]:   test's l2:0 
+## [202]:   test's l2:0 
+## [203]:   test's l2:0 
+## [204]:   test's l2:0 
+## [205]:   test's l2:0 
+## [206]:   test's l2:0 
+## [207]:   test's l2:0 
+## [208]:   test's l2:0 
+## [209]:   test's l2:0 
+## [210]:   test's l2:0 
+## [211]:   test's l2:0 
+## [212]:   test's l2:0 
+## [213]:   test's l2:0 
+## [214]:   test's l2:0 
+## [215]:   test's l2:0 
+## [216]:   test's l2:0 
+## [217]:   test's l2:0 
+## [218]:   test's l2:0 
+## [219]:   test's l2:0 
+## [220]:   test's l2:0 
+## [221]:   test's l2:0 
+## [222]:   test's l2:0 
+## [223]:   test's l2:0 
+## [224]:   test's l2:0 
+## [225]:   test's l2:0 
+## [226]:   test's l2:0 
+## [227]:   test's l2:0 
+## [228]:   test's l2:0 
+## [229]:   test's l2:0 
+## [230]:   test's l2:0 
+## [231]:   test's l2:0 
+## [232]:   test's l2:0 
+## [233]:   test's l2:0 
+## [234]:   test's l2:0 
+## [235]:   test's l2:0 
+## [236]:   test's l2:0 
+## [237]:   test's l2:0 
+## [238]:   test's l2:0 
+## [239]:   test's l2:0 
+## [240]:   test's l2:0 
+## [241]:   test's l2:0 
+## [242]:   test's l2:0 
+## [243]:   test's l2:0 
+## [244]:   test's l2:0 
+## [245]:   test's l2:0 
+## [246]:   test's l2:0 
+## [247]:   test's l2:0 
+## [248]:   test's l2:0 
+## [249]:   test's l2:0 
+## [250]:   test's l2:0 
+## [251]:   test's l2:0 
+## [252]:   test's l2:0 
+## [253]:   test's l2:0 
+## [254]:   test's l2:0 
+## [255]:   test's l2:0 
+## [256]:   test's l2:0 
+## [257]:   test's l2:0 
+## [258]:   test's l2:0 
+## [259]:   test's l2:0 
+## [260]:   test's l2:0 
+## [261]:   test's l2:0 
+## [262]:   test's l2:0 
+## [263]:   test's l2:0 
+## [264]:   test's l2:0 
+## [265]:   test's l2:0 
+## [266]:   test's l2:0 
+## [267]:   test's l2:0 
+## [268]:   test's l2:0 
+## [269]:   test's l2:0 
+## [270]:   test's l2:0 
+## [271]:   test's l2:0 
+## [272]:   test's l2:0 
+## [273]:   test's l2:0 
+## [274]:   test's l2:0 
+## [275]:   test's l2:0 
+## [276]:   test's l2:0 
+## [277]:   test's l2:0 
+## [278]:   test's l2:0 
+## [279]:   test's l2:0 
+## [280]:   test's l2:0 
+## [281]:   test's l2:0 
+## [282]:   test's l2:0 
+## [283]:   test's l2:0 
+## [284]:   test's l2:0 
+## [285]:   test's l2:0 
+## [286]:   test's l2:0 
+## [287]:   test's l2:0 
+## [288]:   test's l2:0 
+## [289]:   test's l2:0 
+## [290]:   test's l2:0 
+## [291]:   test's l2:0 
+## [292]:   test's l2:0 
+## [293]:   test's l2:0 
+## [294]:   test's l2:0 
+## [295]:   test's l2:0 
+## [296]:   test's l2:0 
+## [297]:   test's l2:0 
+## [298]:   test's l2:0 
+## [299]:   test's l2:0 
+## [300]:   test's l2:0 
+## [301]:   test's l2:0 
+## [302]:   test's l2:0 
+## [303]:   test's l2:0 
+## [304]:   test's l2:0 
+## [305]:   test's l2:0 
+## [306]:   test's l2:0 
+## [307]:   test's l2:0 
+## [308]:   test's l2:0 
+## [309]:   test's l2:0 
+## [310]:   test's l2:0 
+## [311]:   test's l2:0 
+## [312]:   test's l2:0 
+## [313]:   test's l2:0 
+## [314]:   test's l2:0 
+## [315]:   test's l2:0 
+## [316]:   test's l2:0 
+## [317]:   test's l2:0 
+## [318]:   test's l2:0 
+## [319]:   test's l2:0 
+## [320]:   test's l2:0 
+## [321]:   test's l2:0 
+## [322]:   test's l2:0 
+## [323]:   test's l2:0 
+## [324]:   test's l2:0 
+## [325]:   test's l2:0 
+## [326]:   test's l2:0 
+## [327]:   test's l2:0 
+## [328]:   test's l2:0 
+## [329]:   test's l2:0 
+## [330]:   test's l2:0 
+## [331]:   test's l2:0 
+## [332]:   test's l2:0 
+## [333]:   test's l2:0 
+## [334]:   test's l2:0 
+## [335]:   test's l2:0 
+## [336]:   test's l2:0 
+## [337]:   test's l2:0 
+## [338]:   test's l2:0 
+## [339]:   test's l2:0 
+## [340]:   test's l2:0 
+## [341]:   test's l2:0 
+## [342]:   test's l2:0 
+## [343]:   test's l2:0 
+## [344]:   test's l2:0 
+## [345]:   test's l2:0 
+## [346]:   test's l2:0 
+## [347]:   test's l2:0 
+## [348]:   test's l2:0 
+## [349]:   test's l2:0 
+## [350]:   test's l2:0 
+## [351]:   test's l2:0 
+## [352]:   test's l2:0 
+## [353]:   test's l2:0 
+## [354]:   test's l2:0 
+## [355]:   test's l2:0 
+## [356]:   test's l2:0 
+## [357]:   test's l2:0 
+## [358]:   test's l2:0 
+## [359]:   test's l2:0 
+## [360]:   test's l2:0 
+## [361]:   test's l2:0 
+## [362]:   test's l2:0 
+## [363]:   test's l2:0 
+## [364]:   test's l2:0 
+## [365]:   test's l2:0 
+## [366]:   test's l2:0 
+## [367]:   test's l2:0 
+## [368]:   test's l2:0 
+## [369]:   test's l2:0 
+## [370]:   test's l2:0 
+## [371]:   test's l2:0 
+## [372]:   test's l2:0 
+## [373]:   test's l2:0 
+## [374]:   test's l2:0 
+## [375]:   test's l2:0 
+## [376]:   test's l2:0 
+## [377]:   test's l2:0 
+## [378]:   test's l2:0 
+## [379]:   test's l2:0 
+## [380]:   test's l2:0 
+## [381]:   test's l2:0 
+## [382]:   test's l2:0 
+## [383]:   test's l2:0 
+## [384]:   test's l2:0 
+## [385]:   test's l2:0 
+## [386]:   test's l2:0 
+## [387]:   test's l2:0 
+## [388]:   test's l2:0 
+## [389]:   test's l2:0 
+## [390]:   test's l2:0 
+## [391]:   test's l2:0 
+## [392]:   test's l2:0 
+## [393]:   test's l2:0 
+## [394]:   test's l2:0 
+## [395]:   test's l2:0 
+## [396]:   test's l2:0 
+## [397]:   test's l2:0 
+## [398]:   test's l2:0 
+## [399]:   test's l2:0 
+## [400]:   test's l2:0 
+## [401]:   test's l2:0 
+## [402]:   test's l2:0 
+## [403]:   test's l2:0 
+## [404]:   test's l2:0 
+## [405]:   test's l2:0 
+## [406]:   test's l2:0 
+## [407]:   test's l2:0 
+## [408]:   test's l2:0 
+## [409]:   test's l2:0 
+## [410]:   test's l2:0 
+## [411]:   test's l2:0 
+## [412]:   test's l2:0 
+## [413]:   test's l2:0 
+## [414]:   test's l2:0 
+## [415]:   test's l2:0 
+## [416]:   test's l2:0 
+## [417]:   test's l2:0 
+## [418]:   test's l2:0 
+## [419]:   test's l2:0 
+## [420]:   test's l2:0 
+## [421]:   test's l2:0 
+## [422]:   test's l2:0 
+## [423]:   test's l2:0 
+## [424]:   test's l2:0 
+## [425]:   test's l2:0 
+## [426]:   test's l2:0 
+## [427]:   test's l2:0 
+## [428]:   test's l2:0 
+## [429]:   test's l2:0 
+## [430]:   test's l2:0 
+## [431]:   test's l2:0 
+## [432]:   test's l2:0 
+## [433]:   test's l2:0 
+## [434]:   test's l2:0 
+## [435]:   test's l2:0 
+## [436]:   test's l2:0 
+## [437]:   test's l2:0 
+## [438]:   test's l2:0 
+## [439]:   test's l2:0 
+## [440]:   test's l2:0 
+## [441]:   test's l2:0 
+## [442]:   test's l2:0 
+## [443]:   test's l2:0 
+## [444]:   test's l2:0 
+## [445]:   test's l2:0 
+## [446]:   test's l2:0 
+## [447]:   test's l2:0 
+## [448]:   test's l2:0 
+## [449]:   test's l2:0 
+## [450]:   test's l2:0 
+## [451]:   test's l2:0 
+## [452]:   test's l2:0 
+## [453]:   test's l2:0 
+## [454]:   test's l2:0 
+## [455]:   test's l2:0 
+## [456]:   test's l2:0 
+## [457]:   test's l2:0 
+## [458]:   test's l2:0 
+## [459]:   test's l2:0 
+## [460]:   test's l2:0 
+## [461]:   test's l2:0 
+## [462]:   test's l2:0 
+## [463]:   test's l2:0 
+## [464]:   test's l2:0 
+## [465]:   test's l2:0 
+## [466]:   test's l2:0 
+## [467]:   test's l2:0 
+## [468]:   test's l2:0 
+## [469]:   test's l2:0 
+## [470]:   test's l2:0 
+## [471]:   test's l2:0 
+## [472]:   test's l2:0 
+## [473]:   test's l2:0 
+## [474]:   test's l2:0 
+## [475]:   test's l2:0 
+## [476]:   test's l2:0 
+## [477]:   test's l2:0 
+## [478]:   test's l2:0 
+## [479]:   test's l2:0 
+## [480]:   test's l2:0 
+## [481]:   test's l2:0 
+## [482]:   test's l2:0 
+## [483]:   test's l2:0 
+## [484]:   test's l2:0 
+## [485]:   test's l2:0 
+## [486]:   test's l2:0 
+## [487]:   test's l2:0 
+## [488]:   test's l2:0 
+## [489]:   test's l2:0 
+## [490]:   test's l2:0 
+## [491]:   test's l2:0 
+## [492]:   test's l2:0 
+## [493]:   test's l2:0 
+## [494]:   test's l2:0 
+## [495]:   test's l2:0 
+## [496]:   test's l2:0 
+## [497]:   test's l2:0 
+## [498]:   test's l2:0 
+## [499]:   test's l2:0 
+## [500]:   test's l2:0 
+## [501]:   test's l2:0 
+## [502]:   test's l2:0 
+## [503]:   test's l2:0 
+## [504]:   test's l2:0 
+## [505]:   test's l2:0 
+## [506]:   test's l2:0 
+## [507]:   test's l2:0 
+## [508]:   test's l2:0 
+## [509]:   test's l2:0 
+## [510]:   test's l2:0 
+## [511]:   test's l2:0 
+## [512]:   test's l2:0 
+## [513]:   test's l2:0 
+## [514]:   test's l2:0 
+## [515]:   test's l2:0 
+## [516]:   test's l2:0 
+## [517]:   test's l2:0 
+## [518]:   test's l2:0 
+## [519]:   test's l2:0 
+## [520]:   test's l2:0 
+## [521]:   test's l2:0 
+## [522]:   test's l2:0 
+## [523]:   test's l2:0 
+## [524]:   test's l2:0 
+## [525]:   test's l2:0 
+## [526]:   test's l2:0 
+## [527]:   test's l2:0 
+## [528]:   test's l2:0 
+## [529]:   test's l2:0 
+## [530]:   test's l2:0 
+## [531]:   test's l2:0 
+## [532]:   test's l2:0 
+## [533]:   test's l2:0 
+## [534]:   test's l2:0 
+## [535]:   test's l2:0 
+## [536]:   test's l2:0 
+## [537]:   test's l2:0 
+## [538]:   test's l2:0 
+## [539]:   test's l2:0 
+## [540]:   test's l2:0 
+## [541]:   test's l2:0 
+## [542]:   test's l2:0 
+## [543]:   test's l2:0 
+## [544]:   test's l2:0 
+## [545]:   test's l2:0 
+## [546]:   test's l2:0 
+## [547]:   test's l2:0 
+## [548]:   test's l2:0 
+## [549]:   test's l2:0 
+## [550]:   test's l2:0 
+## [551]:   test's l2:0 
+## [552]:   test's l2:0 
+## [553]:   test's l2:0 
+## [554]:   test's l2:0 
+## [555]:   test's l2:0 
+## [556]:   test's l2:0 
+## [557]:   test's l2:0 
+## [558]:   test's l2:0 
+## [559]:   test's l2:0 
+## [560]:   test's l2:0 
+## [561]:   test's l2:0 
+## [562]:   test's l2:0 
+## [563]:   test's l2:0 
+## [564]:   test's l2:0 
+## [565]:   test's l2:0 
+## [566]:   test's l2:0 
+## [567]:   test's l2:0 
+## [568]:   test's l2:0 
+## [569]:   test's l2:0 
+## [570]:   test's l2:0 
+## [571]:   test's l2:0 
+## [572]:   test's l2:0 
+## [573]:   test's l2:0 
+## [574]:   test's l2:0 
+## [575]:   test's l2:0 
+## [576]:   test's l2:0 
+## [577]:   test's l2:0 
+## [578]:   test's l2:0 
+## [579]:   test's l2:0 
+## [580]:   test's l2:0 
+## [581]:   test's l2:0 
+## [582]:   test's l2:0 
+## [583]:   test's l2:0 
+## [584]:   test's l2:0 
+## [585]:   test's l2:0 
+## [586]:   test's l2:0 
+## [587]:   test's l2:0 
+## [588]:   test's l2:0 
+## [589]:   test's l2:0 
+## [590]:   test's l2:0 
+## [591]:   test's l2:0 
+## [592]:   test's l2:0 
+## [593]:   test's l2:0 
+## [594]:   test's l2:0 
+## [595]:   test's l2:0 
+## [596]:   test's l2:0 
+## [597]:   test's l2:0 
+## [598]:   test's l2:0 
+## [599]:   test's l2:0 
+## [600]:   test's l2:0 
+## [601]:   test's l2:0 
+## [602]:   test's l2:0 
+## [603]:   test's l2:0 
+## [604]:   test's l2:0 
+## [605]:   test's l2:0 
+## [606]:   test's l2:0 
+## [607]:   test's l2:0 
+## [608]:   test's l2:0 
+## [609]:   test's l2:0 
+## [610]:   test's l2:0 
+## [611]:   test's l2:0 
+## [612]:   test's l2:0 
+## [613]:   test's l2:0 
+## [614]:   test's l2:0 
+## [615]:   test's l2:0 
+## [616]:   test's l2:0 
+## [617]:   test's l2:0 
+## [618]:   test's l2:0 
+## [619]:   test's l2:0 
+## [620]:   test's l2:0 
+## [621]:   test's l2:0 
+## [622]:   test's l2:0 
+## [623]:   test's l2:0 
+## [624]:   test's l2:0 
+## [625]:   test's l2:0 
+## [626]:   test's l2:0 
+## [627]:   test's l2:0 
+## [628]:   test's l2:0 
+## [629]:   test's l2:0 
+## [630]:   test's l2:0 
+## [631]:   test's l2:0 
+## [632]:   test's l2:0 
+## [633]:   test's l2:0 
+## [634]:   test's l2:0 
+## [635]:   test's l2:0 
+## [636]:   test's l2:0 
+## [637]:   test's l2:0 
+## [638]:   test's l2:0 
+## [639]:   test's l2:0 
+## [640]:   test's l2:0 
+## [641]:   test's l2:0 
+## [642]:   test's l2:0 
+## [643]:   test's l2:0 
+## [644]:   test's l2:0 
+## [645]:   test's l2:0 
+## [646]:   test's l2:0 
+## [647]:   test's l2:0 
+## [648]:   test's l2:0 
+## [649]:   test's l2:0 
+## [650]:   test's l2:0 
+## [651]:   test's l2:0 
+## [652]:   test's l2:0 
+## [653]:   test's l2:0 
+## [654]:   test's l2:0 
+## [655]:   test's l2:0 
+## [656]:   test's l2:0 
+## [657]:   test's l2:0 
+## [658]:   test's l2:0 
+## [659]:   test's l2:0 
+## [660]:   test's l2:0 
+## [661]:   test's l2:0 
+## [662]:   test's l2:0 
+## [663]:   test's l2:0 
+## [664]:   test's l2:0 
+## [665]:   test's l2:0 
+## [666]:   test's l2:0 
+## [667]:   test's l2:0 
+## [668]:   test's l2:0 
+## [669]:   test's l2:0 
+## [670]:   test's l2:0 
+## [671]:   test's l2:0 
+## [672]:   test's l2:0 
+## [673]:   test's l2:0 
+## [674]:   test's l2:0 
+## [675]:   test's l2:0 
+## [676]:   test's l2:0 
+## [677]:   test's l2:0 
+## [678]:   test's l2:0 
+## [679]:   test's l2:0 
+## [680]:   test's l2:0 
+## [681]:   test's l2:0 
+## [682]:   test's l2:0 
+## [683]:   test's l2:0 
+## [684]:   test's l2:0 
+## [685]:   test's l2:0 
+## [686]:   test's l2:0 
+## [687]:   test's l2:0 
+## [688]:   test's l2:0 
+## [689]:   test's l2:0 
+## [690]:   test's l2:0 
+## [691]:   test's l2:0 
+## [692]:   test's l2:0 
+## [693]:   test's l2:0 
+## [694]:   test's l2:0 
+## [695]:   test's l2:0 
+## [696]:   test's l2:0 
+## [697]:   test's l2:0 
+## [698]:   test's l2:0 
+## [699]:   test's l2:0 
+## [700]:   test's l2:0 
+## [701]:   test's l2:0 
+## [702]:   test's l2:0 
+## [703]:   test's l2:0 
+## [704]:   test's l2:0 
+## [705]:   test's l2:0 
+## [706]:   test's l2:0 
+## [707]:   test's l2:0 
+## [708]:   test's l2:0 
+## [709]:   test's l2:0 
+## [710]:   test's l2:0 
+## [711]:   test's l2:0 
+## [712]:   test's l2:0 
+## [713]:   test's l2:0 
+## [714]:   test's l2:0 
+## [715]:   test's l2:0 
+## [716]:   test's l2:0 
+## [717]:   test's l2:0 
+## [718]:   test's l2:0 
+## [719]:   test's l2:0 
+## [720]:   test's l2:0 
+## [721]:   test's l2:0 
+## [722]:   test's l2:0 
+## [723]:   test's l2:0 
+## [724]:   test's l2:0 
+## [725]:   test's l2:0 
+## [726]:   test's l2:0 
+## [727]:   test's l2:0 
+## [728]:   test's l2:0 
+## [729]:   test's l2:0 
+## [730]:   test's l2:0 
+## [731]:   test's l2:0 
+## [732]:   test's l2:0 
+## [733]:   test's l2:0 
+## [734]:   test's l2:0 
+## [735]:   test's l2:0 
+## [736]:   test's l2:0 
+## [737]:   test's l2:0 
+## [738]:   test's l2:0 
+## [739]:   test's l2:0 
+## [740]:   test's l2:0 
+## [741]:   test's l2:0 
+## [742]:   test's l2:0 
+## [743]:   test's l2:0 
+## [744]:   test's l2:0 
+## [745]:   test's l2:0 
+## [746]:   test's l2:0 
+## [747]:   test's l2:0 
+## [748]:   test's l2:0 
+## [749]:   test's l2:0 
+## [750]:   test's l2:0 
+## [751]:   test's l2:0 
+## [752]:   test's l2:0 
+## [753]:   test's l2:0 
+## [754]:   test's l2:0 
+## [755]:   test's l2:0 
+## [756]:   test's l2:0 
+## [757]:   test's l2:0 
+## [758]:   test's l2:0 
+## [759]:   test's l2:0 
+## [760]:   test's l2:0 
+## [761]:   test's l2:0 
+## [762]:   test's l2:0 
+## [763]:   test's l2:0 
+## [764]:   test's l2:0 
+## [765]:   test's l2:0 
+## [766]:   test's l2:0 
+## [767]:   test's l2:0 
+## [768]:   test's l2:0 
+## [769]:   test's l2:0 
+## [770]:   test's l2:0 
+## [771]:   test's l2:0 
+## [772]:   test's l2:0 
+## [773]:   test's l2:0 
+## [774]:   test's l2:0 
+## [775]:   test's l2:0 
+## [776]:   test's l2:0 
+## [777]:   test's l2:0 
+## [778]:   test's l2:0 
+## [779]:   test's l2:0 
+## [780]:   test's l2:0 
+## [781]:   test's l2:0 
+## [782]:   test's l2:0 
+## [783]:   test's l2:0 
+## [784]:   test's l2:0 
+## [785]:   test's l2:0 
+## [786]:   test's l2:0 
+## [787]:   test's l2:0 
+## [788]:   test's l2:0 
+## [789]:   test's l2:0 
+## [790]:   test's l2:0 
+## [791]:   test's l2:0 
+## [792]:   test's l2:0 
+## [793]:   test's l2:0 
+## [794]:   test's l2:0 
+## [795]:   test's l2:0 
+## [796]:   test's l2:0 
+## [797]:   test's l2:0 
+## [798]:   test's l2:0 
+## [799]:   test's l2:0 
+## [800]:   test's l2:0 
+## [801]:   test's l2:0 
+## [802]:   test's l2:0 
+## [803]:   test's l2:0 
+## [804]:   test's l2:0 
+## [805]:   test's l2:0 
+## [806]:   test's l2:0 
+## [807]:   test's l2:0 
+## [808]:   test's l2:0 
+## [809]:   test's l2:0 
+## [810]:   test's l2:0 
+## [811]:   test's l2:0 
+## [812]:   test's l2:0 
+## [813]:   test's l2:0 
+## [814]:   test's l2:0 
+## [815]:   test's l2:0 
+## [816]:   test's l2:0 
+## [817]:   test's l2:0 
+## [818]:   test's l2:0 
+## [819]:   test's l2:0 
+## [820]:   test's l2:0 
+## [821]:   test's l2:0 
+## [822]:   test's l2:0 
+## [823]:   test's l2:0 
+## [824]:   test's l2:0 
+## [825]:   test's l2:0 
+## [826]:   test's l2:0 
+## [827]:   test's l2:0 
+## [828]:   test's l2:0 
+## [829]:   test's l2:0 
+## [830]:   test's l2:0 
+## [831]:   test's l2:0 
+## [832]:   test's l2:0 
+## [833]:   test's l2:0 
+## [834]:   test's l2:0 
+## [835]:   test's l2:0 
+## [836]:   test's l2:0 
+## [837]:   test's l2:0 
+## [838]:   test's l2:0 
+## [839]:   test's l2:0 
+## [840]:   test's l2:0 
+## [841]:   test's l2:0 
+## [842]:   test's l2:0 
+## [843]:   test's l2:0 
+## [844]:   test's l2:0 
+## [845]:   test's l2:0 
+## [846]:   test's l2:0 
+## [847]:   test's l2:0 
+## [848]:   test's l2:0 
+## [849]:   test's l2:0 
+## [850]:   test's l2:0 
+## [851]:   test's l2:0 
+## [852]:   test's l2:0 
+## [853]:   test's l2:0 
+## [854]:   test's l2:0 
+## [855]:   test's l2:0 
+## [856]:   test's l2:0 
+## [857]:   test's l2:0 
+## [858]:   test's l2:0 
+## [859]:   test's l2:0 
+## [860]:   test's l2:0 
+## [861]:   test's l2:0 
+## [862]:   test's l2:0 
+## [863]:   test's l2:0 
+## [864]:   test's l2:0 
+## [865]:   test's l2:0 
+## [866]:   test's l2:0 
+## [867]:   test's l2:0 
+## [868]:   test's l2:0 
+## [869]:   test's l2:0 
+## [870]:   test's l2:0 
+## [871]:   test's l2:0 
+## [872]:   test's l2:0 
+## [873]:   test's l2:0 
+## [874]:   test's l2:0 
+## [875]:   test's l2:0 
+## [876]:   test's l2:0 
+## [877]:   test's l2:0 
+## [878]:   test's l2:0 
+## [879]:   test's l2:0 
+## [880]:   test's l2:0 
+## [881]:   test's l2:0 
+## [882]:   test's l2:0 
+## [883]:   test's l2:0 
+## [884]:   test's l2:0 
+## [885]:   test's l2:0 
+## [886]:   test's l2:0 
+## [887]:   test's l2:0 
+## [888]:   test's l2:0 
+## [889]:   test's l2:0 
+## [890]:   test's l2:0 
+## [891]:   test's l2:0 
+## [892]:   test's l2:0 
+## [893]:   test's l2:0 
+## [894]:   test's l2:0 
+## [895]:   test's l2:0 
+## [896]:   test's l2:0 
+## [897]:   test's l2:0 
+## [898]:   test's l2:0 
+## [899]:   test's l2:0 
+## [900]:   test's l2:0 
+## [901]:   test's l2:0 
+## [902]:   test's l2:0 
+## [903]:   test's l2:0 
+## [904]:   test's l2:0 
+## [905]:   test's l2:0 
+## [906]:   test's l2:0 
+## [907]:   test's l2:0 
+## [908]:   test's l2:0 
+## [909]:   test's l2:0 
+## [910]:   test's l2:0 
+## [911]:   test's l2:0 
+## [912]:   test's l2:0 
+## [913]:   test's l2:0 
+## [914]:   test's l2:0 
+## [915]:   test's l2:0 
+## [916]:   test's l2:0 
+## [917]:   test's l2:0 
+## [918]:   test's l2:0 
+## [919]:   test's l2:0 
+## [920]:   test's l2:0 
+## [921]:   test's l2:0 
+## [922]:   test's l2:0 
+## [923]:   test's l2:0 
+## [924]:   test's l2:0 
+## [925]:   test's l2:0 
+## [926]:   test's l2:0 
+## [927]:   test's l2:0 
+## [928]:   test's l2:0 
+## [929]:   test's l2:0 
+## [930]:   test's l2:0 
+## [931]:   test's l2:0 
+## [932]:   test's l2:0 
+## [933]:   test's l2:0 
+## [934]:   test's l2:0 
+## [935]:   test's l2:0 
+## [936]:   test's l2:0 
+## [937]:   test's l2:0 
+## [938]:   test's l2:0 
+## [939]:   test's l2:0 
+## [940]:   test's l2:0 
+## [941]:   test's l2:0 
+## [942]:   test's l2:0 
+## [943]:   test's l2:0 
+## [944]:   test's l2:0 
+## [945]:   test's l2:0 
+## [946]:   test's l2:0 
+## [947]:   test's l2:0 
+## [948]:   test's l2:0 
+## [949]:   test's l2:0 
+## [950]:   test's l2:0 
+## [951]:   test's l2:0 
+## [952]:   test's l2:0 
+## [953]:   test's l2:0 
+## [954]:   test's l2:0 
+## [955]:   test's l2:0 
+## [956]:   test's l2:0 
+## [957]:   test's l2:0 
+## [958]:   test's l2:0 
+## [959]:   test's l2:0 
+## [960]:   test's l2:0 
+## [961]:   test's l2:0 
+## [962]:   test's l2:0 
+## [963]:   test's l2:0 
+## [964]:   test's l2:0 
+## [965]:   test's l2:0 
+## [966]:   test's l2:0 
+## [967]:   test's l2:0 
+## [968]:   test's l2:0 
+## [969]:   test's l2:0 
+## [970]:   test's l2:0 
+## [971]:   test's l2:0 
+## [972]:   test's l2:0 
+## [973]:   test's l2:0 
+## [974]:   test's l2:0 
+## [975]:   test's l2:0 
+## [976]:   test's l2:0 
+## [977]:   test's l2:0 
+## [978]:   test's l2:0 
+## [979]:   test's l2:0 
+## [980]:   test's l2:0 
+## [981]:   test's l2:0 
+## [982]:   test's l2:0 
+## [983]:   test's l2:0 
+## [984]:   test's l2:0 
+## [985]:   test's l2:0 
+## [986]:   test's l2:0 
+## [987]:   test's l2:0 
+## [988]:   test's l2:0 
+## [989]:   test's l2:0 
+## [990]:   test's l2:0 
+## [991]:   test's l2:0 
+## [992]:   test's l2:0 
+## [993]:   test's l2:0 
+## [994]:   test's l2:0 
+## [995]:   test's l2:0 
+## [996]:   test's l2:0 
+## [997]:   test's l2:0 
+## [998]:   test's l2:0 
+## [999]:   test's l2:0 
+## [1000]:  test's l2:0
+
# We create the data structure, but for model3
+new_data3 <- data.frame(X = rowMeans(predict(model3,
+                                             agaricus.test$data,
+                                             predleaf = TRUE)),
+                        Y = pmin(pmax(predict(model3,
+                                              agaricus.test$data), 1e-15), 1 - 1e-15))
+new_data3$Z <- -(agaricus.test$label * log(new_data3$Y) + (1 - agaricus.test$label) * log(1 - new_data3$Y))
+new_data3$binned <- .bincode(x = new_data3$X,
+                             breaks = quantile(x = new_data3$X,
+                                               probs = (1:9)/10),
+                             right = TRUE,
+                             include.lowest = TRUE)
+new_data3$binned[is.na(new_data3$binned)] <- 0
+new_data3$binned <- as.factor(new_data3$binned)
+
+# We can check the binned content
+table(new_data3$binned)
+
## 
+##   0   1   2   4   5   6   8 
+##  25 440 337  31 159 339 280
+
# We can plot the binned content
+# On the third plot, it is clearly not smooth! We are severely overfitting the data, but the rules are real thus it is not an issue.
+# However, if the rules were not true, the loss would explode. See the sudden spikes?
+ggplot(data = new_data3, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density")
+

+
# Compare with our second model, the difference is severe. This is smooth.
+ggplot(data = new_data2, mapping = aes(x = Y, y = ..count.., fill = binned)) + geom_density(position = "fill") + theme_bw() + labs(title = "Depth Density", x = "Prediction Probability", y = "Bin Density")
+

+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-1.png b/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-1.png new file mode 100644 index 0000000000000000000000000000000000000000..092438548cd00cc6be34e1eeedda4c182ef6e465 GIT binary patch literal 19800 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-2.png b/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-2.png new file mode 100644 index 0000000000000000000000000000000000000000..db23e2739aafa0d9e530bb6c4cdcd7ad3f5701da GIT binary patch literal 13762 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 s@w0LGigq)wXpR5$cY*S^X1Ku|Kxc~qF literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-3.png b/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-3.png new file mode 100644 index 0000000000000000000000000000000000000000..29c4695e64c2621cf1dc294bacf839e81c82a1e8 GIT binary patch literal 14509 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-7.png b/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-7.png new file mode 100644 index 0000000000000000000000000000000000000000..6d7e4050ae0f5e3b4c1d7192633ab5907ab75c1f GIT binary patch literal 18147 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-8.png b/R-package/docs/articles/leaf_stability_files/figure-html/unnamed-chunk-1-8.png new file mode 100644 index 0000000000000000000000000000000000000000..6d7e4050ae0f5e3b4c1d7192633ab5907ab75c1f GIT binary patch literal 18147 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/multiclass.html b/R-package/docs/articles/multiclass.html new file mode 100644 index 000000000000..f902314fbf77 --- /dev/null +++ b/R-package/docs/articles/multiclass.html @@ -0,0 +1,216 @@ + + + + + + + +Multiclass training/prediction • lightgbm + + + + + + + + + + diff --git a/R-package/docs/articles/weight_param.html b/R-package/docs/articles/weight_param.html new file mode 100644 index 000000000000..e6a599874633 --- /dev/null +++ b/R-package/docs/articles/weight_param.html @@ -0,0 +1,340 @@ + + + + + + + +Weight-Parameter adjustment relationship • lightgbm + + + + + + +
+
+ + + +
+
+ + + + +
+
# This demo R code is to provide a demonstration of hyperparameter adjustment
+# when scaling weights for appropriate learning
+# As with any optimizers, bad parameters can impair performance
+
+# Load library
+library(lightgbm)
+
## Loading required package: R6
+
# We will train a model with the following scenarii:
+# - Run 1: sum of weights equal to 0.06513 without adjusted regularization (not learning)
+# - Run 2: sum of weights equal to 0.06513 with adjusted regularization (learning)
+# - Run 3: sum of weights equal to 6513 (x 1e5) with adjusted regularization (learning)
+
+# Setup small weights
+weights1 <- rep(1/100000, 6513)
+weights2 <- rep(1/100000, 1611)
+
+# Load data and create datasets
+data(agaricus.train, package = "lightgbm")
+train <- agaricus.train
+dtrain <- lgb.Dataset(train$data, label = train$label, weight = weights1)
+data(agaricus.test, package = "lightgbm")
+test <- agaricus.test
+dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label, weight = weights2)
+valids <- list(test = dtest)
+
+# Run 1: sum of weights equal to 0.06513 without adjusted regularization (not learning)
+# It cannot learn because regularization is too large!
+# min_sum_hessian alone is bigger than the sum of weights, thus you will never learn anything
+params <- list(objective = "regression",
+               metric = "l2",
+               device = "cpu",
+               min_sum_hessian = 10,
+               num_leaves = 7,
+               max_depth = 3,
+               nthread = 1)
+model <- lgb.train(params,
+                   dtrain,
+                   50,
+                   valids,
+                   min_data = 1,
+                   learning_rate = 1,
+                   early_stopping_rounds = 10)
+
## Loading required package: Matrix
+
## [1]: test's l2:0.249665 
+## [2]: test's l2:0.482507 
+## [3]: test's l2:1.18021 
+## [4]: test's l2:2.34279 
+## [5]: test's l2:3.97022 
+## [6]: test's l2:6.06253 
+## [7]: test's l2:8.6197 
+## [8]: test's l2:11.6417 
+## [9]: test's l2:15.1286 
+## [10]:    test's l2:19.0804 
+## [11]:    test's l2:23.497
+
weight_loss <- as.numeric(model$record_evals$test$l2$eval)
+plot(weight_loss) # Shows how poor the learning was: a straight line!
+

+
# Run 2: sum of weights equal to 0.06513 with adjusted regularization (learning)
+# Adjusted regularization just consisting in multiplicating results by 1e4 (x10000)
+# Notice how it learns, there is no issue as we adjusted regularization ourselves
+params <- list(objective = "regression",
+               metric = "l2",
+               device = "cpu",
+               min_sum_hessian = 1e-4,
+               num_leaves = 7,
+               max_depth = 3,
+               nthread = 1)
+model <- lgb.train(params,
+                   dtrain,
+                   50,
+                   valids,
+                   min_data = 1,
+                   learning_rate = 1,
+                   early_stopping_rounds = 10)
+
## [1]: test's l2:0.015004 
+## [2]: test's l2:0.00733572 
+## [3]: test's l2:0.00376968 
+## [4]: test's l2:0.00269737 
+## [5]: test's l2:0.0017028 
+## [6]: test's l2:0.000754526 
+## [7]: test's l2:0.000612458 
+## [8]: test's l2:0.000433644 
+## [9]: test's l2:0.00037502 
+## [10]:    test's l2:0.000343423 
+## [11]:    test's l2:0.000317457 
+## [12]:    test's l2:6.40256e-05 
+## [13]:    test's l2:4.83092e-05 
+## [14]:    test's l2:0.000160781 
+## [15]:    test's l2:0.000102254 
+## [16]:    test's l2:6.40448e-05 
+## [17]:    test's l2:4.31159e-05 
+## [18]:    test's l2:3.45622e-05 
+## [19]:    test's l2:2.92339e-05 
+## [20]:    test's l2:2.67598e-05 
+## [21]:    test's l2:2.99818e-05 
+## [22]:    test's l2:2.8607e-05 
+## [23]:    test's l2:2.67324e-05 
+## [24]:    test's l2:2.48837e-05 
+## [25]:    test's l2:2.02386e-05 
+## [26]:    test's l2:1.93004e-05 
+## [27]:    test's l2:1.88033e-05 
+## [28]:    test's l2:1.37116e-05 
+## [29]:    test's l2:1.28615e-05 
+## [30]:    test's l2:1.45912e-05 
+## [31]:    test's l2:1.04062e-05 
+## [32]:    test's l2:8.28405e-06 
+## [33]:    test's l2:7.53409e-06 
+## [34]:    test's l2:6.80012e-06 
+## [35]:    test's l2:6.60489e-06 
+## [36]:    test's l2:6.27259e-06 
+## [37]:    test's l2:5.7322e-06 
+## [38]:    test's l2:5.22595e-06 
+## [39]:    test's l2:6.30649e-06 
+## [40]:    test's l2:5.44453e-06 
+## [41]:    test's l2:4.76803e-06 
+## [42]:    test's l2:4.57209e-06 
+## [43]:    test's l2:4.27042e-06 
+## [44]:    test's l2:4.39086e-06 
+## [45]:    test's l2:3.46275e-06 
+## [46]:    test's l2:3.18253e-06 
+## [47]:    test's l2:3.14085e-06 
+## [48]:    test's l2:3.01015e-06 
+## [49]:    test's l2:2.38811e-06 
+## [50]:    test's l2:2.22581e-06
+
small_weight_loss <- as.numeric(model$record_evals$test$l2$eval)
+plot(small_weight_loss) # It learns!
+

+
# Run 3: sum of weights equal to 6513 (x 1e5) with adjusted regularization (learning)
+# To make it better, we are first cleaning the environment and reloading LightGBM
+lgb.unloader(wipe = TRUE)
+
+# And now, we are doing as usual
+library(lightgbm)
+data(agaricus.train, package = "lightgbm")
+train <- agaricus.train
+dtrain <- lgb.Dataset(train$data, label = train$label)
+data(agaricus.test, package = "lightgbm")
+test <- agaricus.test
+dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label)
+valids <- list(test = dtest)
+
+# Setup parameters and run model...
+params <- list(objective = "regression",
+               metric = "l2",
+               device = "cpu",
+               min_sum_hessian = 10,
+               num_leaves = 7,
+               max_depth = 3,
+               nthread = 1)
+model <- lgb.train(params,
+                   dtrain,
+                   50,
+                   valids,
+                   min_data = 1,
+                   learning_rate = 1,
+                   early_stopping_rounds = 10)
+
## [1]: test's l2:0.015004 
+## [2]: test's l2:0.00733572 
+## [3]: test's l2:0.00376968 
+## [4]: test's l2:0.00269737 
+## [5]: test's l2:0.00186089 
+## [6]: test's l2:0.00111794 
+## [7]: test's l2:0.00123277 
+## [8]: test's l2:0.00120069 
+## [9]: test's l2:0.00087376 
+## [10]:    test's l2:0.000777554 
+## [11]:    test's l2:0.000707629 
+## [12]:    test's l2:0.000526292 
+## [13]:    test's l2:0.000564568 
+## [14]:    test's l2:0.000520694 
+## [15]:    test's l2:0.000492974 
+## [16]:    test's l2:0.000509947 
+## [17]:    test's l2:0.000409418 
+## [18]:    test's l2:0.000436754 
+## [19]:    test's l2:0.000415116 
+## [20]:    test's l2:0.000398686 
+## [21]:    test's l2:0.000308853 
+## [22]:    test's l2:0.000333474 
+## [23]:    test's l2:0.000308576 
+## [24]:    test's l2:0.000293586 
+## [25]:    test's l2:0.000283788 
+## [26]:    test's l2:0.000228984 
+## [27]:    test's l2:0.000240609 
+## [28]:    test's l2:0.000227057 
+## [29]:    test's l2:0.000218103 
+## [30]:    test's l2:0.000176547 
+## [31]:    test's l2:0.000188157 
+## [32]:    test's l2:0.000176642 
+## [33]:    test's l2:0.000169261 
+## [34]:    test's l2:0.000137216 
+## [35]:    test's l2:0.000143953 
+## [36]:    test's l2:0.000135986 
+## [37]:    test's l2:0.000112708 
+## [38]:    test's l2:0.000117918 
+## [39]:    test's l2:0.000110817 
+## [40]:    test's l2:0.000106353 
+## [41]:    test's l2:0.000103378 
+## [42]:    test's l2:8.72045e-05 
+## [43]:    test's l2:9.12448e-05 
+## [44]:    test's l2:8.61785e-05 
+## [45]:    test's l2:8.30755e-05 
+## [46]:    test's l2:7.0557e-05 
+## [47]:    test's l2:7.39947e-05 
+## [48]:    test's l2:7.09341e-05 
+## [49]:    test's l2:6.19029e-05 
+## [50]:    test's l2:6.39761e-05
+
large_weight_loss <- as.numeric(model$record_evals$test$l2$eval)
+plot(large_weight_loss) # It learns!
+

+
# Do you want to compare the learning? They both converge.
+plot(small_weight_loss, large_weight_loss)
+curve(1*x, from = 0, to = 0.02, add = TRUE)
+

+
+
+ + + +
+ + + +
+ + + diff --git a/R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-1.png b/R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-1.png new file mode 100644 index 0000000000000000000000000000000000000000..731a120e8f4784701aa77125138106422f5b3c89 GIT binary patch literal 7602 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-2.png b/R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-2.png new file mode 100644 index 0000000000000000000000000000000000000000..23d7ea3128f0e5acd5168ae35893561853540838 GIT binary patch literal 9104 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-4.png b/R-package/docs/articles/weight_param_files/figure-html/unnamed-chunk-1-4.png new file mode 100644 index 0000000000000000000000000000000000000000..869fbb791846a809880bb2269c739a02fd625021 GIT binary patch literal 11120 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 p*AkYz-BtocE_EpYL5Bb{9nVmak~Hj literal 0 HcmV?d00001 diff --git a/R-package/docs/authors.html b/R-package/docs/authors.html new file mode 100644 index 000000000000..06e4c4b5e661 --- /dev/null +++ b/R-package/docs/authors.html @@ -0,0 +1,158 @@ + + + + + + + + +Authors • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + + +
+ +
+ + + +
+ + + diff --git a/R-package/docs/index.html b/R-package/docs/index.html new file mode 100644 index 000000000000..4045c939b64e --- /dev/null +++ b/R-package/docs/index.html @@ -0,0 +1,357 @@ + + + + + + + +Light Gradient Boosting Machine • lightgbm + + + + + + +
+
+ + + +
+
+ +
+ + +
+
+

+LightGBM, Light Gradient Boosting Machine

+

LightGBM is a gradient boosting framework that uses tree based learning algorithms. It is designed to be distributed and efficient with the following advantages:

+
    +
  • Faster training speed and higher efficiency
  • +
  • Lower memory usage
  • +
  • Better accuracy
  • +
  • Parallel and GPU learning supported
  • +
  • Capable of handling large-scale data
  • +
+

For more details, please refer to Features.

+

Comparison experiments on public datasets show that LightGBM can outperform existing boosting frameworks on both efficiency and accuracy, with significantly lower memory consumption. What’s more, the parallel experiments show that LightGBM can achieve a linear speed-up by using multiple machines for training in specific settings.

+
+

+News

+

08/15/2017 : Optimal split for categorical features.

+

07/13/2017 : Gitter is available.

+

06/20/2017 : Python-package is on PyPI now.

+

06/09/2017 : LightGBM Slack team is available.

+

05/03/2017 : LightGBM v2 stable release.

+

04/10/2017 : LightGBM supports GPU-accelerated tree learning now. Please read our GPU Tutorial and Performance Comparison.

+

02/20/2017 : Update to LightGBM v2.

+

02/12/2017: LightGBM v1 stable release.

+

01/08/2017 : Release R-package beta version, welcome to have a try and provide feedback.

+

12/05/2016 : Categorical Features as input directly (without one-hot coding).

+

12/02/2016 : Release Python-package beta version, welcome to have a try and provide feedback.

+

More detailed update logs : Key Events.

+
+
+

+External (unofficial) Repositories

+

Julia Package: https://github.com/Allardvm/LightGBM.jl

+

JPMML: https://github.com/jpmml/jpmml-lightgbm

+
+
+

+Get Started and Documentation

+

Install by following the guide for the command line program, Python-package or R-package. Then please see the Quick Start guide.

+

Our primary documentation is at https://lightgbm.readthedocs.io/ and is generated from this repository.

+

Next you may want to read:

+ +

Documentation for contributors:

+ +
+
+

+Support

+ +
+
+

+How to Contribute

+

LightGBM has been developed and used by many active community members. Your help is very valuable to make it better for everyone.

+
    +
  • Check out call for contributions to see what can be improved, or open an issue if you want something.
  • +
  • Contribute to the tests to make it more reliable.
  • +
  • Contribute to the documents to make it clearer for everyone.
  • +
  • Contribute to the examples to share your experience with other users.
  • +
  • Open issue if you met problems during development.
  • +
+
+
+

+Microsoft Open Source Code of Conduct

+

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

+
+
+

+Reference Paper

+

Guolin Ke, Qi Meng, Thomas Finley, Taifeng Wang, Wei Chen, Weidong Ma, Qiwei Ye, and Tie-Yan Liu. LightGBM: A Highly Efficient Gradient Boosting Decision Tree. In Advances in Neural Information Processing Systems (NIPS), pp. 3149-3157. 2017.

+
+
+

+Installation

+
+

+Preparation

+

You need to install git and CMake first.

+

Note: 32-bit R/Rtools is not supported.

+
+

+Windows Preparation

+

Installing Rtools is mandatory, and only support the 64-bit version. It requires to add to PATH the Rtools MinGW64 folder, if it was not done automatically during installation.

+

The default compiler is Visual Studio (or MS Build) in Windows, with an automatic fallback to Rtools or any MinGW64 (x86_64-posix-seh) available (this means if you have only Rtools and CMake, it will compile fine).

+

To force the usage of Rtools / MinGW, you can set use_mingw to TRUE in R-package/src/install.libs.R.

+

For users who wants to install online with GPU or want to choose a specific compiler, please check the end of this document for installation using a helper package (Laurae2/lgbdl).

+

Warning for Windows users: it is recommended to use Visual Studio for its better multi-threading efficency in Windows for many core systems. For very simple systems (dual core computers or worse), MinGW64 is recommended for maximum performance. If you do not know what to choose, it is recommended to use Visual Studio, the default compiler. Do not try using MinGW in Windows on many core systems. It may result in 10x slower results than Visual Studio.

+
+
+

+macOS Preparation

+

gcc with OpenMP support must be installed first. Refer to Installation-Guide for installing gcc with OpenMP support.

+
+
+
+

+Install

+

Install LightGBM R-package with the following command:

+
git clone --recursive https://github.com/Microsoft/LightGBM
+cd LightGBM/R-package
+# export CXX=g++-7 CC=gcc-7 # for macOS
+R CMD INSTALL --build . --no-multiarch
+

Or build a self-contained R package which can be installed afterwards:

+
git clone --recursive https://github.com/Microsoft/LightGBM
+cd LightGBM/R-package
+Rscript build_package.R
+# export CXX=g++-7 CC=gcc-7 # for macOS
+R CMD INSTALL lightgbm_2.0.4.tar.gz --no-multiarch
+

Note: for the build with Visual Studio/MSBuild in Windows, you should use the Windows CMD or Powershell.

+

Windows users may need to run with administrator rights (either R or the command prompt, depending on the way you are installing this package). Linux users might require the appropriate user write permissions for packages.

+

Set use_gpu to TRUE in R-package/src/install.libs.R to enable the build with GPU support. You will need to install Boost and OpenCL first: details for installation can be found in Installation-Guide.

+

You can also install directly from R using the repository with devtools:

+
library(devtools)
+options(devtools.install.args = "--no-multiarch") # if you have 64-bit R only, you can skip this
+install_github("Microsoft/LightGBM", subdir = "R-package")
+

If you are using a precompiled dll/lib locally, you can move the dll/lib into LightGBM root folder, modify LightGBM/R-package/src/install.libs.R’s 2nd line (change use_precompile <- FALSE to use_precompile <- TRUE), and install R-package as usual.

+

When your package installation is done, you can check quickly if your LightGBM R package is working by running the following:

+
library(lightgbm)
+data(agaricus.train, package='lightgbm')
+train <- agaricus.train
+dtrain <- lgb.Dataset(train$data, label=train$label)
+params <- list(objective="regression", metric="l2")
+model <- lgb.cv(params, dtrain, 10, nfold=5, min_data=1, learning_rate=1, early_stopping_rounds=10)
+
+
+
+

+Installation with Precompiled dll/lib from R Using GitHub

+

You can install LightGBM R-package from GitHub with devtools thanks to a helper package for LightGBM.

+
+

+Prerequisites

+

You will need:

+
    +
  • Precompiled LightGBM dll/lib
  • +
  • MinGW / Visual Studio / gcc (depending on your OS and your needs) with make in PATH environment variable
  • +
  • git in PATH environment variable
  • +
  • +CMake in PATH environment variable
  • +
  • +lgbdl R-package, which can be installed using devtools::install_github("Laurae2/lgbdl") +
  • +
  • +Rtools if using Windows
  • +
+

In addition, if you are using a Visual Studio precompiled DLL, assuming you do not have Visual Studio installed (if you have it installed, ignore the warnings below):

+
    +
  • Visual Studio 2015/2017 precompiled DLL: download and install Visual Studio Runtime for 2015/2017 (you will get an error about MSVCP140.dll missing otherwise)
  • +
+

Once you have all this setup, you can use lgb.dl from lgbdl package to install LightGBM from repository.

+

For instance, you can install the R package from LightGBM master commit of GitHub with Visual Studio using the following from R:

+
lgb.dl(commit = "master",
+       compiler = "vs",
+       repo = "https://github.com/Microsoft/LightGBM")
+

You may also install using a precompiled dll/lib using the following from R:

+
lgb.dl(commit = "master",
+       libdll = "C:\\LightGBM\\windows\\x64\\DLL\\lib_lightgbm.dll", # YOUR PRECOMPILED DLL
+       repo = "https://github.com/Microsoft/LightGBM")
+

You may also install online using a LightGBM with proper GPU support using Visual Studio (as an example here) using the following from R:

+
lgb.dl(commit = "master",
+       compiler = "vs", # Remove this for MinGW + GPU installation
+       repo = "https://github.com/Microsoft/LightGBM",
+       use_gpu = TRUE)
+

For more details about options, please check Laurae2/lgbdl R-package.

+

You may also read Microsoft/LightGBM#912 for a visual example for LightGBM installation in Windows with Visual Studio.

+
+
+ +
+ +
+ + +
+ + + +
+ + + diff --git a/R-package/docs/jquery.sticky-kit.min.js b/R-package/docs/jquery.sticky-kit.min.js new file mode 100644 index 000000000000..e2a3c6de9e8e --- /dev/null +++ b/R-package/docs/jquery.sticky-kit.min.js @@ -0,0 +1,9 @@ +/* + Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net +*/ +(function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k)); +if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("
"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, +u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), +a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", +y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n + + + + + diff --git a/R-package/docs/pkgdown.css b/R-package/docs/pkgdown.css new file mode 100644 index 000000000000..209ce57febdc --- /dev/null +++ b/R-package/docs/pkgdown.css @@ -0,0 +1,163 @@ +/* Sticker footer */ +body > .container { + display: flex; + padding-top: 60px; + min-height: calc(100vh); + flex-direction: column; +} + +body > .container .row { + flex: 1; +} + +footer { + margin-top: 45px; + padding: 35px 0 36px; + border-top: 1px solid #e5e5e5; + color: #666; + display: flex; +} +footer p { + margin-bottom: 0; +} +footer div { + flex: 1; +} +footer .pkgdown { + text-align: right; +} +footer p { + margin-bottom: 0; +} + +img.icon { + float: right; +} + +img { + max-width: 100%; +} + +/* Section anchors ---------------------------------*/ + +a.anchor { + margin-left: -30px; + display:inline-block; + width: 30px; + height: 30px; + visibility: hidden; + + background-image: url(./link.svg); + background-repeat: no-repeat; + background-size: 20px 20px; + background-position: center center; +} + +.hasAnchor:hover a.anchor { + visibility: visible; +} + +@media (max-width: 767px) { + .hasAnchor:hover a.anchor { + visibility: hidden; + } +} + + +/* Fixes for fixed navbar --------------------------*/ + +.contents h1, .contents h2, .contents h3, .contents h4 { + padding-top: 60px; + margin-top: -60px; +} + +/* Static header placement on mobile devices */ +@media (max-width: 767px) { + .navbar-fixed-top { + position: absolute; + } + .navbar { + padding: 0; + } +} + + +/* Sidebar --------------------------*/ + +#sidebar { + margin-top: 30px; +} +#sidebar h2 { + font-size: 1.5em; + margin-top: 1em; +} + +#sidebar h2:first-child { + margin-top: 0; +} + +#sidebar .list-unstyled li { + margin-bottom: 0.5em; +} + +/* Reference index & topics ----------------------------------------------- */ + +.ref-index th {font-weight: normal;} +.ref-index h2 {font-size: 20px;} + +.ref-index td {vertical-align: top;} +.ref-index .alias {width: 40%;} +.ref-index .title {width: 60%;} + +.ref-index .alias {width: 40%;} +.ref-index .title {width: 60%;} + +.ref-arguments th {text-align: right; padding-right: 10px;} +.ref-arguments th, .ref-arguments td {vertical-align: top;} +.ref-arguments .name {width: 20%;} +.ref-arguments .desc {width: 80%;} + +/* Nice scrolling for wide elements --------------------------------------- */ + +table { + display: block; + overflow: auto; +} + +/* Syntax highlighting ---------------------------------------------------- */ + +pre { + word-wrap: normal; + word-break: normal; + border: 1px solid #eee; +} + +pre, code { + background-color: #f8f8f8; + color: #333; +} + +pre .img { + margin: 5px 0; +} + +pre .img img { + background-color: #fff; + display: block; + height: auto; +} + +code a, pre a { + color: #375f84; +} + +.fl {color: #1514b5;} +.fu {color: #000000;} /* function */ +.ch,.st {color: #036a07;} /* string */ +.kw {color: #264D66;} /* keyword */ +.co {color: #888888;} /* comment */ + +.message { color: black; font-weight: bolder;} +.error { color: orange; font-weight: bolder;} +.warning { color: #6A0366; font-weight: bolder;} + diff --git a/R-package/docs/pkgdown.js b/R-package/docs/pkgdown.js new file mode 100644 index 000000000000..4b8171328904 --- /dev/null +++ b/R-package/docs/pkgdown.js @@ -0,0 +1,45 @@ +$(function() { + $("#sidebar").stick_in_parent({offset_top: 40}); + $('body').scrollspy({ + target: '#sidebar', + offset: 60 + }); + + var cur_path = paths(location.pathname); + $("#navbar ul li a").each(function(index, value) { + if (value.text == "Home") + return; + if (value.getAttribute("href") === "#") + return; + + var path = paths(value.pathname); + if (is_prefix(cur_path, path)) { + // Add class to parent
  • , and enclosing
  • if in dropdown + var menu_anchor = $(value); + menu_anchor.parent().addClass("active"); + menu_anchor.closest("li.dropdown").addClass("active"); + } + }); +}); + +function paths(pathname) { + var pieces = pathname.split("/"); + pieces.shift(); // always starts with / + + var end = pieces[pieces.length - 1]; + if (end === "index.html" || end === "") + pieces.pop(); + return(pieces); +} + +function is_prefix(needle, haystack) { + if (needle.length > haystack.lengh) + return(false); + + for (var i = 0; i < haystack.length; i++) { + if (needle[i] != haystack[i]) + return(false); + } + + return(true); +} diff --git a/R-package/docs/reference/agaricus.test.html b/R-package/docs/reference/agaricus.test.html new file mode 100644 index 000000000000..ae95ec35fd33 --- /dev/null +++ b/R-package/docs/reference/agaricus.test.html @@ -0,0 +1,180 @@ + + + + + + + + +Test part from Mushroom Data Set — agaricus.test • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    This data set is originally from the Mushroom data set, +UCI Machine Learning Repository.

    + + +
    data(agaricus.test)
    + +

    Format

    + +

    A list containing a label vector, and a dgCMatrix object with 1611 +rows and 126 variables

    + +

    Details

    + +

    This data set includes the following fields:

      +
    • label the label for each record

    • +
    • data a sparse Matrix of dgCMatrix class, with 126 columns.

    • +
    + +

    References

    + +

    https://archive.ics.uci.edu/ml/datasets/Mushroom

    +

    Bache, K. & Lichman, M. (2013). UCI Machine Learning Repository +[http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, +School of Information and Computer Science.

    + + +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/agaricus.train.html b/R-package/docs/reference/agaricus.train.html new file mode 100644 index 000000000000..23246709cbf1 --- /dev/null +++ b/R-package/docs/reference/agaricus.train.html @@ -0,0 +1,180 @@ + + + + + + + + +Training part from Mushroom Data Set — agaricus.train • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    This data set is originally from the Mushroom data set, +UCI Machine Learning Repository.

    + + +
    data(agaricus.train)
    + +

    Format

    + +

    A list containing a label vector, and a dgCMatrix object with 6513 +rows and 127 variables

    + +

    Details

    + +

    This data set includes the following fields:

      +
    • label the label for each record

    • +
    • data a sparse Matrix of dgCMatrix class, with 126 columns.

    • +
    + +

    References

    + +

    https://archive.ics.uci.edu/ml/datasets/Mushroom

    +

    Bache, K. & Lichman, M. (2013). UCI Machine Learning Repository +[http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, +School of Information and Computer Science.

    + + +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/bank.html b/R-package/docs/reference/bank.html new file mode 100644 index 000000000000..803cd87a7dcf --- /dev/null +++ b/R-package/docs/reference/bank.html @@ -0,0 +1,176 @@ + + + + + + + + +Bank Marketing Data Set — bank • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    This data set is originally from the Bank Marketing data set, +UCI Machine Learning Repository.

    + + +
    data(bank)
    + +

    Format

    + +

    A data.table with 4521 rows and 17 variables

    + +

    Details

    + +

    It contains only the following: bank.csv with 10 +randomly selected from 3 (older version of this dataset with less inputs).

    + +

    References

    + +

    http://archive.ics.uci.edu/ml/datasets/Bank+Marketing

    +

    S. Moro, P. Cortez and P. Rita. (2014) +A Data-Driven Approach to Predict the Success of Bank Telemarketing. Decision Support Systems

    + + +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/data.bin b/R-package/docs/reference/data.bin new file mode 100644 index 0000000000000000000000000000000000000000..836fab9305c3043d5e2f73cab19751cd7a3f5acc GIT binary patch literal 105975 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 F{}&SwxNQIc literal 0 HcmV?d00001 diff --git a/R-package/docs/reference/dim.html b/R-package/docs/reference/dim.html new file mode 100644 index 000000000000..0f85511b01ec --- /dev/null +++ b/R-package/docs/reference/dim.html @@ -0,0 +1,194 @@ + + + + + + + + +Dimensions of an lgb.Dataset — dim.lgb.Dataset • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Returns a vector of numbers of rows and of columns in an lgb.Dataset.

    + + +
    # S3 method for lgb.Dataset
    +dim(x, ...)
    + +

    Arguments

    + + + + + + + + + + +
    x

    Object of class lgb.Dataset

    ...

    other parameters

    + +

    Value

    + +

    a vector of numbers of rows and of columns

    + +

    Details

    + +

    Note: since nrow and ncol internally use dim, they can also +be directly used with an lgb.Dataset object.

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) + +stopifnot(nrow(dtrain) == nrow(train$data)) +stopifnot(ncol(dtrain) == ncol(train$data)) +stopifnot(all(dim(dtrain) == dim(train$data)))
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/dimnames.lgb.Dataset.html b/R-package/docs/reference/dimnames.lgb.Dataset.html new file mode 100644 index 000000000000..83ab70307577 --- /dev/null +++ b/R-package/docs/reference/dimnames.lgb.Dataset.html @@ -0,0 +1,349 @@ + + + + + + + + +Handling of column names of <code>lgb.Dataset</code> — dimnames.lgb.Dataset • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Only column names are supported for lgb.Dataset, thus setting of +row names would have no effect and returned row names would be NULL.

    + + +
    # S3 method for lgb.Dataset
    +dimnames(x)
    +
    +# S3 method for lgb.Dataset
    +dimnames(x) <- value
    + +

    Arguments

    + + + + + + + + + + +
    x

    object of class lgb.Dataset

    value

    a list of two elements: the first one is ignored +and the second one is column names

    + +

    Details

    + +

    Generic dimnames methods are used by colnames. +Since row names are irrelevant, it is recommended to use colnames directly.

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +lgb.Dataset.construct(dtrain) +dimnames(dtrain)
    #> [[1]] +#> NULL +#> +#> [[2]] +#> [1] "cap-shape=bell" "cap-shape=conical" +#> [3] "cap-shape=convex" "cap-shape=flat" +#> [5] "cap-shape=knobbed" "cap-shape=sunken" +#> [7] "cap-surface=fibrous" "cap-surface=grooves" +#> [9] "cap-surface=scaly" "cap-surface=smooth" +#> [11] "cap-color=brown" "cap-color=buff" +#> [13] "cap-color=cinnamon" "cap-color=gray" +#> [15] "cap-color=green" "cap-color=pink" +#> [17] "cap-color=purple" "cap-color=red" +#> [19] "cap-color=white" "cap-color=yellow" +#> [21] "bruises?=bruises" "bruises?=no" +#> [23] "odor=almond" "odor=anise" +#> [25] "odor=creosote" "odor=fishy" +#> [27] "odor=foul" "odor=musty" +#> [29] "odor=none" "odor=pungent" +#> [31] "odor=spicy" "gill-attachment=attached" +#> [33] "gill-attachment=descending" "gill-attachment=free" +#> [35] "gill-attachment=notched" "gill-spacing=close" +#> [37] "gill-spacing=crowded" "gill-spacing=distant" +#> [39] "gill-size=broad" "gill-size=narrow" +#> [41] "gill-color=black" "gill-color=brown" +#> [43] "gill-color=buff" "gill-color=chocolate" +#> [45] "gill-color=gray" "gill-color=green" +#> [47] "gill-color=orange" "gill-color=pink" +#> [49] "gill-color=purple" "gill-color=red" +#> [51] "gill-color=white" "gill-color=yellow" +#> [53] "stalk-shape=enlarging" "stalk-shape=tapering" +#> [55] "stalk-root=bulbous" "stalk-root=club" +#> [57] "stalk-root=cup" "stalk-root=equal" +#> [59] "stalk-root=rhizomorphs" "stalk-root=rooted" +#> [61] "stalk-root=missing" "stalk-surface-above-ring=fibrous" +#> [63] "stalk-surface-above-ring=scaly" "stalk-surface-above-ring=silky" +#> [65] "stalk-surface-above-ring=smooth" "stalk-surface-below-ring=fibrous" +#> [67] "stalk-surface-below-ring=scaly" "stalk-surface-below-ring=silky" +#> [69] "stalk-surface-below-ring=smooth" "stalk-color-above-ring=brown" +#> [71] "stalk-color-above-ring=buff" "stalk-color-above-ring=cinnamon" +#> [73] "stalk-color-above-ring=gray" "stalk-color-above-ring=orange" +#> [75] "stalk-color-above-ring=pink" "stalk-color-above-ring=red" +#> [77] "stalk-color-above-ring=white" "stalk-color-above-ring=yellow" +#> [79] "stalk-color-below-ring=brown" "stalk-color-below-ring=buff" +#> [81] "stalk-color-below-ring=cinnamon" "stalk-color-below-ring=gray" +#> [83] "stalk-color-below-ring=orange" "stalk-color-below-ring=pink" +#> [85] "stalk-color-below-ring=red" "stalk-color-below-ring=white" +#> [87] "stalk-color-below-ring=yellow" "veil-type=partial" +#> [89] "veil-type=universal" "veil-color=brown" +#> [91] "veil-color=orange" "veil-color=white" +#> [93] "veil-color=yellow" "ring-number=none" +#> [95] "ring-number=one" "ring-number=two" +#> [97] "ring-type=cobwebby" "ring-type=evanescent" +#> [99] "ring-type=flaring" "ring-type=large" +#> [101] "ring-type=none" "ring-type=pendant" +#> [103] "ring-type=sheathing" "ring-type=zone" +#> [105] "spore-print-color=black" "spore-print-color=brown" +#> [107] "spore-print-color=buff" "spore-print-color=chocolate" +#> [109] "spore-print-color=green" "spore-print-color=orange" +#> [111] "spore-print-color=purple" "spore-print-color=white" +#> [113] "spore-print-color=yellow" "population=abundant" +#> [115] "population=clustered" "population=numerous" +#> [117] "population=scattered" "population=several" +#> [119] "population=solitary" "habitat=grasses" +#> [121] "habitat=leaves" "habitat=meadows" +#> [123] "habitat=paths" "habitat=urban" +#> [125] "habitat=waste" "habitat=woods" +#>
    colnames(dtrain)
    #> [1] "cap-shape=bell" "cap-shape=conical" +#> [3] "cap-shape=convex" "cap-shape=flat" +#> [5] "cap-shape=knobbed" "cap-shape=sunken" +#> [7] "cap-surface=fibrous" "cap-surface=grooves" +#> [9] "cap-surface=scaly" "cap-surface=smooth" +#> [11] "cap-color=brown" "cap-color=buff" +#> [13] "cap-color=cinnamon" "cap-color=gray" +#> [15] "cap-color=green" "cap-color=pink" +#> [17] "cap-color=purple" "cap-color=red" +#> [19] "cap-color=white" "cap-color=yellow" +#> [21] "bruises?=bruises" "bruises?=no" +#> [23] "odor=almond" "odor=anise" +#> [25] "odor=creosote" "odor=fishy" +#> [27] "odor=foul" "odor=musty" +#> [29] "odor=none" "odor=pungent" +#> [31] "odor=spicy" "gill-attachment=attached" +#> [33] "gill-attachment=descending" "gill-attachment=free" +#> [35] "gill-attachment=notched" "gill-spacing=close" +#> [37] "gill-spacing=crowded" "gill-spacing=distant" +#> [39] "gill-size=broad" "gill-size=narrow" +#> [41] "gill-color=black" "gill-color=brown" +#> [43] "gill-color=buff" "gill-color=chocolate" +#> [45] "gill-color=gray" "gill-color=green" +#> [47] "gill-color=orange" "gill-color=pink" +#> [49] "gill-color=purple" "gill-color=red" +#> [51] "gill-color=white" "gill-color=yellow" +#> [53] "stalk-shape=enlarging" "stalk-shape=tapering" +#> [55] "stalk-root=bulbous" "stalk-root=club" +#> [57] "stalk-root=cup" "stalk-root=equal" +#> [59] "stalk-root=rhizomorphs" "stalk-root=rooted" +#> [61] "stalk-root=missing" "stalk-surface-above-ring=fibrous" +#> [63] "stalk-surface-above-ring=scaly" "stalk-surface-above-ring=silky" +#> [65] "stalk-surface-above-ring=smooth" "stalk-surface-below-ring=fibrous" +#> [67] "stalk-surface-below-ring=scaly" "stalk-surface-below-ring=silky" +#> [69] "stalk-surface-below-ring=smooth" "stalk-color-above-ring=brown" +#> [71] "stalk-color-above-ring=buff" "stalk-color-above-ring=cinnamon" +#> [73] "stalk-color-above-ring=gray" "stalk-color-above-ring=orange" +#> [75] "stalk-color-above-ring=pink" "stalk-color-above-ring=red" +#> [77] "stalk-color-above-ring=white" "stalk-color-above-ring=yellow" +#> [79] "stalk-color-below-ring=brown" "stalk-color-below-ring=buff" +#> [81] "stalk-color-below-ring=cinnamon" "stalk-color-below-ring=gray" +#> [83] "stalk-color-below-ring=orange" "stalk-color-below-ring=pink" +#> [85] "stalk-color-below-ring=red" "stalk-color-below-ring=white" +#> [87] "stalk-color-below-ring=yellow" "veil-type=partial" +#> [89] "veil-type=universal" "veil-color=brown" +#> [91] "veil-color=orange" "veil-color=white" +#> [93] "veil-color=yellow" "ring-number=none" +#> [95] "ring-number=one" "ring-number=two" +#> [97] "ring-type=cobwebby" "ring-type=evanescent" +#> [99] "ring-type=flaring" "ring-type=large" +#> [101] "ring-type=none" "ring-type=pendant" +#> [103] "ring-type=sheathing" "ring-type=zone" +#> [105] "spore-print-color=black" "spore-print-color=brown" +#> [107] "spore-print-color=buff" "spore-print-color=chocolate" +#> [109] "spore-print-color=green" "spore-print-color=orange" +#> [111] "spore-print-color=purple" "spore-print-color=white" +#> [113] "spore-print-color=yellow" "population=abundant" +#> [115] "population=clustered" "population=numerous" +#> [117] "population=scattered" "population=several" +#> [119] "population=solitary" "habitat=grasses" +#> [121] "habitat=leaves" "habitat=meadows" +#> [123] "habitat=paths" "habitat=urban" +#> [125] "habitat=waste" "habitat=woods"
    colnames(dtrain) <- make.names(1:ncol(train$data)) +print(dtrain, verbose = TRUE)
    #> <lgb.Dataset> +#> Public: +#> construct: function () +#> create_valid: function (data, info = list(), ...) +#> dim: function () +#> finalize: function () +#> get_colnames: function () +#> getinfo: function (name) +#> initialize: function (data, params = list(), reference = NULL, colnames = NULL, +#> save_binary: function (fname) +#> set_categorical_feature: function (categorical_feature) +#> set_colnames: function (colnames) +#> set_reference: function (reference) +#> setinfo: function (name, info) +#> slice: function (idxset, ...) +#> update_params: function (params) +#> Private: +#> categorical_feature: NULL +#> colnames: X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X ... +#> free_raw_data: TRUE +#> get_handle: function () +#> handle: 7.32442438646731e-318 +#> info: list +#> params: list +#> predictor: NULL +#> raw_data: NULL +#> reference: NULL +#> set_predictor: function (predictor) +#> used_indices: NULL
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/getinfo.html b/R-package/docs/reference/getinfo.html new file mode 100644 index 000000000000..8cec9f127b98 --- /dev/null +++ b/R-package/docs/reference/getinfo.html @@ -0,0 +1,207 @@ + + + + + + + + +Get information of an lgb.Dataset object — getinfo • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Get information of an lgb.Dataset object

    + + +
    getinfo(dataset, ...)
    +
    +# S3 method for lgb.Dataset
    +getinfo(dataset, name, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + +
    dataset

    Object of class lgb.Dataset

    ...

    other parameters

    name

    the name of the information field to get (see details)

    + +

    Value

    + +

    info data

    + +

    Details

    + +

    The name field can be one of the following:

      +
    • label: label lightgbm learn from ;

    • +
    • weight: to do a weight rescale ;

    • +
    • group: group size

    • +
    • init_score: initial score is the base prediction lightgbm will boost from ;

    • +
    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +lgb.Dataset.construct(dtrain) + +labels <- lightgbm::getinfo(dtrain, "label") +lightgbm::setinfo(dtrain, "label", 1 - labels) + +labels2 <- lightgbm::getinfo(dtrain, "label") +stopifnot(all(labels2 == 1 - labels))
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/index.html b/R-package/docs/reference/index.html new file mode 100644 index 000000000000..9f9e16bf1c88 --- /dev/null +++ b/R-package/docs/reference/index.html @@ -0,0 +1,407 @@ + + + + + + + + +Function reference • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Dataset

    +

    Datasets included with the R package

    +
    +

    data

    +

    Test part from Mushroom Data Set

    +

    data

    +

    Training part from Mushroom Data Set

    +

    data

    +

    Bank Marketing Data Set

    +

    Data Input / Output

    +

    Data I/O required for LightGBM

    +
    +

    dim

    +

    Dimensions of an lgb.Dataset

    +

    dimnames dimnames<-

    +

    Handling of column names of lgb.Dataset

    +

    getinfo

    +

    Get information of an lgb.Dataset object

    +

    setinfo

    +

    Set information of an lgb.Dataset object

    +

    slice

    +

    Slice a dataset

    +

    lgb.Dataset.construct

    +

    Construct Dataset explicitly

    +

    lgb.Dataset.create.valid

    +

    Construct validation data

    +

    lgb.Dataset

    +

    Construct lgb.Dataset object

    +

    lgb.Dataset.save

    +

    Save lgb.Dataset to a binary file

    +

    lgb.Dataset.set.categorical

    +

    Set categorical feature of lgb.Dataset

    +

    lgb.Dataset.set.reference

    +

    Set reference of lgb.Dataset

    +

    Machine Learning

    +

    Train models with LightGBM

    +
    +

    lgb.prepare

    +

    Data preparator for LightGBM datasets (numeric)

    +

    lgb.prepare2

    +

    Data preparator for LightGBM datasets (integer)

    +

    lgb.prepare_rules

    +

    Data preparator for LightGBM datasets with rules (numeric)

    +

    lgb.prepare_rules2

    +

    Data preparator for LightGBM datasets with rules (integer)

    +

    lgb.cv lgb.train lightgbm

    +

    Main CV logic for LightGBM

    +

    Saving / Loading Models

    +

    Save and Load LightGBM models

    +
    +

    lgb.dump

    +

    Dump LightGBM model to json

    +

    lgb.load

    +

    Load LightGBM model

    +

    lgb.model.dt.tree

    +

    Parse a LightGBM model json dump

    +

    lgb.save

    +

    Save LightGBM model

    +

    predict

    +

    Predict method for LightGBM model

    +

    readRDS.lgb.Booster

    +

    readRDS for lgb.Booster models

    +

    saveRDS.lgb.Booster

    +

    saveRDS for lgb.Booster models

    +

    Predictive Analysis

    +

    Analyze your predictions

    +
    +

    lgb.get.eval.result

    +

    Get record evaluation result from booster

    +

    lgb.importance

    +

    Compute feature importance in a model

    +

    lgb.interprete

    +

    Compute feature contribution of prediction

    +

    lgb.plot.importance

    +

    Plot feature importance as a bar graph

    +

    lgb.plot.interpretation

    +

    Plot feature contribution as a bar graph

    +

    Miscellaneous

    +

    Ungroupable functions to troubleshoot LightGBM

    +
    +

    lgb.unloader

    +

    LightGBM unloading error fix

    +
    +
    + + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.Dataset.construct.html b/R-package/docs/reference/lgb.Dataset.construct.html new file mode 100644 index 000000000000..d2af98742943 --- /dev/null +++ b/R-package/docs/reference/lgb.Dataset.construct.html @@ -0,0 +1,173 @@ + + + + + + + + +Construct Dataset explicitly — lgb.Dataset.construct • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Construct Dataset explicitly

    + + +
    lgb.Dataset.construct(dataset)
    + +

    Arguments

    + + + + + + +
    dataset

    Object of class lgb.Dataset

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +lgb.Dataset.construct(dtrain)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.Dataset.create.valid.html b/R-package/docs/reference/lgb.Dataset.create.valid.html new file mode 100644 index 000000000000..fc107aec7ab3 --- /dev/null +++ b/R-package/docs/reference/lgb.Dataset.create.valid.html @@ -0,0 +1,193 @@ + + + + + + + + +Construct validation data — lgb.Dataset.create.valid • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Construct validation data according to training data

    + + +
    lgb.Dataset.create.valid(dataset, data, info = list(), ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + +
    dataset

    lgb.Dataset object, training data

    data

    a matrix object, a dgCMatrix object or a character representing a filename

    info

    a list of information of the lgb.Dataset object

    ...

    other information to pass to info.

    + +

    Value

    + +

    constructed dataset

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.Dataset.data b/R-package/docs/reference/lgb.Dataset.data new file mode 100644 index 0000000000000000000000000000000000000000..836fab9305c3043d5e2f73cab19751cd7a3f5acc GIT binary patch literal 105975 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 F{}&SwxNQIc literal 0 HcmV?d00001 diff --git a/R-package/docs/reference/lgb.Dataset.html b/R-package/docs/reference/lgb.Dataset.html new file mode 100644 index 000000000000..b44361d538ac --- /dev/null +++ b/R-package/docs/reference/lgb.Dataset.html @@ -0,0 +1,211 @@ + + + + + + + + +Construct lgb.Dataset object — lgb.Dataset • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Construct lgb.Dataset object from dense matrix, sparse matrix +or local file (that was created previously by saving an lgb.Dataset).

    + + +
    lgb.Dataset(data, params = list(), reference = NULL, colnames = NULL,
    +  categorical_feature = NULL, free_raw_data = TRUE, info = list(), ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    data

    a matrix object, a dgCMatrix object or a character representing a filename

    params

    a list of parameters

    reference

    reference dataset

    colnames

    names of columns

    categorical_feature

    categorical features

    free_raw_data

    TRUE for need to free raw data after construct

    info

    a list of information of the lgb.Dataset object

    ...

    other information to pass to info or parameters pass to params

    + +

    Value

    + +

    constructed dataset

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +lgb.Dataset.save(dtrain, "lgb.Dataset.data") +dtrain <- lgb.Dataset("lgb.Dataset.data") +lgb.Dataset.construct(dtrain)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.Dataset.save.html b/R-package/docs/reference/lgb.Dataset.save.html new file mode 100644 index 000000000000..c4a5407b3dfd --- /dev/null +++ b/R-package/docs/reference/lgb.Dataset.save.html @@ -0,0 +1,184 @@ + + + + + + + + +Save <code>lgb.Dataset</code> to a binary file — lgb.Dataset.save • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Save lgb.Dataset to a binary file

    + + +
    lgb.Dataset.save(dataset, fname)
    + +

    Arguments

    + + + + + + + + + + +
    dataset

    object of class lgb.Dataset

    fname

    object filename of output file

    + +

    Value

    + +

    passed dataset

    + + +

    Examples

    +
    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +lgb.Dataset.save(dtrain, "data.bin")
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.Dataset.set.categorical.html b/R-package/docs/reference/lgb.Dataset.set.categorical.html new file mode 100644 index 000000000000..a9b7ebacacfa --- /dev/null +++ b/R-package/docs/reference/lgb.Dataset.set.categorical.html @@ -0,0 +1,185 @@ + + + + + + + + +Set categorical feature of <code>lgb.Dataset</code> — lgb.Dataset.set.categorical • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Set categorical feature of lgb.Dataset

    + + +
    lgb.Dataset.set.categorical(dataset, categorical_feature)
    + +

    Arguments

    + + + + + + + + + + +
    dataset

    object of class lgb.Dataset

    categorical_feature

    categorical features

    + +

    Value

    + +

    passed dataset

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +lgb.Dataset.save(dtrain, "lgb.Dataset.data") +dtrain <- lgb.Dataset("lgb.Dataset.data") +lgb.Dataset.set.categorical(dtrain, 1:2)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.Dataset.set.reference.html b/R-package/docs/reference/lgb.Dataset.set.reference.html new file mode 100644 index 000000000000..cf60db01cd0d --- /dev/null +++ b/R-package/docs/reference/lgb.Dataset.set.reference.html @@ -0,0 +1,186 @@ + + + + + + + + +Set reference of <code>lgb.Dataset</code> — lgb.Dataset.set.reference • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    If you want to use validation data, you should set reference to training data

    + + +
    lgb.Dataset.set.reference(dataset, reference)
    + +

    Arguments

    + + + + + + + + + + +
    dataset

    object of class lgb.Dataset

    reference

    object of class lgb.Dataset

    + +

    Value

    + +

    passed dataset

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package ="lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset(test$data, test = train$label) +lgb.Dataset.set.reference(dtest, dtrain)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.dump.html b/R-package/docs/reference/lgb.dump.html new file mode 100644 index 000000000000..953bc1eac623 --- /dev/null +++ b/R-package/docs/reference/lgb.dump.html @@ -0,0 +1,206 @@ + + + + + + + + +Dump LightGBM model to json — lgb.dump • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Dump LightGBM model to json

    + + +
    lgb.dump(booster, num_iteration = NULL)
    + +

    Arguments

    + + + + + + + + + + +
    booster

    Object of class lgb.Booster

    num_iteration

    number of iteration want to predict with, NULL or <= 0 means use best iteration

    + +

    Value

    + +

    json format of model

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10)
    #> [1]: test's l2:6.44165e-17 +#> [2]: test's l2:1.97215e-31 +#> [3]: test's l2:0 +#> [4]: test's l2:0 +#> [5]: test's l2:0 +#> [6]: test's l2:0 +#> [7]: test's l2:0 +#> [8]: test's l2:0 +#> [9]: test's l2:0 +#> [10]: test's l2:0 +#> [11]: test's l2:0 +#> [12]: test's l2:0 +#> [13]: test's l2:0
    json_model <- lgb.dump(model)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.get.eval.result.html b/R-package/docs/reference/lgb.get.eval.result.html new file mode 100644 index 000000000000..bcfb54d868d2 --- /dev/null +++ b/R-package/docs/reference/lgb.get.eval.result.html @@ -0,0 +1,221 @@ + + + + + + + + +Get record evaluation result from booster — lgb.get.eval.result • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Get record evaluation result from booster

    + + +
    lgb.get.eval.result(booster, data_name, eval_name, iters = NULL,
    +  is_err = FALSE)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + +
    booster

    Object of class lgb.Booster

    data_name

    name of dataset

    eval_name

    name of evaluation

    iters

    iterations, NULL will return all

    is_err

    TRUE will return evaluation error instead

    + +

    Value

    + +

    vector of evaluation result

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10)
    #> [1]: test's l2:6.44165e-17 +#> [2]: test's l2:1.97215e-31 +#> [3]: test's l2:0 +#> [4]: test's l2:0 +#> [5]: test's l2:0 +#> [6]: test's l2:0 +#> [7]: test's l2:0 +#> [8]: test's l2:0 +#> [9]: test's l2:0 +#> [10]: test's l2:0 +#> [11]: test's l2:0 +#> [12]: test's l2:0 +#> [13]: test's l2:0
    lgb.get.eval.result(model, "test", "l2")
    #> [1] 6.441652e-17 1.972152e-31 0.000000e+00 0.000000e+00 0.000000e+00 +#> [6] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 +#> [11] 0.000000e+00 0.000000e+00 0.000000e+00
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.importance.html b/R-package/docs/reference/lgb.importance.html new file mode 100644 index 000000000000..860a938b8dae --- /dev/null +++ b/R-package/docs/reference/lgb.importance.html @@ -0,0 +1,197 @@ + + + + + + + + +Compute feature importance in a model — lgb.importance • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Creates a data.table of feature importances in a model.

    + + +
    lgb.importance(model, percentage = TRUE)
    + +

    Arguments

    + + + + + + + + + + +
    model

    object of class lgb.Booster.

    percentage

    whether to show importance in relative percentage.

    + +

    Value

    + +

    For a tree model, a data.table with the following columns:

      +
    • Feature Feature names in the model.

    • +
    • Gain The total gain of this feature's splits.

    • +
    • Cover The number of observation related to this feature.

    • +
    • Frequency The number of times a feature splited in trees.

    • +
    + + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) + +params = list(objective = "binary", + learning_rate = 0.01, num_leaves = 63, max_depth = -1, + min_data_in_leaf = 1, min_sum_hessian_in_leaf = 1) + model <- lgb.train(params, dtrain, 20) +model <- lgb.train(params, dtrain, 20) + +tree_imp1 <- lgb.importance(model, percentage = TRUE) +tree_imp2 <- lgb.importance(model, percentage = FALSE)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.interprete.html b/R-package/docs/reference/lgb.interprete.html new file mode 100644 index 000000000000..3b4db1cf73d0 --- /dev/null +++ b/R-package/docs/reference/lgb.interprete.html @@ -0,0 +1,206 @@ + + + + + + + + +Compute feature contribution of prediction — lgb.interprete • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Computes feature contribution components of rawscore prediction.

    + + +
    lgb.interprete(model, data, idxset, num_iteration = NULL)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + +
    model

    object of class lgb.Booster.

    data

    a matrix object or a dgCMatrix object.

    idxset

    a integer vector of indices of rows needed.

    num_iteration

    number of iteration want to predict with, NULL or <= 0 means use best iteration.

    + +

    Value

    + +

    For regression, binary classification and lambdarank model, a list of data.table with the following columns:

      +
    • Feature Feature names in the model.

    • +
    • Contribution The total contribution of this feature's splits.

    • +

    For multiclass classification, a list of data.table with the Feature column and Contribution columns to each class.

    + + +

    Examples

    +
    library(lightgbm) +Sigmoid <- function(x) 1 / (1 + exp(-x)) +Logit <- function(x) log(x / (1 - x)) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +setinfo(dtrain, "init_score", rep(Logit(mean(train$label)), length(train$label))) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test + +params = list(objective = "binary", + learning_rate = 0.01, num_leaves = 63, max_depth = -1, + min_data_in_leaf = 1, min_sum_hessian_in_leaf = 1) + model <- lgb.train(params, dtrain, 20) +model <- lgb.train(params, dtrain, 20) + +tree_interpretation <- lgb.interprete(model, test$data, 1:5)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.load.html b/R-package/docs/reference/lgb.load.html new file mode 100644 index 000000000000..32b074b786ae --- /dev/null +++ b/R-package/docs/reference/lgb.load.html @@ -0,0 +1,204 @@ + + + + + + + + +Load LightGBM model — lgb.load • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Load LightGBM model from saved model file or string +Load LightGBM takes in either a file path or model string +If both are provided, Load will default to loading from file

    + + +
    lgb.load(filename = NULL, model_str = NULL)
    + +

    Arguments

    + + + + + + + + + + +
    filename

    path of model file

    model_str

    a str containing the model

    + +

    Value

    + +

    lgb.Booster

    + + +

    Examples

    +
    # It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + +library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +lgb.save(model, "model.txt") +load_booster <- lgb.load(filename = "model.txt") +model_string <- model$save_model_to_string(NULL) # saves best iteration +load_booster_from_str <- lgb.load(model_str = model_string) +}
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.model.dt.tree.html b/R-package/docs/reference/lgb.model.dt.tree.html new file mode 100644 index 000000000000..63c151d481b9 --- /dev/null +++ b/R-package/docs/reference/lgb.model.dt.tree.html @@ -0,0 +1,205 @@ + + + + + + + + +Parse a LightGBM model json dump — lgb.model.dt.tree • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Parse a LightGBM model json dump into a data.table structure.

    + + +
    lgb.model.dt.tree(model, num_iteration = NULL)
    + +

    Arguments

    + + + + + + +
    model

    object of class lgb.Booster

    + +

    Value

    + +

    A data.table with detailed information about model trees' nodes and leafs.

    +

    The columns of the data.table are:

      +
    • tree_index: ID of a tree in a model (integer)

    • +
    • split_index: ID of a node in a tree (integer)

    • +
    • split_feature: for a node, it's a feature name (character); + for a leaf, it simply labels it as "NA"

    • +
    • node_parent: ID of the parent node for current node (integer)

    • +
    • leaf_index: ID of a leaf in a tree (integer)

    • +
    • leaf_parent: ID of the parent node for current leaf (integer)

    • +
    • split_gain: Split gain of a node

    • +
    • threshold: Spliting threshold value of a node

    • +
    • decision_type: Decision type of a node

    • +
    • default_left: Determine how to handle NA value, TRUE -> Left, FALSE -> Right

    • +
    • internal_value: Node value

    • +
    • internal_count: The number of observation collected by a node

    • +
    • leaf_value: Leaf value

    • +
    • leaf_count: The number of observation collected by a leaf

    • +
    + + + +

    Examples

    +
    library(lightgbm) + +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) + +params = list(objective = "binary", + learning_rate = 0.01, num_leaves = 63, max_depth = -1, + min_data_in_leaf = 1, min_sum_hessian_in_leaf = 1) + model <- lgb.train(params, dtrain, 20) +model <- lgb.train(params, dtrain, 20) + +tree_dt <- lgb.model.dt.tree(model)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.plot.importance-2.png b/R-package/docs/reference/lgb.plot.importance-2.png new file mode 100644 index 0000000000000000000000000000000000000000..fa2235b02093e9961d6fe7540c1266dcbb7e14bb GIT binary patch literal 13062 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/reference/lgb.plot.importance-3.png b/R-package/docs/reference/lgb.plot.importance-3.png new file mode 100644 index 0000000000000000000000000000000000000000..fa2235b02093e9961d6fe7540c1266dcbb7e14bb GIT binary patch literal 13062 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 literal 0 HcmV?d00001 diff --git a/R-package/docs/reference/lgb.plot.importance.html b/R-package/docs/reference/lgb.plot.importance.html new file mode 100644 index 000000000000..8987ccf13259 --- /dev/null +++ b/R-package/docs/reference/lgb.plot.importance.html @@ -0,0 +1,211 @@ + + + + + + + + +Plot feature importance as a bar graph — lgb.plot.importance • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Plot previously calculated feature importance: Gain, Cover and Frequency, as a bar graph.

    + + +
    lgb.plot.importance(tree_imp, top_n = 10, measure = "Gain",
    +  left_margin = 10, cex = NULL)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + +
    tree_imp

    a data.table returned by lgb.importance.

    top_n

    maximal number of top features to include into the plot.

    measure

    the name of importance measure to plot, can be "Gain", "Cover" or "Frequency".

    left_margin

    (base R barplot) allows to adjust the left margin size to fit feature names.

    cex

    (base R barplot) passed as cex.names parameter to barplot.

    + +

    Value

    + +

    The lgb.plot.importance function creates a barplot +and silently returns a processed data.table with top_n features sorted by defined importance.

    + +

    Details

    + +

    The graph represents each feature as a horizontal bar of length proportional to the defined importance of a feature. +Features are shown ranked in a decreasing importance order.

    + + +

    Examples

    +
    data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) + +params = list(objective = "binary", + learning_rate = 0.01, num_leaves = 63, max_depth = -1, + min_data_in_leaf = 1, min_sum_hessian_in_leaf = 1) + model <- lgb.train(params, dtrain, 20) +model <- lgb.train(params, dtrain, 20) + +tree_imp <- lgb.importance(model, percentage = TRUE) +lgb.plot.importance(tree_imp, top_n = 10, measure = "Gain")
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.plot.interpretation-2.png b/R-package/docs/reference/lgb.plot.interpretation-2.png new file mode 100644 index 0000000000000000000000000000000000000000..91174065aeb9f7c28ee7caea5652ab204ec5b508 GIT binary patch literal 9500 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%0DoMfEj7w<}fX6Z}Hen?W*#9 znjnbF?Mj}~5bt_nC2JAH&YVRaJ|Mv~J72;(Wr&Bb6fxxEmf&4eh z8Nj{Vgd#hO7hcMZKCBBgX0jtUI!c({5l?cSB8E9Smyx5>1T8cj)31SWz`144?RyPw zA9xQuGPTyr17F?zsH15`1g|~52)A74XoQIna|xLg5B)`P7)*PeKVv+ws8jQHSGLb2 zVnA*nDBd{B-oLX(G{(A>h4ifN$o5epJ--RO|A?kqKW}I68_wgU?;!sSLZLj}efE}r I7;^Ey00C}>qyPW_ literal 0 HcmV?d00001 diff --git a/R-package/docs/reference/lgb.plot.interpretation-3.png b/R-package/docs/reference/lgb.plot.interpretation-3.png new file mode 100644 index 0000000000000000000000000000000000000000..91174065aeb9f7c28ee7caea5652ab204ec5b508 GIT binary patch literal 9500 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%0DoMfEj7w<}fX6Z}Hen?W*#9 znjnbF?Mj}~5bt_nC2JAH&YVRaJ|Mv~J72;(Wr&Bb6fxxEmf&4eh z8Nj{Vgd#hO7hcMZKCBBgX0jtUI!c({5l?cSB8E9Smyx5>1T8cj)31SWz`144?RyPw zA9xQuGPTyr17F?zsH15`1g|~52)A74XoQIna|xLg5B)`P7)*PeKVv+ws8jQHSGLb2 zVnA*nDBd{B-oLX(G{(A>h4ifN$o5epJ--RO|A?kqKW}I68_wgU?;!sSLZLj}efE}r I7;^Ey00C}>qyPW_ literal 0 HcmV?d00001 diff --git a/R-package/docs/reference/lgb.plot.interpretation.html b/R-package/docs/reference/lgb.plot.interpretation.html new file mode 100644 index 000000000000..e73f1a82d25a --- /dev/null +++ b/R-package/docs/reference/lgb.plot.interpretation.html @@ -0,0 +1,216 @@ + + + + + + + + +Plot feature contribution as a bar graph — lgb.plot.interpretation • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Plot previously calculated feature contribution as a bar graph.

    + + +
    lgb.plot.interpretation(tree_interpretation_dt, top_n = 10, cols = 1,
    +  left_margin = 10, cex = NULL)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + +
    tree_interpretation_dt

    a data.table returned by lgb.interprete.

    top_n

    maximal number of top features to include into the plot.

    cols

    the column numbers of layout, will be used only for multiclass classification feature contribution.

    left_margin

    (base R barplot) allows to adjust the left margin size to fit feature names.

    cex

    (base R barplot) passed as cex.names parameter to barplot.

    + +

    Value

    + +

    The lgb.plot.interpretation function creates a barplot.

    + +

    Details

    + +

    The graph represents each feature as a horizontal bar of length proportional to the defined contribution of a feature. +Features are shown ranked in a decreasing contribution order.

    + + +

    Examples

    +
    library(lightgbm) +Sigmoid <- function(x) {1 / (1 + exp(-x))} +Logit <- function(x) {log(x / (1 - x))} +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +setinfo(dtrain, "init_score", rep(Logit(mean(train$label)), length(train$label))) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test + +params = list(objective = "binary", + learning_rate = 0.01, num_leaves = 63, max_depth = -1, + min_data_in_leaf = 1, min_sum_hessian_in_leaf = 1) + model <- lgb.train(params, dtrain, 20) +model <- lgb.train(params, dtrain, 20) + +tree_interpretation <- lgb.interprete(model, test$data, 1:5) +lgb.plot.interpretation(tree_interpretation[[1]], top_n = 10)
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.prepare.html b/R-package/docs/reference/lgb.prepare.html new file mode 100644 index 000000000000..0cb0cfc0ed52 --- /dev/null +++ b/R-package/docs/reference/lgb.prepare.html @@ -0,0 +1,216 @@ + + + + + + + + +Data preparator for LightGBM datasets (numeric) — lgb.prepare • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Attempts to prepare a clean dataset to prepare to put in a lgb.Dataset. Factors and characters are converted to numeric without integers. Please use lgb.prepare_rules if you want to apply this transformation to other datasets.

    + + +
    lgb.prepare(data)
    + +

    Arguments

    + + + + + + +
    data

    A data.frame or data.table to prepare.

    + +

    Value

    + +

    The cleaned dataset. It must be converted to a matrix format (as.matrix) for input in lgb.Dataset.

    + + +

    Examples

    +
    library(lightgbm) +data(iris) + +str(iris)
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 ... + +str(lgb.prepare(data = iris)) # Convert all factors/chars to numeric
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : num 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : num 1 1 1 1 1 1 1 1 1 1 ... + +# When lightgbm package is installed, and you do not want to load it +# You can still use the function! +lgb.unloader() +str(lightgbm::lgb.prepare(data = iris))
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : num 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : num 1 1 1 1 1 1 1 1 1 1 ... +
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.prepare2.html b/R-package/docs/reference/lgb.prepare2.html new file mode 100644 index 000000000000..b0a44a1d24aa --- /dev/null +++ b/R-package/docs/reference/lgb.prepare2.html @@ -0,0 +1,217 @@ + + + + + + + + +Data preparator for LightGBM datasets (integer) — lgb.prepare2 • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Attempts to prepare a clean dataset to prepare to put in a lgb.Dataset. Factors and characters are converted to numeric (specifically: integer). Please use lgb.prepare_rules2 if you want to apply this transformation to other datasets. This is useful if you have a specific need for integer dataset instead of numeric dataset. Note that there are programs which do not support integer-only input. Consider this as a half memory technique which is dangerous, especially for LightGBM.

    + + +
    lgb.prepare2(data)
    + +

    Arguments

    + + + + + + +
    data

    A data.frame or data.table to prepare.

    + +

    Value

    + +

    The cleaned dataset. It must be converted to a matrix format (as.matrix) for input in lgb.Dataset.

    + + +

    Examples

    +
    library(lightgbm) +data(iris) + +str(iris)
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 ... + +str(lgb.prepare2(data = iris)) # Convert all factors/chars to integer
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : int 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : int 1 1 1 1 1 1 1 1 1 1 ... + +# When lightgbm package is installed, and you do not want to load it +# You can still use the function! +lgb.unloader() +str(lightgbm::lgb.prepare2(data = iris))
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : int 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : int 1 1 1 1 1 1 1 1 1 1 ... + +
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.prepare_rules.html b/R-package/docs/reference/lgb.prepare_rules.html new file mode 100644 index 000000000000..68fec978b0d7 --- /dev/null +++ b/R-package/docs/reference/lgb.prepare_rules.html @@ -0,0 +1,246 @@ + + + + + + + + +Data preparator for LightGBM datasets with rules (numeric) — lgb.prepare_rules • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Attempts to prepare a clean dataset to prepare to put in a lgb.Dataset. Factors and characters are converted to numeric. In addition, keeps rules created so you can convert other datasets using this converter.

    + + +
    lgb.prepare_rules(data, rules = NULL)
    + +

    Arguments

    + + + + + + + + + + +
    data

    A data.frame or data.table to prepare.

    rules

    A set of rules from the data preparator, if already used.

    + +

    Value

    + +

    A list with the cleaned dataset (data) and the rules (rules). The data must be converted to a matrix format (as.matrix) for input in lgb.Dataset.

    + + +

    Examples

    +
    library(lightgbm) +data(iris) + +str(iris)
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 ... + +new_iris <- lgb.prepare_rules(data = iris) # Autoconverter +str(new_iris$data)
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : num 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : num 1 1 1 1 1 1 1 1 1 1 ... + +data(iris) # Erase iris dataset +iris$Species[1] <- "NEW FACTOR" # Introduce junk factor (NA)
    #> Warning: invalid factor level, NA generated
    # Warning message: +# In `[<-.factor`(`*tmp*`, 1, value = c(NA, 1L, 1L, 1L, 1L, 1L, 1L, : +# invalid factor level, NA generated + +# Use conversion using known rules +# Unknown factors become 0, excellent for sparse datasets +newer_iris <- lgb.prepare_rules(data = iris, rules = new_iris$rules) + +# Unknown factor is now zero, perfect for sparse datasets +newer_iris$data[1, ] # Species became 0 as it is an unknown factor
    #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species +#> 1 5.1 3.5 1.4 0.2 0
    # Sepal.Length Sepal.Width Petal.Length Petal.Width Species +# 1 5.1 3.5 1.4 0.2 0 + +newer_iris$data[1, 5] <- 1 # Put back real initial value + +# Is the newly created dataset equal? YES! +all.equal(new_iris$data, newer_iris$data)
    #> [1] TRUE
    # [1] TRUE + +# Can we test our own rules? +data(iris) # Erase iris dataset + +# We remapped values differently +personal_rules <- list(Species = c("setosa" = 3, + "versicolor" = 2, + "virginica" = 1)) +newest_iris <- lgb.prepare_rules(data = iris, rules = personal_rules) +str(newest_iris$data) # SUCCESS!
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : num 0 3 3 3 3 3 3 3 3 3 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : num 3 3 3 3 3 3 3 3 3 3 ... + +
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.prepare_rules2.html b/R-package/docs/reference/lgb.prepare_rules2.html new file mode 100644 index 000000000000..bfa1a169974a --- /dev/null +++ b/R-package/docs/reference/lgb.prepare_rules2.html @@ -0,0 +1,246 @@ + + + + + + + + +Data preparator for LightGBM datasets with rules (integer) — lgb.prepare_rules2 • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Attempts to prepare a clean dataset to prepare to put in a lgb.Dataset. Factors and characters are converted to numeric (specifically: integer). In addition, keeps rules created so you can convert other datasets using this converter. This is useful if you have a specific need for integer dataset instead of numeric dataset. Note that there are programs which do not support integer-only input. Consider this as a half memory technique which is dangerous, especially for LightGBM.

    + + +
    lgb.prepare_rules2(data, rules = NULL)
    + +

    Arguments

    + + + + + + + + + + +
    data

    A data.frame or data.table to prepare.

    rules

    A set of rules from the data preparator, if already used.

    + +

    Value

    + +

    A list with the cleaned dataset (data) and the rules (rules). The data must be converted to a matrix format (as.matrix) for input in lgb.Dataset.

    + + +

    Examples

    +
    library(lightgbm) +data(iris) + +str(iris)
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 ... + +new_iris <- lgb.prepare_rules2(data = iris) # Autoconverter +str(new_iris$data)
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : int 1 1 1 1 1 1 1 1 1 1 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : int 1 1 1 1 1 1 1 1 1 1 ... + +data(iris) # Erase iris dataset +iris$Species[1] <- "NEW FACTOR" # Introduce junk factor (NA)
    #> Warning: invalid factor level, NA generated
    # Warning message: +# In `[<-.factor`(`*tmp*`, 1, value = c(NA, 1L, 1L, 1L, 1L, 1L, 1L, : +# invalid factor level, NA generated + +# Use conversion using known rules +# Unknown factors become 0, excellent for sparse datasets +newer_iris <- lgb.prepare_rules2(data = iris, rules = new_iris$rules) + +# Unknown factor is now zero, perfect for sparse datasets +newer_iris$data[1, ] # Species became 0 as it is an unknown factor
    #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species +#> 1 5.1 3.5 1.4 0.2 0
    # Sepal.Length Sepal.Width Petal.Length Petal.Width Species +# 1 5.1 3.5 1.4 0.2 0 + +newer_iris$data[1, 5] <- 1 # Put back real initial value + +# Is the newly created dataset equal? YES! +all.equal(new_iris$data, newer_iris$data)
    #> [1] TRUE
    # [1] TRUE + +# Can we test our own rules? +data(iris) # Erase iris dataset + +# We remapped values differently +personal_rules <- list(Species = c("setosa" = 3L, + "versicolor" = 2L, + "virginica" = 1L)) +newest_iris <- lgb.prepare_rules2(data = iris, rules = personal_rules) +str(newest_iris$data) # SUCCESS!
    #> 'data.frame': 150 obs. of 5 variables: +#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +#> $ Species : int 0 3 3 3 3 3 3 3 3 3 ...
    # 'data.frame': 150 obs. of 5 variables: +# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... +# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... +# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... +# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... +# $ Species : int 3 3 3 3 3 3 3 3 3 3 ... + +
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.save.html b/R-package/docs/reference/lgb.save.html new file mode 100644 index 000000000000..0cf151200278 --- /dev/null +++ b/R-package/docs/reference/lgb.save.html @@ -0,0 +1,203 @@ + + + + + + + + +Save LightGBM model — lgb.save • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Save LightGBM model

    + + +
    lgb.save(booster, filename, num_iteration = NULL)
    + +

    Arguments

    + + + + + + + + + + + + + + +
    booster

    Object of class lgb.Booster

    filename

    saved filename

    num_iteration

    number of iteration want to predict with, NULL or <= 0 means use best iteration

    + +

    Value

    + +

    lgb.Booster

    + + +

    Examples

    +
    # It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + +library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +lgb.save(model, "model.txt") +}
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.train.html b/R-package/docs/reference/lgb.train.html new file mode 100644 index 000000000000..7d99714851d4 --- /dev/null +++ b/R-package/docs/reference/lgb.train.html @@ -0,0 +1,438 @@ + + + + + + + + +Main CV logic for LightGBM — lgb.cv • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Main CV logic for LightGBM

    +

    Main training logic for LightGBM

    +

    Simple interface for training an lightgbm model. +Its documentation is combined with lgb.train.

    + + +
    lgb.cv(params = list(), data, nrounds = 10, nfold = 3, label = NULL,
    +  weight = NULL, obj = NULL, eval = NULL, verbose = 1, record = TRUE,
    +  eval_freq = 1L, showsd = TRUE, stratified = TRUE, folds = NULL,
    +  init_model = NULL, colnames = NULL, categorical_feature = NULL,
    +  early_stopping_rounds = NULL, callbacks = list(), ...)
    +
    +lgb.train(params = list(), data, nrounds = 10, valids = list(),
    +  obj = NULL, eval = NULL, verbose = 1, record = TRUE, eval_freq = 1L,
    +  init_model = NULL, colnames = NULL, categorical_feature = NULL,
    +  early_stopping_rounds = NULL, callbacks = list(), reset_data = FALSE,
    +  ...)
    +
    +lightgbm(data, label = NULL, weight = NULL, params = list(),
    +  nrounds = 10, verbose = 1, eval_freq = 1L,
    +  early_stopping_rounds = NULL, save_name = "lightgbm.model",
    +  init_model = NULL, callbacks = list(), ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    params

    List of parameters

    data

    a lgb.Dataset object, used for CV

    nrounds

    number of CV rounds

    nfold

    the original dataset is randomly partitioned into nfold equal size subsamples.

    label

    vector of response values. Should be provided only when data is an R-matrix.

    weight

    vector of response values. If not NULL, will set to dataset

    obj

    objective function, can be character or custom objective function. Examples include +regression, regression_l1, huber, +binary, lambdarank, multiclass, multiclass

    eval

    evaluation function, can be (list of) character or custom eval function

    verbose

    verbosity for output, if <= 0, also will disable the print of evalutaion during training

    record

    Boolean, TRUE will record iteration message to booster$record_evals

    eval_freq

    evalutaion output frequence, only effect when verbose > 0

    showsd

    boolean, whether to show standard deviation of cross validation

    stratified

    a boolean indicating whether sampling of folds should be stratified +by the values of outcome labels.

    folds

    list provides a possibility to use a list of pre-defined CV folds +(each element must be a vector of test fold's indices). When folds are supplied, +the nfold and stratified parameters are ignored.

    init_model

    path of model file of lgb.Booster object, will continue train from this model

    colnames

    feature names, if not null, will use this to overwrite the names in dataset

    categorical_feature

    list of str or int +type int represents index, +type str represents feature names

    early_stopping_rounds

    int +Activates early stopping. +Requires at least one validation data and one metric +If there's more than one, will check all of them +Returns the model with (best_iter + early_stopping_rounds) +If early stopping occurs, the model will have 'best_iter' field

    callbacks

    list of callback functions +List of callback functions that are applied at each iteration.

    ...

    other parameters, see Parameters.rst for more informations

    valids

    a list of lgb.Dataset objects, used for validation

    reset_data

    Boolean, setting it to TRUE (not the default value) will transform the booster model into a predictor model which frees up memory and the original datasets

    boosting

    boosting type. gbdt, dart

    num_leaves

    number of leaves in one tree. defaults to 127

    max_depth

    Limit the max depth for tree model. This is used to deal with overfit when #data is small. +Tree still grow by leaf-wise.

    num_threads

    Number of threads for LightGBM. For the best speed, set this to the number of real CPU cores, not the number of threads (most CPU using hyper-threading to generate 2 threads per CPU core).

    params

    List of parameters

    data

    a lgb.Dataset object, used for training

    nrounds

    number of training rounds

    obj

    objective function, can be character or custom objective function. Examples include +regression, regression_l1, huber, +binary, lambdarank, multiclass, multiclass

    boosting

    boosting type. gbdt, dart

    num_leaves

    number of leaves in one tree. defaults to 127

    max_depth

    Limit the max depth for tree model. This is used to deal with overfit when #data is small. +Tree still grow by leaf-wise.

    num_threads

    Number of threads for LightGBM. For the best speed, set this to the number of real CPU cores, not the number of threads (most CPU using hyper-threading to generate 2 threads per CPU core).

    eval

    evaluation function, can be (a list of) character or custom eval function

    verbose

    verbosity for output, if <= 0, also will disable the print of evalutaion during training

    record

    Boolean, TRUE will record iteration message to booster$record_evals

    eval_freq

    evalutaion output frequency, only effect when verbose > 0

    init_model

    path of model file of lgb.Booster object, will continue training from this model

    colnames

    feature names, if not null, will use this to overwrite the names in dataset

    categorical_feature

    list of str or int +type int represents index, +type str represents feature names

    early_stopping_rounds

    int +Activates early stopping. +Requires at least one validation data and one metric +If there's more than one, will check all of them +Returns the model with (best_iter + early_stopping_rounds) +If early stopping occurs, the model will have 'best_iter' field

    callbacks

    list of callback functions +List of callback functions that are applied at each iteration.

    ...

    other parameters, see Parameters.rst for more informations

    + +

    Value

    + +

    a trained model lgb.CVBooster.

    +

    a trained booster model lgb.Booster.

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +params <- list(objective = "regression", metric = "l2") +model <- lgb.cv(params, + dtrain, + 10, + nfold = 5, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10)
    #> [1]: valid's l2:0.000460829+0.000921659 +#> [2]: valid's l2:0.000460829+0.000921659 +#> [3]: valid's l2:0.000460829+0.000921659 +#> [4]: valid's l2:0.000460829+0.000921659 +#> [5]: valid's l2:0.000460829+0.000921659 +#> [6]: valid's l2:0.000460829+0.000921659 +#> [7]: valid's l2:0.000460829+0.000921659 +#> [8]: valid's l2:0.000460829+0.000921659 +#> [9]: valid's l2:0.000460829+0.000921659 +#> [10]: valid's l2:0.000460829+0.000921659
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10)
    #> [1]: test's l2:6.44165e-17 +#> [2]: test's l2:1.97215e-31 +#> [3]: test's l2:0 +#> [4]: test's l2:0 +#> [5]: test's l2:0 +#> [6]: test's l2:0 +#> [7]: test's l2:0 +#> [8]: test's l2:0 +#> [9]: test's l2:0 +#> [10]: test's l2:0 +#> [11]: test's l2:0 +#> [12]: test's l2:0 +#> [13]: test's l2:0
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/lgb.unloader.html b/R-package/docs/reference/lgb.unloader.html new file mode 100644 index 000000000000..51ec9bad036b --- /dev/null +++ b/R-package/docs/reference/lgb.unloader.html @@ -0,0 +1,220 @@ + + + + + + + + +LightGBM unloading error fix — lgb.unloader • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Attempts to unload LightGBM packages so you can remove objects cleanly without having to restart R. This is useful for instance if an object becomes stuck for no apparent reason and you do not want to restart R to fix the lost object.

    + + +
    lgb.unloader(restore = TRUE, wipe = FALSE, envir = .GlobalEnv)
    + +

    Arguments

    + + + + + + + + + + + + + + +
    wipe

    Whether to wipe all lgb.Dataset and lgb.Booster from the global environment. Defaults to FALSE which means to not remove them.

    envir

    The environment to perform wiping on if wipe == TRUE. Defaults to .GlobalEnv which is the global environment.

    restart

    Whether to reload LightGBM immediately after detaching from R. Defaults to TRUE which means automatically reload LightGBM once unloading is performed.

    + +

    Value

    + +

    NULL invisibly.

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10)
    #> [1]: test's l2:6.44165e-17 +#> [2]: test's l2:1.97215e-31 +#> [3]: test's l2:0 +#> [4]: test's l2:0 +#> [5]: test's l2:0 +#> [6]: test's l2:0 +#> [7]: test's l2:0 +#> [8]: test's l2:0 +#> [9]: test's l2:0 +#> [10]: test's l2:0 +#> [11]: test's l2:0 +#> [12]: test's l2:0 +#> [13]: test's l2:0
    +# Disabled the following line as it crashes the documentation generator +# lgb.unloader(restore = FALSE, wipe = FALSE, envir = .GlobalEnv) +rm(model, dtrain, dtest) # Not needed if wipe = TRUE +gc() # Not needed if wipe = TRUE
    #> used (Mb) gc trigger (Mb) max used (Mb) +#> Ncells 1782257 95.2 3205452 171.2 2637877 140.9 +#> Vcells 5701405 43.5 8845222 67.5 7997217 61.1
    +# Disabled the following line as it crashes the documentation generator +# library(lightgbm) +# Do whatever you want again with LightGBM without object clashing +
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/predict.lgb.Booster.html b/R-package/docs/reference/predict.lgb.Booster.html new file mode 100644 index 000000000000..a712dfc6aa6e --- /dev/null +++ b/R-package/docs/reference/predict.lgb.Booster.html @@ -0,0 +1,230 @@ + + + + + + + + +Predict method for LightGBM model — predict.lgb.Booster • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Predicted values based on class lgb.Booster

    + + +
    # S3 method for lgb.Booster
    +predict(object, data, num_iteration = NULL,
    +  rawscore = FALSE, predleaf = FALSE, header = FALSE, reshape = FALSE,
    +  ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    object

    Object of class lgb.Booster

    data

    a matrix object, a dgCMatrix object or a character representing a filename

    num_iteration

    number of iteration want to predict with, NULL or <= 0 means use best iteration

    rawscore

    whether the prediction should be returned in the for of original untransformed +sum of predictions from boosting iterations' results. E.g., setting rawscore=TRUE for +logistic regression would result in predictions for log-odds instead of probabilities.

    predleaf

    whether predict leaf index instead.

    header

    only used for prediction for text file. True if text file has header

    reshape

    whether to reshape the vector of predictions to a matrix form when there are several +prediction outputs per case.

    + +

    Value

    + +

    For regression or binary classification, it returns a vector of length nrows(data). +For multiclass classification, either a num_class * nrows(data) vector or +a (nrows(data), num_class) dimension matrix is returned, depending on +the reshape value.

    +

    When predleaf = TRUE, the output is a matrix object with the +number of columns corresponding to the number of trees.

    + + +

    Examples

    +
    # It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + +library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +preds <- predict(model, test$data) +}
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/readRDS.lgb.Booster.html b/R-package/docs/reference/readRDS.lgb.Booster.html new file mode 100644 index 000000000000..5b19ffcd3a32 --- /dev/null +++ b/R-package/docs/reference/readRDS.lgb.Booster.html @@ -0,0 +1,200 @@ + + + + + + + + +readRDS for lgb.Booster models — readRDS.lgb.Booster • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Attemps to load a model using RDS.

    + + +
    readRDS.lgb.Booster(file = "", refhook = NULL)
    + +

    Arguments

    + + + + + + + + + + +
    file

    a connection or the name of the file where the R object is saved to or read from.

    refhook

    a hook function for handling reference objects.

    + +

    Value

    + +

    lgb.Booster.

    + + +

    Examples

    +
    # It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + +library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +saveRDS.lgb.Booster(model, "model.rds") +new_model <- readRDS.lgb.Booster("model.rds") +}
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/saveRDS.lgb.Booster.html b/R-package/docs/reference/saveRDS.lgb.Booster.html new file mode 100644 index 000000000000..6098336056d4 --- /dev/null +++ b/R-package/docs/reference/saveRDS.lgb.Booster.html @@ -0,0 +1,220 @@ + + + + + + + + +saveRDS for lgb.Booster models — saveRDS.lgb.Booster • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Attemps to save a model using RDS. Has an additional parameter (raw) which decides whether to save the raw model or not.

    + + +
    saveRDS.lgb.Booster(object, file = "", ascii = FALSE, version = NULL,
    +  compress = TRUE, refhook = NULL, raw = TRUE)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    object

    R object to serialize.

    file

    a connection or the name of the file where the R object is saved to or read from.

    ascii

    a logical. If TRUE or NA, an ASCII representation is written; otherwise (default), a binary one is used. See the comments in the help for save.

    version

    the workspace format version to use. NULL specifies the current default version (2). Versions prior to 2 are not supported, so this will only be relevant when there are later versions.

    compress

    a logical specifying whether saving to a named file is to use "gzip" compression, or one of "gzip", "bzip2" or "xz" to indicate the type of compression to be used. Ignored if file is a connection.

    refhook

    a hook function for handling reference objects.

    raw

    whether to save the model in a raw variable or not, recommended to leave it to TRUE.

    + +

    Value

    + +

    NULL invisibly.

    + + +

    Examples

    +
    # It crashes the documentation generation, skipping +if (!(pkgdown::in_pkgdown())) { + +library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +data(agaricus.test, package = "lightgbm") +test <- agaricus.test +dtest <- lgb.Dataset.create.valid(dtrain, test$data, label = test$label) +params <- list(objective = "regression", metric = "l2") +valids <- list(test = dtest) +model <- lgb.train(params, + dtrain, + 100, + valids, + min_data = 1, + learning_rate = 1, + early_stopping_rounds = 10) +saveRDS.lgb.Booster(model, "model.rds") +}
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/setinfo.html b/R-package/docs/reference/setinfo.html new file mode 100644 index 000000000000..5d0fd11f34cc --- /dev/null +++ b/R-package/docs/reference/setinfo.html @@ -0,0 +1,211 @@ + + + + + + + + +Set information of an lgb.Dataset object — setinfo • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Set information of an lgb.Dataset object

    + + +
    setinfo(dataset, ...)
    +
    +# S3 method for lgb.Dataset
    +setinfo(dataset, name, info, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + +
    dataset

    Object of class "lgb.Dataset"

    ...

    other parameters

    name

    the name of the field to get

    info

    the specific field of information to set

    + +

    Value

    + +

    passed object

    + +

    Details

    + +

    The name field can be one of the following:

      +
    • label: label lightgbm learn from ;

    • +
    • weight: to do a weight rescale ;

    • +
    • init_score: initial score is the base prediction lightgbm will boost from ;

    • +
    • group.

    • +
    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) +lgb.Dataset.construct(dtrain) + +labels <- lightgbm::getinfo(dtrain, "label") +lightgbm::setinfo(dtrain, "label", 1 - labels) + +labels2 <- lightgbm::getinfo(dtrain, "label") +stopifnot(all.equal(labels2, 1 - labels))
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/docs/reference/slice.html b/R-package/docs/reference/slice.html new file mode 100644 index 000000000000..5aec77639d2d --- /dev/null +++ b/R-package/docs/reference/slice.html @@ -0,0 +1,193 @@ + + + + + + + + +Slice a dataset — slice • lightgbm + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + +

    Get a new lgb.Dataset containing the specified rows of +orginal lgb.Dataset object

    + + +
    slice(dataset, ...)
    +
    +# S3 method for lgb.Dataset
    +slice(dataset, idxset, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + +
    dataset

    Object of class "lgb.Dataset"

    ...

    other parameters (currently not used)

    idxset

    a integer vector of indices of rows needed

    + +

    Value

    + +

    constructed sub dataset

    + + +

    Examples

    +
    library(lightgbm) +data(agaricus.train, package = "lightgbm") +train <- agaricus.train +dtrain <- lgb.Dataset(train$data, label = train$label) + +dsub <- lightgbm::slice(dtrain, 1:42) +labels <- lightgbm::getinfo(dsub, "label")
    +
    +
    + +
    + + +
    + + + diff --git a/R-package/pkgdown/_pkgdown.yml b/R-package/pkgdown/_pkgdown.yml new file mode 100644 index 000000000000..7e9115617733 --- /dev/null +++ b/R-package/pkgdown/_pkgdown.yml @@ -0,0 +1,120 @@ +template: + params: + bootswatch: united + +authors: + Guolin Ke: + href: https://github.com/guolinke + html: Guolin Ke + Damien Soukhavong: + href: https://github.com/Laurae2 + html: Damien Soukhavong + Yachen Yan: + href: https://github.com/yanyachen + html: Yachen Yan + +site: + root: '' + title: LightGBM, Light Gradient Boosting Machine + +reference: + - title: Dataset + desc: Datasets included with the R package + contents: + - '`agaricus.test`' + - '`agaricus.train`' + - '`bank`' + - title: Data Input / Output + desc: Data I/O required for LightGBM + contents: + - '`dim.lgb.Dataset`' + - '`dimnames.lgb.Dataset`' + - '`getinfo`' + - '`setinfo`' + - '`slice`' + - '`lgb.Dataset.construct`' + - '`lgb.Dataset.create.valid`' + - '`lgb.Dataset`' + - '`lgb.Dataset.save`' + - '`lgb.Dataset.set.categorical`' + - '`lgb.Dataset.set.reference`' + - title: Machine Learning + desc: Train models with LightGBM + contents: + - '`lgb.prepare`' + - '`lgb.prepare2`' + - '`lgb.prepare_rules`' + - '`lgb.prepare_rules2`' + - '`lgb.cv`' + - '`lgb.train`' + - title: Saving / Loading Models + desc: Save and Load LightGBM models + contents: + - '`lgb.dump`' + - '`lgb.load`' + - '`lgb.model.dt.tree`' + - '`lgb.save`' + - '`predict.lgb.Booster`' + - '`readRDS.lgb.Booster`' + - '`saveRDS.lgb.Booster`' + - title: Predictive Analysis + desc: Analyze your predictions + contents: + - '`lgb.get.eval.result`' + - '`lgb.importance`' + - '`lgb.interprete`' + - '`lgb.plot.importance`' + - '`lgb.plot.interpretation`' + - title: Miscellaneous + desc: Ungroupable functions to troubleshoot LightGBM + contents: + - '`lgb.unloader`' + +navbar: + title: LightGBM + type: default + left: + - icon: fa-home fa-lg + href: index.html + - text: Reference + href: reference/index.html + - text: Vignettes + menu: + - text: Basic Walkthrough + href: articles/basic_walkthrough.html + - text: Boosting from existing prediction + href: articles/boost_from_prediction.html + - text: Categorical Feature Preparation + href: articles/categorical_features_prepare.html + - text: Categorical Feature Preparation with Rule + href: articles/categorical_features_rules.html + - text: Cross Validation + href: articles/cross_validation.html + - text: Early Stop in training + href: articles/early_stopping.html + - text: Efficiency for Many Model Trainings + href: articles/efficient_many_training.html + - text: Leaf (in)Stability example + href: articles/leaf_stability.html + - text: Multiclass training/prediction + href: articles/multiclass.html + - text: Weight-Parameter adjustment relationship + href: articles/weight_param.html + right: + - icon: fa-github fa-lg + href: https://github.com/Microsoft/LightGBM + +articles: +- title: Vignettes + desc: ~ + contents: + - '`basic_walkthrough`' + - '`boost_from_prediction`' + - '`categorical_features_prepare`' + - '`categorical_features_rules`' + - '`cross_validation`' + - '`early_stopping`' + - '`efficient_many_training`' + - '`leaf_stability`' + - '`multiclass`' + - '`weight_param`' diff --git a/R-package/pkgdown/doc_gen.R b/R-package/pkgdown/doc_gen.R new file mode 100644 index 000000000000..f44f0307e514 --- /dev/null +++ b/R-package/pkgdown/doc_gen.R @@ -0,0 +1,19 @@ +# Load useful libraries for development +library(devtools) +library(roxygen2) # devtools::install_github("klutometis/roxygen") +library(pkgdown) # devtools::install_github("Laurae2/pkgdown") # devtools::install_github("hadley/pkgdown") + +# Set the working directory to where I am +# setwd("E:/GitHub/LightGBM/R-package") + +# Generate documentation +document() + +# Check for errors +devtools::check(document = FALSE) + +# Build static website +pkgdown::build_site(run_dont_run = TRUE) + +# Install package +install() diff --git a/R-package/vignettes/basic_walkthrough.Rmd b/R-package/vignettes/basic_walkthrough.Rmd index 06cc279e1a48..9b3ed224d031 100644 --- a/R-package/vignettes/basic_walkthrough.Rmd +++ b/R-package/vignettes/basic_walkthrough.Rmd @@ -1,5 +1,5 @@ --- -title: "basic_walkthrough" +title: "Basic Walkthrough" output: html_document --- diff --git a/R-package/vignettes/efficient_many_training.Rmd b/R-package/vignettes/efficient_many_training.Rmd index 5ba837b2bb7f..7f1ffb9b3211 100644 --- a/R-package/vignettes/efficient_many_training.Rmd +++ b/R-package/vignettes/efficient_many_training.Rmd @@ -14,7 +14,7 @@ output: html_document # Just doing reset=TRUE will already improve things: OS reports 4.6GB. # Doing reset=TRUE and calling gc() in the loop will have OS 1.3GB. Thanks for the latest tip." -# 2017-12-25 example patch: use the "small" switch to make it bigger. +# 2018-01-21 example patch: use the "small" switch to make it bigger. small <- TRUE @@ -34,8 +34,8 @@ data$construct() # It MUST remain constant (if not increasing very slightly) gbm <- list() -for (i in 1:(ifelse(small, 100, 1000)) { - print(i) +for (i in 1:(ifelse(small, 100, 1000))) { + cat(format(Sys.time(), "%a %b %d %Y %X"), ": ", i, "\n", sep = "") gbm[[i]] <- lgb.train(params = list(objective = "regression", nthread = 1), data = data, From 6f1982ad0605f35e05daa138c649faff42a7a208 Mon Sep 17 00:00:00 2001 From: Laurae Date: Tue, 23 Jan 2018 20:41:32 +0100 Subject: [PATCH 5/6] No more workaround for model crash --- R-package/R/lgb.Booster.R | 15 -- R-package/R/readRDS.lgb.Booster.R | 5 - R-package/R/saveRDS.lgb.Booster.R | 5 - R-package/demo/basic_walkthrough.R | 13 +- .../docs/articles/basic_walkthrough.html | 21 +- R-package/docs/articles/cross_validation.html | 12 +- .../articles/efficient_many_training.html | 200 +++++++++--------- R-package/docs/articles/weight_param.html | 2 +- .../docs/reference/dimnames.lgb.Dataset.html | 7 +- R-package/docs/reference/getinfo.html | 3 +- .../docs/reference/lgb.Dataset.construct.html | 2 +- R-package/docs/reference/lgb.Dataset.html | 5 +- .../docs/reference/lgb.Dataset.save.html | 2 +- .../lgb.Dataset.set.categorical.html | 3 +- R-package/docs/reference/lgb.dump.html | 14 +- .../docs/reference/lgb.get.eval.result.html | 16 +- R-package/docs/reference/lgb.importance.html | 7 +- R-package/docs/reference/lgb.interprete.html | 6 +- R-package/docs/reference/lgb.load.html | 12 +- .../docs/reference/lgb.model.dt.tree.html | 6 +- .../docs/reference/lgb.plot.importance.html | 7 +- .../reference/lgb.plot.interpretation.html | 7 +- R-package/docs/reference/lgb.save.html | 21 +- R-package/docs/reference/lgb.unloader.html | 4 +- .../docs/reference/predict.lgb.Booster.html | 21 +- .../docs/reference/readRDS.lgb.Booster.html | 23 +- .../docs/reference/saveRDS.lgb.Booster.html | 21 +- R-package/docs/reference/slice.html | 2 +- R-package/man/lgb.load.Rd | 5 - R-package/man/lgb.save.Rd | 5 - R-package/man/predict.lgb.Booster.Rd | 5 - R-package/man/readRDS.lgb.Booster.Rd | 5 - R-package/man/saveRDS.lgb.Booster.Rd | 5 - R-package/vignettes/basic_walkthrough.Rmd | 19 +- src/boosting/gbdt_model_text.cpp | 2 +- 35 files changed, 212 insertions(+), 296 deletions(-) diff --git a/R-package/R/lgb.Booster.R b/R-package/R/lgb.Booster.R index f5536abccc74..1774d4e3874e 100644 --- a/R-package/R/lgb.Booster.R +++ b/R-package/R/lgb.Booster.R @@ -625,9 +625,6 @@ Booster <- R6Class( #' #' @examples #' \dontrun{ -#' # It crashes the documentation generation, skipping -#' if (!(pkgdown::in_pkgdown())) { -#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -647,8 +644,6 @@ Booster <- R6Class( #' preds <- predict(model, test$data) #' } #' -#' } -#' #' @rdname predict.lgb.Booster #' @export predict.lgb.Booster <- function(object, data, @@ -685,9 +680,6 @@ predict.lgb.Booster <- function(object, data, #' #' @examples #' \dontrun{ -#' # It crashes the documentation generation, skipping -#' if (!(pkgdown::in_pkgdown())) { -#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -710,8 +702,6 @@ predict.lgb.Booster <- function(object, data, #' load_booster_from_str <- lgb.load(model_str = model_string) #' } #' -#' } -#' #' @rdname lgb.load #' @export lgb.load <- function(filename = NULL, model_str = NULL){ @@ -750,9 +740,6 @@ lgb.load <- function(filename = NULL, model_str = NULL){ #' #' @examples #' \dontrun{ -#' # It crashes the documentation generation, skipping -#' if (!(pkgdown::in_pkgdown())) { -#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -772,8 +759,6 @@ lgb.load <- function(filename = NULL, model_str = NULL){ #' lgb.save(model, "model.txt") #' } #' -#' } -#' #' @rdname lgb.save #' @export lgb.save <- function(booster, filename, num_iteration = NULL){ diff --git a/R-package/R/readRDS.lgb.Booster.R b/R-package/R/readRDS.lgb.Booster.R index 52a3dd16c3d8..e001800dea97 100644 --- a/R-package/R/readRDS.lgb.Booster.R +++ b/R-package/R/readRDS.lgb.Booster.R @@ -9,9 +9,6 @@ #' #' @examples #' \dontrun{ -#' # It crashes the documentation generation, skipping -#' if (!(pkgdown::in_pkgdown())) { -#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -32,8 +29,6 @@ #' new_model <- readRDS.lgb.Booster("model.rds") #' } #' -#' } -#' #' @export readRDS.lgb.Booster <- function(file = "", refhook = NULL) { diff --git a/R-package/R/saveRDS.lgb.Booster.R b/R-package/R/saveRDS.lgb.Booster.R index 6e2f25503904..97083763bff8 100644 --- a/R-package/R/saveRDS.lgb.Booster.R +++ b/R-package/R/saveRDS.lgb.Booster.R @@ -14,9 +14,6 @@ #' #' @examples #' \dontrun{ -#' # It crashes the documentation generation, skipping -#' if (!(pkgdown::in_pkgdown())) { -#' #' library(lightgbm) #' data(agaricus.train, package = "lightgbm") #' train <- agaricus.train @@ -36,8 +33,6 @@ #' saveRDS.lgb.Booster(model, "model.rds") #' } #' -#' } -#' #' @export saveRDS.lgb.Booster <- function(object, file = "", diff --git a/R-package/demo/basic_walkthrough.R b/R-package/demo/basic_walkthrough.R index d799b839a4fb..b1362e7af28b 100644 --- a/R-package/demo/basic_walkthrough.R +++ b/R-package/demo/basic_walkthrough.R @@ -86,16 +86,11 @@ err <- mean(as.numeric(pred > 0.5) != test$label) print(paste("test-error=", err)) #--------------------Save and load models------------------------- +# Save model to binary local file +lgb.save(bst, "lightgbm.model") -if (!(pkgdown::in_pkgdown())) { - # Save model to binary local file - lgb.save(bst, "lightgbm.model") - - # Load binary model to R - bst2 <- lgb.load("lightgbm.model") -} else { - bst2 <- bst -} +# Load binary model to R +bst2 <- lgb.load("lightgbm.model") pred2 <- predict(bst2, test$data) # pred2 should be identical to pred diff --git a/R-package/docs/articles/basic_walkthrough.html b/R-package/docs/articles/basic_walkthrough.html index 6dee21a57a31..a42af49fe78e 100644 --- a/R-package/docs/articles/basic_walkthrough.html +++ b/R-package/docs/articles/basic_walkthrough.html @@ -209,19 +209,16 @@

    Basic Walkthrough

    ## [1] "test-error= 0.0217256362507759"
    #--------------------Save and load models-------------------------
     # Save model to binary local file
    -# Crash temporary workaround for pkgdown
    -if (!(pkgdown::in_pkgdown())) {
    -  lgb.save(bst, "lightgbm.model")
    -  
    -  # Load binary model to R
    -  bst2 <- lgb.load("lightgbm.model")
    -  pred2 <- predict(bst2, test$data)
    -  
    -  # pred2 should be identical to pred
    -  print(paste("sum(abs(pred2-pred))=", sum(abs(pred2 - pred))))
    -}
    +lgb.save(bst, "lightgbm.model")
     
    -#--------------------Advanced features ---------------------------
    +# Load binary model to R
    +bst2 <- lgb.load("lightgbm.model")
    +pred2 <- predict(bst2, test$data)
    +
    +# pred2 should be identical to pred
    +print(paste("sum(abs(pred2-pred))=", sum(abs(pred2 - pred))))
    +
    ## [1] "sum(abs(pred2-pred))= 0"
    +
    #--------------------Advanced features ---------------------------
     # To use advanced features, we need to put data in lgb.Dataset
     dtrain <- lgb.Dataset(data = train$data, label = train$label, free_raw_data = FALSE)
     dtest <- lgb.Dataset(data = test$data, label = test$label, free_raw_data = FALSE)
    diff --git a/R-package/docs/articles/cross_validation.html b/R-package/docs/articles/cross_validation.html
    index 14c35274583a..532ce1106f2f 100644
    --- a/R-package/docs/articles/cross_validation.html
    +++ b/R-package/docs/articles/cross_validation.html
    @@ -129,8 +129,8 @@ 

    Cross Validation

    nfold = 5, eval = "binary_error")
    ## Loading required package: Matrix
    -
    ## [1]: valid's binary_error:0.0304007+0.00390108 
    -## [2]: valid's binary_error:0.0222629+0.00431306
    +
    ## [1]: valid's binary_error:0.0304001+0.00491304 
    +## [2]: valid's binary_error:0.0222626+0.00298825
    ## <lgb.CVBooster>
     ##   Public:
     ##     best_iter: -1
    @@ -150,8 +150,8 @@ 

    Cross Validation

    nfold = 5, eval = "binary_error", showsd = FALSE)
  • -
    ## [1]: valid's binary_error:0.0304012 
    -## [2]: valid's binary_error:0.0222635
    +
    ## [1]: valid's binary_error:0.030401 
    +## [2]: valid's binary_error:0.0222636
    ## <lgb.CVBooster>
     ##   Public:
     ##     best_iter: -1
    @@ -183,8 +183,8 @@ 

    Cross Validation

    obj = logregobj, eval = evalerror, nfold = 5)
    -
    ## [1]: valid's error:0.0304005+0.0036178 
    -## [2]: valid's error:0.0222632+0.00431487
    +
    ## [1]: valid's error:0.0304002+0.00164458 
    +## [2]: valid's error:0.0222625+0.00193436
    ## <lgb.CVBooster>
     ##   Public:
     ##     best_iter: -1
    diff --git a/R-package/docs/articles/efficient_many_training.html b/R-package/docs/articles/efficient_many_training.html
    index c84b9d246d13..68cb2a778c4c 100644
    --- a/R-package/docs/articles/efficient_many_training.html
    +++ b/R-package/docs/articles/efficient_many_training.html
    @@ -142,106 +142,106 @@ 

    Efficiency for Many Model Trainings

    reset_data = TRUE) gc(verbose = FALSE) }
    -
    ## Sun Jan 21 2018 03:49:55 PM: 1
    -## Sun Jan 21 2018 03:49:55 PM: 2
    -## Sun Jan 21 2018 03:49:55 PM: 3
    -## Sun Jan 21 2018 03:49:55 PM: 4
    -## Sun Jan 21 2018 03:49:55 PM: 5
    -## Sun Jan 21 2018 03:49:55 PM: 6
    -## Sun Jan 21 2018 03:49:55 PM: 7
    -## Sun Jan 21 2018 03:49:55 PM: 8
    -## Sun Jan 21 2018 03:49:55 PM: 9
    -## Sun Jan 21 2018 03:49:55 PM: 10
    -## Sun Jan 21 2018 03:49:55 PM: 11
    -## Sun Jan 21 2018 03:49:56 PM: 12
    -## Sun Jan 21 2018 03:49:56 PM: 13
    -## Sun Jan 21 2018 03:49:56 PM: 14
    -## Sun Jan 21 2018 03:49:56 PM: 15
    -## Sun Jan 21 2018 03:49:56 PM: 16
    -## Sun Jan 21 2018 03:49:56 PM: 17
    -## Sun Jan 21 2018 03:49:56 PM: 18
    -## Sun Jan 21 2018 03:49:56 PM: 19
    -## Sun Jan 21 2018 03:49:56 PM: 20
    -## Sun Jan 21 2018 03:49:56 PM: 21
    -## Sun Jan 21 2018 03:49:56 PM: 22
    -## Sun Jan 21 2018 03:49:56 PM: 23
    -## Sun Jan 21 2018 03:49:56 PM: 24
    -## Sun Jan 21 2018 03:49:56 PM: 25
    -## Sun Jan 21 2018 03:49:56 PM: 26
    -## Sun Jan 21 2018 03:49:56 PM: 27
    -## Sun Jan 21 2018 03:49:56 PM: 28
    -## Sun Jan 21 2018 03:49:56 PM: 29
    -## Sun Jan 21 2018 03:49:56 PM: 30
    -## Sun Jan 21 2018 03:49:57 PM: 31
    -## Sun Jan 21 2018 03:49:57 PM: 32
    -## Sun Jan 21 2018 03:49:57 PM: 33
    -## Sun Jan 21 2018 03:49:57 PM: 34
    -## Sun Jan 21 2018 03:49:57 PM: 35
    -## Sun Jan 21 2018 03:49:57 PM: 36
    -## Sun Jan 21 2018 03:49:57 PM: 37
    -## Sun Jan 21 2018 03:49:57 PM: 38
    -## Sun Jan 21 2018 03:49:57 PM: 39
    -## Sun Jan 21 2018 03:49:57 PM: 40
    -## Sun Jan 21 2018 03:49:57 PM: 41
    -## Sun Jan 21 2018 03:49:57 PM: 42
    -## Sun Jan 21 2018 03:49:57 PM: 43
    -## Sun Jan 21 2018 03:49:57 PM: 44
    -## Sun Jan 21 2018 03:49:57 PM: 45
    -## Sun Jan 21 2018 03:49:57 PM: 46
    -## Sun Jan 21 2018 03:49:57 PM: 47
    -## Sun Jan 21 2018 03:49:57 PM: 48
    -## Sun Jan 21 2018 03:49:57 PM: 49
    -## Sun Jan 21 2018 03:49:57 PM: 50
    -## Sun Jan 21 2018 03:49:58 PM: 51
    -## Sun Jan 21 2018 03:49:58 PM: 52
    -## Sun Jan 21 2018 03:49:58 PM: 53
    -## Sun Jan 21 2018 03:49:58 PM: 54
    -## Sun Jan 21 2018 03:49:58 PM: 55
    -## Sun Jan 21 2018 03:49:58 PM: 56
    -## Sun Jan 21 2018 03:49:58 PM: 57
    -## Sun Jan 21 2018 03:49:58 PM: 58
    -## Sun Jan 21 2018 03:49:58 PM: 59
    -## Sun Jan 21 2018 03:49:58 PM: 60
    -## Sun Jan 21 2018 03:49:58 PM: 61
    -## Sun Jan 21 2018 03:49:58 PM: 62
    -## Sun Jan 21 2018 03:49:58 PM: 63
    -## Sun Jan 21 2018 03:49:58 PM: 64
    -## Sun Jan 21 2018 03:49:58 PM: 65
    -## Sun Jan 21 2018 03:49:58 PM: 66
    -## Sun Jan 21 2018 03:49:58 PM: 67
    -## Sun Jan 21 2018 03:49:58 PM: 68
    -## Sun Jan 21 2018 03:49:59 PM: 69
    -## Sun Jan 21 2018 03:49:59 PM: 70
    -## Sun Jan 21 2018 03:49:59 PM: 71
    -## Sun Jan 21 2018 03:49:59 PM: 72
    -## Sun Jan 21 2018 03:49:59 PM: 73
    -## Sun Jan 21 2018 03:49:59 PM: 74
    -## Sun Jan 21 2018 03:49:59 PM: 75
    -## Sun Jan 21 2018 03:49:59 PM: 76
    -## Sun Jan 21 2018 03:49:59 PM: 77
    -## Sun Jan 21 2018 03:49:59 PM: 78
    -## Sun Jan 21 2018 03:49:59 PM: 79
    -## Sun Jan 21 2018 03:49:59 PM: 80
    -## Sun Jan 21 2018 03:49:59 PM: 81
    -## Sun Jan 21 2018 03:49:59 PM: 82
    -## Sun Jan 21 2018 03:49:59 PM: 83
    -## Sun Jan 21 2018 03:49:59 PM: 84
    -## Sun Jan 21 2018 03:49:59 PM: 85
    -## Sun Jan 21 2018 03:49:59 PM: 86
    -## Sun Jan 21 2018 03:49:59 PM: 87
    -## Sun Jan 21 2018 03:50:00 PM: 88
    -## Sun Jan 21 2018 03:50:00 PM: 89
    -## Sun Jan 21 2018 03:50:00 PM: 90
    -## Sun Jan 21 2018 03:50:00 PM: 91
    -## Sun Jan 21 2018 03:50:00 PM: 92
    -## Sun Jan 21 2018 03:50:00 PM: 93
    -## Sun Jan 21 2018 03:50:00 PM: 94
    -## Sun Jan 21 2018 03:50:00 PM: 95
    -## Sun Jan 21 2018 03:50:00 PM: 96
    -## Sun Jan 21 2018 03:50:00 PM: 97
    -## Sun Jan 21 2018 03:50:00 PM: 98
    -## Sun Jan 21 2018 03:50:00 PM: 99
    -## Sun Jan 21 2018 03:50:00 PM: 100
    +
    ## Tue Jan 23 2018 08:38:50 PM: 1
    +## Tue Jan 23 2018 08:38:50 PM: 2
    +## Tue Jan 23 2018 08:38:50 PM: 3
    +## Tue Jan 23 2018 08:38:50 PM: 4
    +## Tue Jan 23 2018 08:38:50 PM: 5
    +## Tue Jan 23 2018 08:38:51 PM: 6
    +## Tue Jan 23 2018 08:38:51 PM: 7
    +## Tue Jan 23 2018 08:38:51 PM: 8
    +## Tue Jan 23 2018 08:38:51 PM: 9
    +## Tue Jan 23 2018 08:38:51 PM: 10
    +## Tue Jan 23 2018 08:38:51 PM: 11
    +## Tue Jan 23 2018 08:38:51 PM: 12
    +## Tue Jan 23 2018 08:38:51 PM: 13
    +## Tue Jan 23 2018 08:38:51 PM: 14
    +## Tue Jan 23 2018 08:38:51 PM: 15
    +## Tue Jan 23 2018 08:38:51 PM: 16
    +## Tue Jan 23 2018 08:38:51 PM: 17
    +## Tue Jan 23 2018 08:38:51 PM: 18
    +## Tue Jan 23 2018 08:38:51 PM: 19
    +## Tue Jan 23 2018 08:38:51 PM: 20
    +## Tue Jan 23 2018 08:38:52 PM: 21
    +## Tue Jan 23 2018 08:38:52 PM: 22
    +## Tue Jan 23 2018 08:38:52 PM: 23
    +## Tue Jan 23 2018 08:38:52 PM: 24
    +## Tue Jan 23 2018 08:38:52 PM: 25
    +## Tue Jan 23 2018 08:38:52 PM: 26
    +## Tue Jan 23 2018 08:38:52 PM: 27
    +## Tue Jan 23 2018 08:38:52 PM: 28
    +## Tue Jan 23 2018 08:38:52 PM: 29
    +## Tue Jan 23 2018 08:38:52 PM: 30
    +## Tue Jan 23 2018 08:38:52 PM: 31
    +## Tue Jan 23 2018 08:38:52 PM: 32
    +## Tue Jan 23 2018 08:38:52 PM: 33
    +## Tue Jan 23 2018 08:38:52 PM: 34
    +## Tue Jan 23 2018 08:38:52 PM: 35
    +## Tue Jan 23 2018 08:38:52 PM: 36
    +## Tue Jan 23 2018 08:38:52 PM: 37
    +## Tue Jan 23 2018 08:38:53 PM: 38
    +## Tue Jan 23 2018 08:38:53 PM: 39
    +## Tue Jan 23 2018 08:38:53 PM: 40
    +## Tue Jan 23 2018 08:38:53 PM: 41
    +## Tue Jan 23 2018 08:38:53 PM: 42
    +## Tue Jan 23 2018 08:38:53 PM: 43
    +## Tue Jan 23 2018 08:38:53 PM: 44
    +## Tue Jan 23 2018 08:38:53 PM: 45
    +## Tue Jan 23 2018 08:38:53 PM: 46
    +## Tue Jan 23 2018 08:38:53 PM: 47
    +## Tue Jan 23 2018 08:38:53 PM: 48
    +## Tue Jan 23 2018 08:38:53 PM: 49
    +## Tue Jan 23 2018 08:38:53 PM: 50
    +## Tue Jan 23 2018 08:38:53 PM: 51
    +## Tue Jan 23 2018 08:38:53 PM: 52
    +## Tue Jan 23 2018 08:38:54 PM: 53
    +## Tue Jan 23 2018 08:38:54 PM: 54
    +## Tue Jan 23 2018 08:38:54 PM: 55
    +## Tue Jan 23 2018 08:38:54 PM: 56
    +## Tue Jan 23 2018 08:38:54 PM: 57
    +## Tue Jan 23 2018 08:38:54 PM: 58
    +## Tue Jan 23 2018 08:38:54 PM: 59
    +## Tue Jan 23 2018 08:38:54 PM: 60
    +## Tue Jan 23 2018 08:38:54 PM: 61
    +## Tue Jan 23 2018 08:38:54 PM: 62
    +## Tue Jan 23 2018 08:38:54 PM: 63
    +## Tue Jan 23 2018 08:38:54 PM: 64
    +## Tue Jan 23 2018 08:38:54 PM: 65
    +## Tue Jan 23 2018 08:38:54 PM: 66
    +## Tue Jan 23 2018 08:38:54 PM: 67
    +## Tue Jan 23 2018 08:38:55 PM: 68
    +## Tue Jan 23 2018 08:38:55 PM: 69
    +## Tue Jan 23 2018 08:38:55 PM: 70
    +## Tue Jan 23 2018 08:38:55 PM: 71
    +## Tue Jan 23 2018 08:38:55 PM: 72
    +## Tue Jan 23 2018 08:38:55 PM: 73
    +## Tue Jan 23 2018 08:38:55 PM: 74
    +## Tue Jan 23 2018 08:38:55 PM: 75
    +## Tue Jan 23 2018 08:38:55 PM: 76
    +## Tue Jan 23 2018 08:38:55 PM: 77
    +## Tue Jan 23 2018 08:38:55 PM: 78
    +## Tue Jan 23 2018 08:38:55 PM: 79
    +## Tue Jan 23 2018 08:38:55 PM: 80
    +## Tue Jan 23 2018 08:38:55 PM: 81
    +## Tue Jan 23 2018 08:38:55 PM: 82
    +## Tue Jan 23 2018 08:38:55 PM: 83
    +## Tue Jan 23 2018 08:38:55 PM: 84
    +## Tue Jan 23 2018 08:38:56 PM: 85
    +## Tue Jan 23 2018 08:38:56 PM: 86
    +## Tue Jan 23 2018 08:38:56 PM: 87
    +## Tue Jan 23 2018 08:38:56 PM: 88
    +## Tue Jan 23 2018 08:38:56 PM: 89
    +## Tue Jan 23 2018 08:38:56 PM: 90
    +## Tue Jan 23 2018 08:38:56 PM: 91
    +## Tue Jan 23 2018 08:38:56 PM: 92
    +## Tue Jan 23 2018 08:38:56 PM: 93
    +## Tue Jan 23 2018 08:38:56 PM: 94
    +## Tue Jan 23 2018 08:38:56 PM: 95
    +## Tue Jan 23 2018 08:38:56 PM: 96
    +## Tue Jan 23 2018 08:38:56 PM: 97
    +## Tue Jan 23 2018 08:38:56 PM: 98
    +## Tue Jan 23 2018 08:38:56 PM: 99
    +## Tue Jan 23 2018 08:38:56 PM: 100
    diff --git a/R-package/docs/articles/weight_param.html b/R-package/docs/articles/weight_param.html index e6a599874633..541d2e2010a5 100644 --- a/R-package/docs/articles/weight_param.html +++ b/R-package/docs/articles/weight_param.html @@ -215,7 +215,7 @@

    Weight-Parameter adjustment relationship

    ## [36]: test's l2:6.27259e-06 ## [37]: test's l2:5.7322e-06 ## [38]: test's l2:5.22595e-06 -## [39]: test's l2:6.30649e-06 +## [39]: test's l2:6.3065e-06 ## [40]: test's l2:5.44453e-06 ## [41]: test's l2:4.76803e-06 ## [42]: test's l2:4.57209e-06 diff --git a/R-package/docs/reference/dimnames.lgb.Dataset.html b/R-package/docs/reference/dimnames.lgb.Dataset.html index 83ab70307577..ea727b454a88 100644 --- a/R-package/docs/reference/dimnames.lgb.Dataset.html +++ b/R-package/docs/reference/dimnames.lgb.Dataset.html @@ -158,8 +158,7 @@

    Examp data(agaricus.train, package = "lightgbm") train <- agaricus.train dtrain <- lgb.Dataset(train$data, label = train$label) -lgb.Dataset.construct(dtrain) -dimnames(dtrain)
    #> [[1]] +lgb.Dataset.construct(dtrain)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    dimnames(dtrain)
    #> [[1]] #> NULL #> #> [[2]] @@ -310,11 +309,11 @@

    Examp #> colnames: X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X ... #> free_raw_data: TRUE #> get_handle: function () -#> handle: 7.32442438646731e-318 +#> handle: NULL #> info: list #> params: list #> predictor: NULL -#> raw_data: NULL +#> raw_data: dgCMatrix #> reference: NULL #> set_predictor: function (predictor) #> used_indices: NULL

    diff --git a/R-package/docs/reference/getinfo.html b/R-package/docs/reference/getinfo.html index 8cec9f127b98..5ccc1e734dde 100644 --- a/R-package/docs/reference/getinfo.html +++ b/R-package/docs/reference/getinfo.html @@ -167,8 +167,7 @@

    Examp data(agaricus.train, package = "lightgbm") train <- agaricus.train dtrain <- lgb.Dataset(train$data, label = train$label) -lgb.Dataset.construct(dtrain) - +lgb.Dataset.construct(dtrain)

    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    labels <- lightgbm::getinfo(dtrain, "label") lightgbm::setinfo(dtrain, "label", 1 - labels) diff --git a/R-package/docs/reference/lgb.Dataset.construct.html b/R-package/docs/reference/lgb.Dataset.construct.html index d2af98742943..07cddef1377f 100644 --- a/R-package/docs/reference/lgb.Dataset.construct.html +++ b/R-package/docs/reference/lgb.Dataset.construct.html @@ -143,7 +143,7 @@

    Examp data(agaricus.train, package = "lightgbm") train <- agaricus.train dtrain <- lgb.Dataset(train$data, label = train$label) -lgb.Dataset.construct(dtrain)

    +lgb.Dataset.construct(dtrain)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    +lgb.Dataset.save(dtrain, "lgb.Dataset.data")
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    dtrain <- lgb.Dataset("lgb.Dataset.data") +lgb.Dataset.construct(dtrain)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromFile_R" not available for .Call() for package "lib_lightgbm"
    +lgb.Dataset.save(dtrain, "data.bin")
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    dtrain <- lgb.Dataset("lgb.Dataset.data") lgb.Dataset.set.categorical(dtrain, 1:2)
    diff --git a/R-package/docs/reference/lgb.dump.html b/R-package/docs/reference/lgb.dump.html index 953bc1eac623..d9fd185005e0 100644 --- a/R-package/docs/reference/lgb.dump.html +++ b/R-package/docs/reference/lgb.dump.html @@ -162,19 +162,7 @@

    Examp valids, min_data = 1, learning_rate = 1, - early_stopping_rounds = 10)
    #> [1]: test's l2:6.44165e-17 -#> [2]: test's l2:1.97215e-31 -#> [3]: test's l2:0 -#> [4]: test's l2:0 -#> [5]: test's l2:0 -#> [6]: test's l2:0 -#> [7]: test's l2:0 -#> [8]: test's l2:0 -#> [9]: test's l2:0 -#> [10]: test's l2:0 -#> [11]: test's l2:0 -#> [12]: test's l2:0 -#> [13]: test's l2:0
    json_model <- lgb.dump(model)
    + early_stopping_rounds = 10)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    json_model <- lgb.dump(model)
    #> Error in c("R6", name) %in% class(object): object 'model' not found
    #> [1]: test's l2:6.44165e-17 -#> [2]: test's l2:1.97215e-31 -#> [3]: test's l2:0 -#> [4]: test's l2:0 -#> [5]: test's l2:0 -#> [6]: test's l2:0 -#> [7]: test's l2:0 -#> [8]: test's l2:0 -#> [9]: test's l2:0 -#> [10]: test's l2:0 -#> [11]: test's l2:0 -#> [12]: test's l2:0 -#> [13]: test's l2:0
    lgb.get.eval.result(model, "test", "l2")
    #> [1] 6.441652e-17 1.972152e-31 0.000000e+00 0.000000e+00 0.000000e+00 -#> [6] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 -#> [11] 0.000000e+00 0.000000e+00 0.000000e+00
    + early_stopping_rounds = 10)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    lgb.get.eval.result(model, "test", "l2")
    #> Error in c("R6", name) %in% class(object): object 'model' not found
    + model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    +tree_imp1 <- lgb.importance(model, percentage = TRUE)
    #> Error in inherits(model, "lgb.Booster"): object 'model' not found
    tree_imp2 <- lgb.importance(model, percentage = FALSE)
    #> Error in lgb.importance(model, percentage = FALSE): object 'model' not found
    + model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    +tree_interpretation <- lgb.interprete(model, test$data, 1:5)
    #> Error in c("R6", name) %in% class(object): object 'model' not found
    + model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    +tree_imp <- lgb.importance(model, percentage = TRUE)
    #> Error in lgb.importance(model, percentage = TRUE): object 'model' not found
    lgb.plot.importance(tree_imp, top_n = 10, measure = "Gain")
    #> Error in nrow(tree_imp): object 'tree_imp' not found
    + model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    model <- lgb.train(params, dtrain, 20)
    #> Error in .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm"): "LGBM_DatasetCreateFromCSC_R" not available for .Call() for package "lib_lightgbm"
    +tree_interpretation <- lgb.interprete(model, test$data, 1:5)
    #> Error in c("R6", name) %in% class(object): object 'model' not found
    lgb.plot.interpretation(tree_interpretation[[1]], top_n = 10)
    #> Error in ncol(tree_interpretation_dt): object 'tree_interpretation' not found

    +
    + + + +
    +
    + + + + +
    +
    require(lightgbm)
    +
    ## Loading required package: lightgbm
    +
    ## Loading required package: R6
    +
    # We load the default iris dataset shipped with R
    +data(iris)
    +
    +# We must convert factors to numeric
    +# They must be starting from number 0 to use multiclass
    +# For instance: 0, 1, 2, 3, 4, 5...
    +iris$Species <- as.numeric(as.factor(iris$Species)) - 1
    +
    +# We cut the data set into 80% train and 20% validation
    +# The 10 last samples of each class are for validation
    +
    +train <- as.matrix(iris[c(1:40, 51:90, 101:140), ])
    +test <- as.matrix(iris[c(41:50, 91:100, 141:150), ])
    +dtrain <- lgb.Dataset(data = train[, 1:4], label = train[, 5])
    +dtest <- lgb.Dataset.create.valid(dtrain, data = test[, 1:4], label = test[, 5])
    +valids <- list(test = dtest)
    +
    +# Method 1 of training
    +params <- list(objective = "multiclass", metric = "multi_error", num_class = 3)
    +model <- lgb.train(params,
    +                   dtrain,
    +                   100,
    +                   valids,
    +                   min_data = 1,
    +                   learning_rate = 1,
    +                   early_stopping_rounds = 10,
    +                   nthread = 1)
    +
    ## [1]: test's multi_error:0.0333333 
    +## [2]: test's multi_error:0.0333333 
    +## [3]: test's multi_error:0.0333333 
    +## [4]: test's multi_error:0.0333333 
    +## [5]: test's multi_error:0.0333333 
    +## [6]: test's multi_error:0.0333333 
    +## [7]: test's multi_error:0.0333333 
    +## [8]: test's multi_error:0.0333333 
    +## [9]: test's multi_error:0.0333333 
    +## [10]:    test's multi_error:0.0333333 
    +## [11]:    test's multi_error:0.0333333
    +
    # We can predict on test data, outputs a 90-length vector
    +# Order: obs1 class1, obs1 class2, obs1 class3, obs2 class1, obs2 class2, obs2 class3...
    +my_preds <- predict(model, test[, 1:4])
    +
    +# Method 2 of training, identical
    +model <- lgb.train(list(),
    +                   dtrain,
    +                   100,
    +                   valids,
    +                   min_data = 1,
    +                   learning_rate = 1,
    +                   early_stopping_rounds = 10,
    +                   objective = "multiclass",
    +                   metric = "multi_error",
    +                   num_class = 3,
    +                   nthread = 1)
    +
    ## [1]: test's multi_error:0.0333333 
    +## [2]: test's multi_error:0.0333333 
    +## [3]: test's multi_error:0.0333333 
    +## [4]: test's multi_error:0.0333333 
    +## [5]: test's multi_error:0.0333333 
    +## [6]: test's multi_error:0.0333333 
    +## [7]: test's multi_error:0.0333333 
    +## [8]: test's multi_error:0.0333333 
    +## [9]: test's multi_error:0.0333333 
    +## [10]:    test's multi_error:0.0333333 
    +## [11]:    test's multi_error:0.0333333
    +
    # We can predict on test data, identical
    +my_preds <- predict(model, test[, 1:4])
    +
    +# A (30x3) matrix with the predictions, use parameter reshape
    +# class1 class2 class3
    +#   obs1   obs1   obs1
    +#   obs2   obs2   obs2
    +#   ....   ....   ....
    +my_preds <- predict(model, test[, 1:4], reshape = TRUE)
    +
    +# We can also get the predicted scores before the Sigmoid/Softmax application
    +my_preds <- predict(model, test[, 1:4], rawscore = TRUE)
    +
    +# Raw score predictions as matrix instead of vector
    +my_preds <- predict(model, test[, 1:4], rawscore = TRUE, reshape = TRUE)
    +
    +# We can also get the leaf index
    +my_preds <- predict(model, test[, 1:4], predleaf = TRUE)
    +
    +# Predict leaf index as matrix instead of vector
    +my_preds <- predict(model, test[, 1:4], predleaf = TRUE, reshape = TRUE)
    +
    +
    + + + +
    + + + +