├── .Rbuildignore ├── .covrignore ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── app.R ├── dalex_shortcut.R ├── explain.R ├── explore.R ├── generics.R ├── helpers.R ├── kernels.R ├── live.R ├── local_perimp.R ├── plot.R ├── sampling_methods.R └── zzz.R ├── README.md ├── _pkgdown.yml ├── arepo ├── backpack.db └── gallery │ ├── 0a79acf1a27b1a2a6404f257223041e4.rda │ ├── 1025d57a48c5a037e5a56d8b1b06c1df.rda │ ├── 1f3204991d06e083f7608cd3f2acce5b.rda │ ├── 32f06fe892f0b02a756d28280b985cbd.rda │ ├── 3722f537a2cb2d78daba392d1c7e8bd7.rda │ ├── 3722f537a2cb2d78daba392d1c7e8bd7.txt │ ├── 66e9851f52186a38d5773dd5b7f1a669.rda │ ├── 66e9851f52186a38d5773dd5b7f1a669.txt │ ├── 82bfc17ccfc8f765f19926485baa5fbf.rda │ ├── e1ae768c305f1df6d89bd564ebe84003.rda │ ├── ee48c1cf298256247c7170da8048cfca.rda │ └── eebe616e0e3bae29d79416cb6e6b91ed.rda ├── codecov.yml ├── data └── wine.rda ├── docs ├── LICENSE-text.html ├── MI2logo.jpg ├── articles │ ├── HR.html │ ├── HR_files │ │ └── figure-html │ │ │ ├── unnamed-chunk-1-1.png │ │ │ ├── unnamed-chunk-1-2.png │ │ │ └── unnamed-chunk-1-3.png │ ├── TCGA.html │ ├── TCGA_files │ │ └── figure-html │ │ │ ├── libs-1.png │ │ │ └── libs-2.png │ ├── index.html │ ├── wine_quality.html │ └── wine_quality_files │ │ └── figure-html │ │ ├── forestplot-1.png │ │ ├── plot-1.png │ │ ├── plot-2.png │ │ └── waterfallplot-1.png ├── authors.html ├── index.html ├── jquery.sticky-kit.min.js ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml └── reference │ ├── add_predictions.html │ ├── add_predictions2.html │ ├── calculate_weights.html │ ├── check_conditions.html │ ├── check_for_na.html │ ├── create_task.html │ ├── euclidean_kernel.html │ ├── fit_explanation.html │ ├── fit_explanation2.html │ ├── gaussian_kernel.html │ ├── generate_neighbourhood.html │ ├── generate_neighbourhood2.html │ ├── give_predictions.html │ ├── give_predictions2.html │ ├── identity_kernel.html │ ├── index.html │ ├── live.html │ ├── live_shiny.html │ ├── local_approximation.html │ ├── local_permutation_importance.html │ ├── normal_neighbourhood.html │ ├── permutation_neighbourhood.html │ ├── plot.live_explainer.html │ ├── plot.local_permutation_importance.html │ ├── plot_explanation.html │ ├── plot_explanation2.html │ ├── plot_regression.html │ ├── plot_regression2.html │ ├── prepare_forestplot.html │ ├── print.live_explainer.html │ ├── print.live_explorer.html │ ├── print.local_permutation_importance.html │ ├── replace_items_by_rows.html │ ├── sample_locally.html │ ├── sample_locally2.html │ ├── select_variables.html │ ├── set_constant_dates.html │ ├── set_constant_variables.html │ ├── wine.html │ └── winequality_red.html ├── inst └── CITATION ├── live.Rproj ├── man ├── add_predictions.Rd ├── euclidean_kernel.Rd ├── fit_explanation.Rd ├── gaussian_kernel.Rd ├── identity_kernel.Rd ├── live.Rd ├── live_shiny.Rd ├── local_approximation.Rd ├── local_permutation_importance.Rd ├── plot.live_explainer.Rd ├── plot.local_permutation_importance.Rd ├── print.live_explainer.Rd ├── print.live_explorer.Rd ├── print.local_permutation_importance.Rd ├── sample_locally.Rd └── wine.Rd ├── tests ├── testthat.R └── testthat │ ├── test_explaining.R │ ├── test_local_varimp.R │ ├── test_shortcut.R │ └── test_simulating.R └── vignettes └── wine_quality.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^_pkgdown\.yml$ 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | ^.travis.yml 5 | ^docs$ 6 | ^arepo$ 7 | ^cheatsheet$ 8 | ^cheatsheets$ 9 | ^codecov\.yml$ 10 | \.covrignore 11 | _pkgdown.yml 12 | -------------------------------------------------------------------------------- /.covrignore: -------------------------------------------------------------------------------- 1 | R/app.R -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | inst/doc 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | warnings_are_errors: false 7 | 8 | notifications: 9 | email: false 10 | 11 | r_packages: 12 | - mlr 13 | - dplyr 14 | - forestmodel 15 | - e1071 16 | - breakDown 17 | 18 | after_success: 19 | - Rscript -e 'covr::codecov()' 20 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: live 2 | Type: Package 3 | Title: Local Interpretable (Model-Agnostic) Visual Explanations 4 | Version: 1.5.10 5 | Authors@R: c( 6 | person("Mateusz", "Staniak", role = c("cre","aut"), 7 | email = "mateusz.staniak@math.uni.wroc.pl"), 8 | person("Przemysław", "Biecek", role = "aut", 9 | email = "przemyslaw.biecek@gmail.com") 10 | ) 11 | Description: Interpretability of complex machine learning models is a growing concern. 12 | This package helps to understand key factors that drive the 13 | decision made by complicated predictive model (so called black box model). 14 | This is achieved through local approximations that are either based on 15 | additive regression like model or CART like model that allows for 16 | higher interactions. The methodology is based on Tulio Ribeiro, Singh, Guestrin (2016) . 17 | More details can be found in Staniak, Biecek (2018) . 18 | URL: https://github.com/ModelOriented/live 19 | BugReports: https://github.com/ModelOriented/live/issues 20 | License: MIT + file LICENSE 21 | Encoding: UTF-8 22 | LazyData: true 23 | RoxygenNote: 6.1.1 24 | Depends: R (>= 3.0.2), 25 | Suggests: knitr, 26 | rmarkdown, 27 | testthat, 28 | glmnet, 29 | covr, 30 | DALEX 31 | VignetteBuilder: knitr 32 | Imports: mlr, 33 | dplyr, 34 | breakDown, 35 | data.table, 36 | forestmodel, 37 | shiny, 38 | MASS, 39 | ggplot2, 40 | gower, 41 | e1071 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: Mateusz Staniak 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | import(ggplot2) 4 | import(mlr) 5 | import(shiny) 6 | importFrom(dplyr,desc) 7 | importFrom(graphics,plot) 8 | importFrom(stats,as.formula) 9 | importFrom(stats,model.matrix) 10 | importFrom(stats,predict) 11 | importFrom(stats,reorder) 12 | importFrom(stats,sd) 13 | importFrom(stats,weighted.mean) 14 | importFrom(utils,head) 15 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # live 1.5.10 2 | 3 | * Updated CITATION. 4 | * Removed unnecessary dependency. 5 | 6 | # live 1.5.9 7 | 8 | * Dropped old interface. 9 | * Improved distance calculations. 10 | * ... argument added to `plot`. 11 | 12 | # live 1.5.8 13 | 14 | * Allow setting seed before sampling in `sample_locally2` to make results reproducible. 15 | * Add new explainer: `local_permutation_importance` function. 16 | * Fixed problems with mlr dependency. 17 | * Add shortcut function for DALEX explainers: `local_approximation`. 18 | 19 | # live 1.5.7 20 | 21 | * New method of sampling ("normal"). 22 | 23 | # 1ive 1.5.6 24 | 25 | * Waterfall plots can be viewed in a Shiny app. 26 | 27 | # live 1.5.5 28 | 29 | * Fixed bug related to standardizing columns in `fit_explanation`. 30 | 31 | # live 1.5.4 32 | 33 | * Old interface dropped. 34 | 35 | # live 1.5.3 36 | 37 | * Minor fix to `euclidean_kernel` function. 38 | * Default kernel in `fit_explanation` is now `gaussian_kernel`. 39 | * Order of arguments changed in `add_predictions` and `data` arguments defaults to `NULL`. 40 | * Variables are standardized after predictions are added, before explanation model is fitted in `fit_explanation` function. 41 | 42 | # live 1.5.2 43 | 44 | * Print functions for results of sample_locally, add_predictions and fit_explanation. 45 | 46 | # live 1.5.1 47 | 48 | * New, LIME-like method of sampling as an option in `sample_locally`. 49 | 50 | # live 1.5.0 51 | 52 | * Observations in simulated dataset can now be weighted according to their distance from the explained instance. The distance is defined by `kernel` argument to `fit_explanation` function. 53 | * Some variables can be excluded from sampling. This is controled via `fixed_variables` argument to `sample_locally` function. 54 | * Documentation was improved. 55 | * Object returned by `sample_locally`, `add_predictions` and `fit_explanation` functions now carry more information (mainly explained instance) so some function calls were simplified (`plot_explanation`). 56 | 57 | # live 1.4.2 58 | 59 | * Fixed bug in variable selection. 60 | 61 | # live 1.4.1 62 | 63 | * Variable selection is now better suited to work with factor/character variables. 64 | 65 | # live 1.4.0 66 | 67 | * Variable selection is now based on LASSO as implemented in glmnet package. 68 | * Updated documentation and vignette. 69 | 70 | # live 1.3.3 71 | 72 | * `add_predictions` also returns black box model object (`model` element). 73 | 74 | 75 | # live 1.3.2 76 | 77 | * Hyperparameters can be also passed to `add_predictions` function. 78 | 79 | # live 1.3.1 80 | 81 | * `fit_explanation` is now more flexible, can take a list of hyperparameters for a chosen model. 82 | 83 | # live 1.3.0 84 | 85 | * For classification problems waterfall plots can be drawn on probability or logit scale. 86 | 87 | # live 1.2.0 88 | 89 | * Now using forestmodel package for better factor handling. 90 | 91 | # live 1.1.2 92 | 93 | * Date variables will now be hold constant while performing local exploration. 94 | * Improved performance. 95 | 96 | # live 1.1.1 97 | 98 | * `add_predictions` improved to handle more learners (for example ranger). 99 | 100 | # live 1.1.0 101 | 102 | * Added a `NEWS.md` file to track changes to the package. 103 | * `sample\_locally` uses data.table for faster local exploration. 104 | 105 | # live 1.0.0 106 | 107 | * Cheatsheet added. 108 | * First package release. 109 | -------------------------------------------------------------------------------- /R/app.R: -------------------------------------------------------------------------------- 1 | #' Function that starts a Shiny app which helps use LIVE. 2 | #' 3 | #' @param train_data dataset from which observations will be sampled. 4 | #' @param black_box_model Pre-trained model with predict interface. 5 | #' @param target character, name of the response variable. 6 | #' @param explained_data Data frame with predictions to explain. 7 | #' 8 | #' @import shiny 9 | #' 10 | #' @export 11 | #' 12 | #' @return shiny app 13 | #' 14 | 15 | live_shiny <- function(train_data, black_box_model, target, explained_data = train_data) { 16 | shinyApp( 17 | ui = fluidPage( 18 | column(3, 19 | sliderInput("instance", "Explained prediction (row number)", 20 | min = 1, max = nrow(explained_data), 21 | step = 1, round = T, value = 1), 22 | sliderInput("size", "Size of simulated dataset", 23 | min = 100, max = 10000, step = 100, 24 | round = T, value = 1000), 25 | selectInput("method", "Sampling method", 26 | choices = c("live", "permute", "normal"), 27 | selected = "live"), 28 | checkboxInput("standardize", "Center predictors"), 29 | checkboxInput("selection", "Variable selection"), 30 | selectInput("whitebox", "Explanation model", 31 | choices = paste(mlr::listLearners(warn.missing.packages = F)$type, 32 | mlr::listLearners(warn.missing.packages = F)$short.name, 33 | sep = "."), 34 | selected = "regr.lm"), 35 | selectInput("fixed", "Fixed variables", choices = colnames(train_data), 36 | selected = NULL, multiple = TRUE) 37 | 38 | ), 39 | column(9, plotOutput("main_plot")) 40 | ), 41 | server = function(input, output) { 42 | similars <- reactive({ 43 | sample_locally(train_data, explained_data[input$instance, ], 44 | target, input$size, input$method, 45 | input$fixed) 46 | }) 47 | 48 | similars2 <- reactive({ 49 | add_predictions(similars(), black_box_model) 50 | }) 51 | expl <- reactive({ 52 | fit_explanation(similars2(), input$whitebox, standardize = input$standardize, 53 | selection = input$selection) 54 | }) 55 | output$main_plot <- renderPlot(plot(expl(), type = "waterfall")) 56 | } 57 | ) 58 | } 59 | 60 | -------------------------------------------------------------------------------- /R/dalex_shortcut.R: -------------------------------------------------------------------------------- 1 | #' Fit local model around the observation: shortcut for DALEX explainer objects 2 | #' 3 | #' @param explainer a model to be explained, preprocessed by the DALEX::explain function 4 | #' @param observation a new observation for which predictions need to be explained 5 | #' @param target_variable_name name of the response variablea as a character 6 | #' @param n_new_obs Number of observation in the simulated dataset 7 | #' @param local_model Character specyfing mlr learner to be used as a local model 8 | #' @param select_variables If TRUE, variable selection will be performed while 9 | #' fitting the local linear model 10 | #' @param predict_type Argument passed to mlr::makeLearner() argument "predict.type" 11 | #' while fitting the local model. Defaults to "response" 12 | #' @param kernel_type Function which will be used to calculate distances from 13 | #' simulated observation to explained instance 14 | #' @param ... Arguments to be passed to sample_locally function 15 | #' 16 | #' @return object of class live_explainer. More details in fit_explanation function help. 17 | #' 18 | #' @export 19 | #' 20 | #' @examples 21 | #' \dontrun{ 22 | #' data('wine') 23 | #' library(randomForest) 24 | #' library(DALEX) 25 | #' rf <- randomForest(quality~., data = wine) 26 | #' expl <- explain(rf, wine, wine$quality) 27 | #' live_expl <- local_approximation(expl, wine[5, ], "quality", 500) 28 | #' } 29 | #' 30 | 31 | local_approximation <- function(explainer, observation, target_variable_name, 32 | n_new_obs, 33 | local_model = "regr.lm", 34 | select_variables = F, 35 | predict_type = "response", 36 | kernel_type = gaussian_kernel, ...) { 37 | 38 | neighbourhood <- sample_locally(explainer$data, 39 | observation, 40 | target_variable_name, 41 | n_new_obs, 42 | ...) 43 | with_predictions <- add_predictions(neighbourhood, 44 | explainer$model, 45 | predict_fun = explainer$predict_function) 46 | live::fit_explanation(with_predictions, 47 | white_box = local_model, 48 | selection = select_variables, 49 | predict_type = predict_type, 50 | kernel = kernel_type) 51 | } -------------------------------------------------------------------------------- /R/generics.R: -------------------------------------------------------------------------------- 1 | #' Generic print function for live explainer 2 | #' 3 | #' @param x Object created using fit_explanation function 4 | #' @param ... other arguments 5 | #' 6 | #' @export 7 | #' 8 | 9 | print.live_explainer <- function(x, ...) { 10 | if(x$selected_variables) { 11 | selection_present <- "Variable selection was performed" 12 | } else { 13 | selection_present <- "Variable selection wasn't performed" 14 | } 15 | if(is.null(x$weights)) { 16 | weights_present <- "Weights not present in the explanation model" 17 | } else { 18 | weights_present <- "Weights present in the explanation model" 19 | } 20 | model_tmp <- mlr::getLearnerModel(x$model) 21 | if(all(class(model_tmp) == "lm")) { 22 | rsq <- summary(model_tmp)$r.squared 23 | gof <- paste("R-squared:", round(rsq, 4)) 24 | } else { 25 | gof <- NULL 26 | } 27 | 28 | cat("Dataset: \n", 29 | "Observations: ", nrow(x$data), "\n", 30 | "Variables: ", ncol(x$data), "\n", 31 | "Response variable: ", mlr::getTaskTargetNames(x$model$task.desc), "\n") 32 | cat("Explanation model: \n", 33 | "Name: ", mlr::getLearnerId(x$model$learner), "\n", 34 | selection_present, "\n", 35 | weights_present, "\n", 36 | gof) 37 | invisible(x) 38 | } 39 | 40 | #' Generic print function for class live_explorer 41 | #' 42 | #' @param x Object created by sample_locally function or add_predictions function 43 | #' @param ... Other arguments 44 | #' 45 | #' @export 46 | #' 47 | 48 | print.live_explorer <- function(x, ...) { 49 | if(x$target %in% colnames(x$data)) { 50 | target_message <- "Black box model predictions were added" 51 | model_message <- paste("Model: ", class(x$model)[1]) 52 | } else { 53 | target_message <- "Black box model predictions were not added" 54 | model_message <- NULL 55 | } 56 | cat("Dataset: \n", 57 | "Observations: ", nrow(x$data), "\n", 58 | "Variables: ", ncol(x$data), "\n", 59 | "Response variable: ", x$target, "\n") 60 | cat("Properties: \n", 61 | "Sampling method:", x$sampling_method, "\n", 62 | "Fixed variables", x$fixed_variables, "\n", 63 | target_message, "\n", 64 | model_message) 65 | invisible(x) 66 | } 67 | -------------------------------------------------------------------------------- /R/helpers.R: -------------------------------------------------------------------------------- 1 | check_for_na <- function(data, explained_instance) { 2 | if(any(is.na(explained_instance))) warning("Missing values present in explained instance.") 3 | if(any(is.na(data))) warning("Missing values present in dataset. NAs will be omitted while sampling.") 4 | } 5 | 6 | 7 | check_conditions <- function(data, explained_instance, size) { 8 | if(nrow(data) == 0) stop("Empty data frame") 9 | if(ncol(data) == 0) stop("Data frame has no columns") 10 | if(size <= 0 | !is.finite(size)) stop("Size has to be a positive integer") 11 | if(any(colnames(data) != colnames(explained_instance))) 12 | stop("Explained instance must have the same variables as data") 13 | } 14 | 15 | 16 | set_constant_variables <- function(data, explained_instance, col_names) { 17 | cols <- (1:ncol(data))[which(colnames(data) %in% col_names)] 18 | if(length(cols) == 0) { 19 | return(data) 20 | } else { 21 | for(k in cols) { 22 | data.table::set(data, j = as.integer(k), 23 | value = explained_instance[1, as.integer(k)]) 24 | } 25 | data 26 | } 27 | } 28 | 29 | 30 | create_task <- function(model, dataset, target_var, weights = NULL) { 31 | if(grepl("regr", model)) { 32 | mlr::makeRegrTask(id = "lime_task", 33 | data = as.data.frame(dataset), 34 | target = target_var, 35 | weights = weights) 36 | } else { 37 | mlr::makeClassifTask(id = "lime_task", 38 | data = as.data.frame(dataset), 39 | target = target_var) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /R/kernels.R: -------------------------------------------------------------------------------- 1 | #' LIME kernel that treats all observations as equally similar to 2 | #' observation of interest. 3 | #' 4 | #' @param explained_instance explained instance 5 | #' @param simulated_instance new observation 6 | #' 7 | #' @return numeric 8 | #' 9 | #' @export 10 | #' 11 | 12 | identity_kernel <- function(explained_instance, simulated_instance) { 13 | 1 14 | } 15 | 16 | 17 | #' LIME kernel from the original article with sigma = 1. 18 | #' 19 | #' @param explained_instance explained instance 20 | #' @param simulated_instance new observation 21 | #' 22 | #' @return numeric 23 | #' 24 | #' @export 25 | #' 26 | 27 | gaussian_kernel <- function(explained_instance, simulated_instance) { 28 | exp(-sum((explained_instance - simulated_instance)^2)) 29 | } 30 | 31 | 32 | #' LIME kernel equal to the inverse of euclidean distance. 33 | #' 34 | #' @param explained_instance explained instance 35 | #' @param simulated_instance new observation 36 | #' 37 | #' @return numeric 38 | #' 39 | #' @export 40 | #' 41 | 42 | euclidean_kernel <- function(explained_instance, simulated_instance) { 43 | 1/(sqrt(sum((explained_instance - simulated_instance)^2)) + 44 | all(simulated_instance == explained_instance)) 45 | } 46 | -------------------------------------------------------------------------------- /R/live.R: -------------------------------------------------------------------------------- 1 | #' live: visualizing interpretable models to explain black box models. 2 | #' 3 | #' This package aims to help locally fit and visualize interpretable models similarly to LIME methodology. 4 | #' Interface provided by mlr package is used. Tools are provided to create a simulated dataset of 5 | #' similar observations, fit chosen white box models (GLM and CART in particular) and visualize 6 | #' them. The methodology is based on Tulio Ribeiro, Singh, Guestrin (2016) . 7 | #' More details can be found in Staniak, Biecek (2018) . 8 | #' 9 | #' @section Important functions: 10 | #' \code{\link{sample_locally}} generates a dataset that will be used for local exploration. 11 | #' \code{\link{add_predictions}} adds black box model predictions to simulated dataset. 12 | #' \code{\link{fit_explanation}} fits a chosen white box model to simulated dataset. 13 | #' generic \code{\link{plot}} function visualizes fitted model. 14 | #' \code{\link{local_approximation}} function can be used with DALEX explainers to perform 15 | #' all the steps of local model exploration. 16 | #' 17 | #' @section Example datasets: 18 | #' \code{wine} Data on wine quality taken from 19 | #' Modeling wine preferences by data mining from physicochemical properties 20 | #' 21 | #' @docType package 22 | #' @name live 23 | NULL 24 | 25 | #' Red wine characteristics and quality. 26 | #' 27 | #' Popular dataset related to wine samples from north Portugal. 28 | #' 29 | #' @format Data frame with 1599 rows and 12 columns. 30 | #' 31 | #' @references P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis. 32 | #' Modeling wine preferences by data mining from physicochemical properties. 33 | #' In Decision Support Systems, Elsevier, 47(4):547-553, 2009. 34 | "wine" 35 | 36 | #' @importFrom data.table as.data.table rbindlist 37 | #' @importFrom stats as.formula model.matrix 38 | -------------------------------------------------------------------------------- /R/local_perimp.R: -------------------------------------------------------------------------------- 1 | #' Local permutation variable importance 2 | #' 3 | #' This function calculates local variable importance (variable drop-out) 4 | #' by finding top_n observations closest to the explained instance, 5 | #' performing permutation variable importance and using weighted mean square 6 | #' error as loss function with weights equal to 1 - Gower distances of the 7 | #' closest observations to the explainedi instance. 8 | #' 9 | #' @param explained_instance Data frame with one observation for which 10 | #' prediction will be explained 11 | #' @param data Data from with the same columns as explained_instance 12 | #' @param explained_var Character with the names of response variable 13 | #' @param model Model to be explained 14 | #' @param top_n Number of observation that will be used to calculate 15 | #' local variable importance 16 | #' 17 | #' @export 18 | #' 19 | #' @return list of class "local_permutation_importance" that consists of 20 | #' \item{residuals}{Data frame with names of variables in the dataset ("label") and 21 | #' values of drop-out loss ("dropout_loss")} 22 | #' \item{weighted_local_mse}{Value of weighted MSE for the whole dataset with weights 23 | #' given by 1 - Gower distance from the explained instance} 24 | #' \item{explained_instance}{Explained instance as a data frame} 25 | #' 26 | #' @examples 27 | #' \dontrun{ 28 | #' local_permutation_importance(wine[5, ], wine, 29 | #' randomForest(quality~., data = wine), 30 | #' top_n = 1000) 31 | #' } 32 | #' 33 | #' @importFrom stats predict 34 | #' @importFrom dplyr desc 35 | #' 36 | 37 | local_permutation_importance <- function(explained_instance, data, 38 | explained_var, model, 39 | top_n = nrow(data)) { 40 | dropout_loss <- NULL 41 | 42 | predictors <- data[, -which(colnames(data) == explained_var)] 43 | top_closest <- gower::gower_topn(explained_instance, predictors, n = top_n) 44 | indices <- as.numeric(top_closest$index) 45 | distances <- as.numeric(top_closest$distance) 46 | data_closest <- predictors[indices, ] 47 | res <- sapply(colnames(data_closest), function(predictor) { 48 | permuted <- data_closest 49 | permuted[, predictor] <- sample(unlist(data_closest[, predictor], 50 | use.names = FALSE), 51 | size = nrow(permuted)) 52 | predicted <- predict(model, permuted) 53 | weighted.mean((predicted - data[indices, explained_var])^2, 1 - distances) 54 | }) 55 | res <- data.frame(label = names(res), dropout_loss = res) 56 | residuals <- dplyr::arrange(res, desc(dropout_loss)) 57 | full_mse <- weighted.mean((data[, explained_var] - predict(model, data))^2, 58 | 1 - gower::gower_dist(explained_instance, data)) 59 | result <- list(residuals = residuals, 60 | weighted_local_mse = full_mse, 61 | explained_instance = explained_instance) 62 | class(result) <- c("local_permutation_importance", "list") 63 | result 64 | } 65 | 66 | 67 | #' Plot local permutation importance 68 | #' 69 | #' @param x Object of class local_permutation_importance 70 | #' @param ... Optional arguments, currently ignored 71 | #' 72 | #' @return ggplot2 object 73 | #' 74 | #' @import ggplot2 75 | #' @importFrom stats reorder weighted.mean 76 | #' 77 | #' @export 78 | #' 79 | 80 | plot.local_permutation_importance <- function(x, ...) { 81 | dropout_loss <- label <- NULL 82 | x$residuals <- dplyr::mutate(x$residuals, dropout_loss = dropout_loss - x$weighted_local_mse) 83 | ggplot(x$residuals, 84 | aes(reorder(label, x$residuals$dropout_loss, desc = T), 85 | ymin = 0, ymax = dropout_loss)) + 86 | geom_errorbar() + 87 | coord_flip() + 88 | ylab("Weighted drop-out loss") + 89 | xlab("") 90 | } 91 | 92 | 93 | #' Print method for local_permutation_importance class 94 | #' 95 | #' @param x Object of class local_permutation_importance 96 | #' @param ... Optional arguments, currently ignored 97 | #' 98 | #' @export 99 | #' 100 | 101 | print.local_permutation_importance <- function(x, ...) { 102 | max_length = max(nchar(as.character(unlist(x$residuals$label, use.names = FALSE)))) 103 | if(max_length < 8) { 104 | initial_spaces <- 0 105 | } else { 106 | initial_spaces <- max_length - 8 107 | } 108 | cat("Variable", paste(rep(" ", times = initial_spaces), sep = "", collapse = ""), "Drop-out loss", "\n") 109 | for(i in 1:nrow(x$residuals)) { 110 | current_label <- as.character(x$residuals[i, "label"]) 111 | n_spaces = max_length - nchar(current_label) 112 | cat(paste(current_label, paste0(rep(" ", times = n_spaces), sep = "", 113 | collapse = "")), 114 | x$residuals[i, "dropout_loss"], "\n") 115 | } 116 | invisible(x) 117 | } 118 | -------------------------------------------------------------------------------- /R/plot.R: -------------------------------------------------------------------------------- 1 | #' @importFrom graphics plot 2 | 3 | plot_regression <- function(plot_type, fitted_model, explained_instance, classif, ...) { 4 | if(plot_type == "forest") { 5 | forestmodel::forest_model(fitted_model) 6 | } else { 7 | if(classif) { 8 | plot(breakDown::broken(fitted_model, explained_instance, baseline = "Intercept"), 9 | trans = function(x) exp(x)/(1 + exp(x)), ...) 10 | } else { 11 | plot(breakDown::broken(fitted_model, explained_instance, baseline = "Intercept"), ...) 12 | } 13 | } 14 | } 15 | 16 | 17 | #' Plotting white box models. 18 | #' 19 | #' @param x List returned by fit_explanation function. 20 | #' @param type Chr, "forest" or "waterfall" depending 21 | #' on which type of plot is to be created. 22 | #' if lm/glm model is used as interpretable approximation. 23 | #' @param ... Additional parameters that will be passed to plot.broken or plot method. 24 | #' In particular, when number of features is large, top_features argument can 25 | #' be set in plot.broken. 26 | #' 27 | #' @return plot (ggplot2 or base) 28 | #' 29 | #' @export 30 | #' 31 | #' @examples 32 | #' \dontrun{ 33 | #' # Forest plot for regression 34 | #' plot(fitted_explanation1, type = "forest") 35 | #' # Waterfall plot 36 | #' plot(fitted_explanation1, type = "waterfall") 37 | #' # Plot decision tree 38 | #' plot(fitted_explanation2) 39 | #' } 40 | #' 41 | 42 | plot.live_explainer <- function(x, type = "waterfall", ...) { 43 | trained_model <- mlr::getLearnerModel(x$model) 44 | present_variables <- colnames(x$data) 45 | explained_instance <- x$explained_instance[, present_variables] 46 | classif <- x$model$learner$type == "classif" 47 | 48 | if(any(grepl("lm", class(trained_model)))) { 49 | plot_regression(type, trained_model, explained_instance, classif, ...) 50 | } else { 51 | plot(trained_model, ...) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /R/sampling_methods.R: -------------------------------------------------------------------------------- 1 | generate_neighbourhood <- function(data, explained_instance, size, fixed_variables, seed = NULL) { 2 | data <- data.table::as.data.table(data) 3 | neighbourhood <- data.table::rbindlist(lapply(1:size, function(x) explained_instance)) 4 | if(!is.null(seed)) { 5 | set.seed(seed) 6 | } 7 | for(k in 1:nrow(neighbourhood)) { 8 | picked_var <- sample(1:ncol(data), 1) 9 | data.table::set(neighbourhood, i = as.integer(k), j = as.integer(picked_var), 10 | data[sample(1:nrow(data), 1), picked_var, with = FALSE]) 11 | } 12 | as.data.frame(set_constant_variables(neighbourhood, explained_instance, fixed_variables)) 13 | } 14 | 15 | 16 | permutation_neighbourhood <- function(data, explained_instance, size, fixed_variables, seed = NULL) { 17 | neighbourhood <- data.table::rbindlist(lapply(1:size, function(x) 18 | explained_instance)) 19 | if(!is.null(seed)) { 20 | set.seed(seed) 21 | } 22 | for(k in 1:ncol(neighbourhood)) { 23 | data.table::set(neighbourhood, j = as.integer(k), 24 | value = data[sample(1:nrow(data), size, replace = TRUE), 25 | k]) 26 | } 27 | as.data.frame(set_constant_variables(neighbourhood, explained_instance, fixed_variables)) 28 | } 29 | 30 | #' @importFrom utils head 31 | 32 | normal_neighbourhood <- function(data, explained_instance, size, fixed_variables, seed = NULL, ...) { 33 | 34 | numerical_features <- dplyr::select_if(data, is.numeric) 35 | categorical_features <- dplyr::select_if(data, function(x) !is.numeric(x)) 36 | 37 | if(!is.null(seed)) { 38 | set.seed(seed) 39 | } 40 | numerical_part <- MASS::mvrnorm(size, ...) 41 | 42 | colnames(numerical_part) <- colnames(numerical_features) 43 | 44 | if(ncol(categorical_features) > 0) { 45 | if(size <= nrow(categorical_features)) { 46 | categorical_features <- data.table::as.data.table(head(categorical_features, size)) 47 | } else { 48 | categorical_features <- data.table::as.data.table(data.table::rbindlist(lapply(1:size, 49 | function(x) categorical_features[1, , drop = FALSE]))) 50 | } 51 | 52 | categorical_col_nums <- which(sapply(data, function(x) !is.numeric(x))) 53 | 54 | for(k in 1:ncol(categorical_features)) { 55 | data.table::set(categorical_features, j = as.integer(k), 56 | value = data[sample(1:nrow(data), size, replace = TRUE), 57 | categorical_col_nums[k]]) 58 | } 59 | } 60 | 61 | neighbourhood <- as.data.frame(cbind(numerical_part, categorical_features)) 62 | as.data.frame(set_constant_variables(neighbourhood, 63 | explained_instance, fixed_variables)) 64 | } 65 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | .onAttach <- function(...) { 2 | mlr::configureMlr() 3 | packageStartupMessage("Welcome to live v", utils::packageVersion("live"), ". Live is a part of DALEXverse. Find out more at https://github.com/pbiecek/DALEX.") 4 | } 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # live: Local Interpretable (Model-agnostic) Visual Explanations 2 | 3 | [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/live)](https://CRAN.R-project.org/package=live) 4 | [![Downloads](http://cranlogs.r-pkg.org/badges/live)](https://CRAN.R-project.org/package=live) 5 | [![Total Downloads](http://cranlogs.r-pkg.org/badges/grand-total/live?color=orange)](https://cranlogs.r-pkg.org/badges/grand-total/live) 6 | [![Build Status](https://travis-ci.org/ModelOriented/live.svg?branch=master)](https://travis-ci.org/ModelOriented/live) 7 | [![Coverage Status](https://img.shields.io/codecov/c/github/ModelOriented/live/master.svg)](https://codecov.io/github/ModelOriented/live?branch=master) 8 | [![DOI](https://zenodo.org/badge/97615889.svg)](https://zenodo.org/badge/latestdoi/97615889) 9 | [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=The%20live%20package%20will%20help%20you%20explain%20your%20model%27s%20predictions%20by%20fitting%20a%20simpler%20model%20locally%20and%20visualizing%20it.%20Find%20out%20more%20at%0Ahttps://github.com/MI2DataLab/live%0A&hashtags=rstats,interpretableML,machinelearning,xAI) 10 | 11 | 12 | ## Installation 13 | 14 | To get started, install stable CRAN version: 15 | 16 | ``` 17 | install.packages("live") 18 | ``` 19 | 20 | or the development version: 21 | 22 | ``` 23 | devtools::install_github("ModelOriented/live") 24 | ``` 25 | 26 | [See the latest changes.](https://github.com/ModelOriented/live/blob/master/NEWS.md) 27 | 28 | Features coming up next: 29 | 30 | * better support for comparing explanations for different models / different instances, 31 | 32 | * improved Shiny application (see `live_shiny` function in development version). 33 | 34 | If you have any bug reports, feature requests or ideas to improve the methodology, feel free to leave an issue. 35 | 36 | 37 | ## Materials 38 | 39 | Find the paper about `live` and [breakDown](https://github.com/pbiecek/breakDown) in [R Journal](https://journal.r-project.org/archive/2018/RJ-2018-072/index.html). 40 | 41 | Website: https://mi2datalab.github.io/live/ 42 | 43 | Conference talks on `live`: [Wrocław 2018](https://github.com/mstaniak/Talks/raw/master/2018/Wroclaw_IX.pdf), [Berlin 2017](https://github.com/mstaniak/Berlin_2017). 44 | 45 | Python implementation of LIME and info about the method: https://github.com/marcotcr/lime 46 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | template: 2 | package: MI2template 3 | default_assets: false 4 | -------------------------------------------------------------------------------- /arepo/backpack.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/backpack.db -------------------------------------------------------------------------------- /arepo/gallery/0a79acf1a27b1a2a6404f257223041e4.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/0a79acf1a27b1a2a6404f257223041e4.rda -------------------------------------------------------------------------------- /arepo/gallery/1025d57a48c5a037e5a56d8b1b06c1df.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/1025d57a48c5a037e5a56d8b1b06c1df.rda -------------------------------------------------------------------------------- /arepo/gallery/1f3204991d06e083f7608cd3f2acce5b.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/1f3204991d06e083f7608cd3f2acce5b.rda -------------------------------------------------------------------------------- /arepo/gallery/32f06fe892f0b02a756d28280b985cbd.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/32f06fe892f0b02a756d28280b985cbd.rda -------------------------------------------------------------------------------- /arepo/gallery/3722f537a2cb2d78daba392d1c7e8bd7.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/3722f537a2cb2d78daba392d1c7e8bd7.rda -------------------------------------------------------------------------------- /arepo/gallery/3722f537a2cb2d78daba392d1c7e8bd7.txt: -------------------------------------------------------------------------------- 1 | # A tibble: 6 x 12 2 | fixed_acidity volatile_acidity citric_acid residual_sugar chlorides 3 | 4 | 1 7.4 0.7 0 1.9 0.076 5 | 2 7.8 0.88 0 2.6 0.098 6 | 3 7.8 0.76 0.04 2.3 0.092 7 | 4 11.2 0.28 0.56 1.9 0.075 8 | 5 7.4 0.7 0 1.9 0.076 9 | 6 7.4 0.66 0 1.8 0.075 10 | # ... with 7 more variables: free_sulfur_dioxide , 11 | # total_sulfur_dioxide , density , pH , sulphates , 12 | # alcohol , quality 13 | -------------------------------------------------------------------------------- /arepo/gallery/66e9851f52186a38d5773dd5b7f1a669.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/66e9851f52186a38d5773dd5b7f1a669.rda -------------------------------------------------------------------------------- /arepo/gallery/66e9851f52186a38d5773dd5b7f1a669.txt: -------------------------------------------------------------------------------- 1 | model_type case model_r2 model_intercept model_prediction 2 | 1 regression 1 0.1178565 5.516584 5.187165 3 | 2 regression 1 0.1178565 5.516584 5.187165 4 | 3 regression 1 0.1178565 5.516584 5.187165 5 | 4 regression 1 0.1178565 5.516584 5.187165 6 | 5 regression 1 0.1178565 5.516584 5.187165 7 | 6 regression 1 0.1178565 5.516584 5.187165 8 | feature feature_value feature_weight 9 | 1 alcohol 9.40 -0.14136067 10 | 2 volatile_acidity 0.70 -0.11221659 11 | 3 pH 3.51 -0.07516158 12 | 4 total_sulfur_dioxide 34.00 0.04183254 13 | 5 residual_sugar 1.90 -0.02921456 14 | 6 sulphates 0.56 -0.02195751 15 | feature_desc 16 | 1 alcohol <= 9.5 17 | 2 0.64 < volatile_acidity 18 | 3 3.40 < pH 19 | 4 22 < total_sulfur_dioxide <= 38 20 | 5 residual_sugar <= 1.9 21 | 6 0.55 < sulphates <= 0.62 22 | data 23 | 1 7.4000, 0.7000, 0.0000, 1.9000, 0.0760, 11.0000, 34.0000, 0.9978, 3.5100, 0.5600, 9.4000, 5.0000 24 | 2 7.4000, 0.7000, 0.0000, 1.9000, 0.0760, 11.0000, 34.0000, 0.9978, 3.5100, 0.5600, 9.4000, 5.0000 25 | 3 7.4000, 0.7000, 0.0000, 1.9000, 0.0760, 11.0000, 34.0000, 0.9978, 3.5100, 0.5600, 9.4000, 5.0000 26 | 4 7.4000, 0.7000, 0.0000, 1.9000, 0.0760, 11.0000, 34.0000, 0.9978, 3.5100, 0.5600, 9.4000, 5.0000 27 | 5 7.4000, 0.7000, 0.0000, 1.9000, 0.0760, 11.0000, 34.0000, 0.9978, 3.5100, 0.5600, 9.4000, 5.0000 28 | 6 7.4000, 0.7000, 0.0000, 1.9000, 0.0760, 11.0000, 34.0000, 0.9978, 3.5100, 0.5600, 9.4000, 5.0000 29 | prediction 30 | 1 5.032032 31 | 2 5.032032 32 | 3 5.032032 33 | 4 5.032032 34 | 5 5.032032 35 | 6 5.032032 36 | -------------------------------------------------------------------------------- /arepo/gallery/82bfc17ccfc8f765f19926485baa5fbf.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/82bfc17ccfc8f765f19926485baa5fbf.rda -------------------------------------------------------------------------------- /arepo/gallery/e1ae768c305f1df6d89bd564ebe84003.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/e1ae768c305f1df6d89bd564ebe84003.rda -------------------------------------------------------------------------------- /arepo/gallery/ee48c1cf298256247c7170da8048cfca.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/ee48c1cf298256247c7170da8048cfca.rda -------------------------------------------------------------------------------- /arepo/gallery/eebe616e0e3bae29d79416cb6e6b91ed.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/arepo/gallery/eebe616e0e3bae29d79416cb6e6b91ed.rda -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | codecov: 3 | token: bf629347-0b7e-423e-8b4c-8e7261a1b29c 4 | -------------------------------------------------------------------------------- /data/wine.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/data/wine.rda -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | License • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
39 |
40 | 92 | 93 | 94 |
95 | 96 |
97 |
98 | 101 | 102 |
YEAR: 2018
103 | COPYRIGHT HOLDER: Mateusz Staniak
104 | 
105 | 106 |
107 | 108 |
109 | 110 | 111 |
112 | 115 | 116 |
117 |

Site built with pkgdown.

118 |
119 | 120 |
121 |
122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/MI2logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/MI2logo.jpg -------------------------------------------------------------------------------- /docs/articles/HR_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/HR_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /docs/articles/HR_files/figure-html/unnamed-chunk-1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/HR_files/figure-html/unnamed-chunk-1-2.png -------------------------------------------------------------------------------- /docs/articles/HR_files/figure-html/unnamed-chunk-1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/HR_files/figure-html/unnamed-chunk-1-3.png -------------------------------------------------------------------------------- /docs/articles/TCGA_files/figure-html/libs-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/TCGA_files/figure-html/libs-1.png -------------------------------------------------------------------------------- /docs/articles/TCGA_files/figure-html/libs-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/TCGA_files/figure-html/libs-2.png -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Articles • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
39 |
40 | 92 | 93 | 94 |
95 | 96 |
97 |
98 | 101 | 102 |
103 |

All vignettes

104 |

105 | 106 | 109 |
110 |
111 |
112 | 113 |
114 | 117 | 118 |
119 |

Site built with pkgdown.

120 |
121 | 122 |
123 |
124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/articles/wine_quality_files/figure-html/forestplot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/wine_quality_files/figure-html/forestplot-1.png -------------------------------------------------------------------------------- /docs/articles/wine_quality_files/figure-html/plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/wine_quality_files/figure-html/plot-1.png -------------------------------------------------------------------------------- /docs/articles/wine_quality_files/figure-html/plot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/wine_quality_files/figure-html/plot-2.png -------------------------------------------------------------------------------- /docs/articles/wine_quality_files/figure-html/waterfallplot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelOriented/live/772a01f6ba95eeec65082126a9c422a7be1fcd2a/docs/articles/wine_quality_files/figure-html/waterfallplot-1.png -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Citation and Authors • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
39 |
40 | 92 | 93 | 94 |
95 | 96 |
97 |
98 | 99 | 102 | 103 |

Staniak M, Biecek P (2018). 104 | “Explanations of Model Predictions with live and breakDown Packages.” 105 | The R Journal, 10(2), 395–409. 106 | doi: 10.32614/RJ-2018-072, https://doi.org/10.32614/RJ-2018-072. 107 |

108 |
@Article{RJ-2018-072,
109 |   title = {Explanations of Model Predictions with live and breakDown Packages},
110 |   author = {Mateusz Staniak and Przemysław Biecek},
111 |   year = {2018},
112 |   journal = {The R Journal},
113 |   doi = {10.32614/RJ-2018-072},
114 |   url = {https://doi.org/10.32614/RJ-2018-072},
115 |   pages = {395--409},
116 |   volume = {10},
117 |   number = {2},
118 | }
119 | 122 | 123 |
    124 |
  • 125 |

    Mateusz Staniak. Maintainer, author. 126 |

    127 |
  • 128 |
  • 129 |

    Przemysław Biecek. Author. 130 |

    131 |
  • 132 |
133 | 134 |
135 | 136 |
137 | 138 | 139 |
140 | 143 | 144 |
145 |

Site built with pkgdown.

146 |
147 | 148 |
149 |
150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/jquery.sticky-kit.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 3 | */ 4 | (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)); 5 | 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, 6 | 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"}), 8 | 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", 9 | 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 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticker footer */ 2 | body > .container { 3 | display: flex; 4 | padding-top: 60px; 5 | min-height: calc(100vh); 6 | flex-direction: column; 7 | } 8 | 9 | body > .container .row { 10 | flex: 1; 11 | } 12 | 13 | footer { 14 | margin-top: 45px; 15 | padding: 35px 0 36px; 16 | border-top: 1px solid #e5e5e5; 17 | color: #666; 18 | display: flex; 19 | } 20 | footer p { 21 | margin-bottom: 0; 22 | } 23 | footer div { 24 | flex: 1; 25 | } 26 | footer .pkgdown { 27 | text-align: right; 28 | } 29 | footer p { 30 | margin-bottom: 0; 31 | } 32 | 33 | img.icon { 34 | float: right; 35 | } 36 | 37 | img { 38 | max-width: 100%; 39 | } 40 | 41 | /* Section anchors ---------------------------------*/ 42 | 43 | a.anchor { 44 | margin-left: -30px; 45 | display:inline-block; 46 | width: 30px; 47 | height: 30px; 48 | visibility: hidden; 49 | 50 | background-image: url(./link.svg); 51 | background-repeat: no-repeat; 52 | background-size: 20px 20px; 53 | background-position: center center; 54 | } 55 | 56 | .hasAnchor:hover a.anchor { 57 | visibility: visible; 58 | } 59 | 60 | @media (max-width: 767px) { 61 | .hasAnchor:hover a.anchor { 62 | visibility: hidden; 63 | } 64 | } 65 | 66 | 67 | /* Fixes for fixed navbar --------------------------*/ 68 | 69 | .contents h1, .contents h2, .contents h3, .contents h4 { 70 | padding-top: 60px; 71 | margin-top: -60px; 72 | } 73 | 74 | /* Static header placement on mobile devices */ 75 | @media (max-width: 767px) { 76 | .navbar-fixed-top { 77 | position: absolute; 78 | } 79 | .navbar { 80 | padding: 0; 81 | } 82 | } 83 | 84 | 85 | /* Sidebar --------------------------*/ 86 | 87 | #sidebar { 88 | margin-top: 30px; 89 | } 90 | #sidebar h2 { 91 | font-size: 1.5em; 92 | margin-top: 1em; 93 | } 94 | 95 | #sidebar h2:first-child { 96 | margin-top: 0; 97 | } 98 | 99 | #sidebar .list-unstyled li { 100 | margin-bottom: 0.5em; 101 | } 102 | 103 | /* Reference index & topics ----------------------------------------------- */ 104 | 105 | .ref-index th {font-weight: normal;} 106 | .ref-index h2 {font-size: 20px;} 107 | 108 | .ref-index td {vertical-align: top;} 109 | .ref-index .alias {width: 40%;} 110 | .ref-index .title {width: 60%;} 111 | 112 | .ref-index .alias {width: 40%;} 113 | .ref-index .title {width: 60%;} 114 | 115 | .ref-arguments th {text-align: right; padding-right: 10px;} 116 | .ref-arguments th, .ref-arguments td {vertical-align: top;} 117 | .ref-arguments .name {width: 20%;} 118 | .ref-arguments .desc {width: 80%;} 119 | 120 | /* Nice scrolling for wide elements --------------------------------------- */ 121 | 122 | table { 123 | display: block; 124 | overflow: auto; 125 | } 126 | 127 | /* Syntax highlighting ---------------------------------------------------- */ 128 | 129 | pre { 130 | word-wrap: normal; 131 | word-break: normal; 132 | border: 1px solid #eee; 133 | } 134 | 135 | pre, code { 136 | background-color: #f8f8f8; 137 | color: #333; 138 | } 139 | 140 | pre .img { 141 | margin: 5px 0; 142 | } 143 | 144 | pre .img img { 145 | background-color: #fff; 146 | display: block; 147 | height: auto; 148 | } 149 | 150 | code a, pre a { 151 | color: #375f84; 152 | } 153 | table { 154 | display: block; 155 | overflow: auto; 156 | width: 100% !important; 157 | } 158 | 159 | .fl {color: #1514b5;} 160 | .fu {color: #000000;} /* function */ 161 | .ch,.st {color: #036a07;} /* string */ 162 | .kw {color: #264D66;} /* keyword */ 163 | .co {color: #888888;} /* comment */ 164 | 165 | .message { color: black; font-weight: bolder;} 166 | .error { color: orange; font-weight: bolder;} 167 | .warning { color: #6A0366; font-weight: bolder;} 168 | 169 | .navbar-mi2logo { 170 | float: left; 171 | margin-right: 15px; 172 | margin-top: 2px; 173 | } 174 | .navbar-mi2 { 175 | background-color: #4a3c89; 176 | color: #fff !important; 177 | margin-right: 0px; 178 | } 179 | .navbar-mi2 > li > a { 180 | color: #fff !important; 181 | } 182 | .navbar-mi2 > .active > a{ 183 | background-color: #370f54 !important; 184 | } 185 | .navbar-mi2 > .open > a:focus, .nav-pills> .open > a:focus{ 186 | background-color: #370f54 !important; 187 | } 188 | .dropdown-menu > .active > a, .dropdown-menu > .active > a:focus{ 189 | background-color: #370f54 !important; 190 | } 191 | 192 | .contents-mi2 > li > a:focus, .nav-pills > li > a:focus { 193 | background-color: #4a3c89 !important; 194 | color: #fff; 195 | } 196 | .contents-mi2 > li.active > a, .nav-pills > li.active > a{ 197 | background-color: #370f54 !important; 198 | } 199 | .contents-mi2 > li > a, .nav-pills > li > a{ 200 | background-color: #4a3c89 !important; 201 | color: #fff; 202 | } 203 | 204 | .sidebar-logo { 205 | display:block; 206 | margin-left:auto; 207 | margin-right:auto; 208 | text-align: justify; 209 | } -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | $("#sidebar").stick_in_parent({offset_top: 40}); 3 | $('body').scrollspy({ 4 | target: '#sidebar', 5 | offset: 60 6 | }); 7 | 8 | var cur_path = location.href; 9 | $("#navbar ul li a").each(function(index, value) { 10 | if (value.text == "Home") 11 | return; 12 | if (value.getAttribute("href") === "#") 13 | return; 14 | 15 | var path = value.href; 16 | if (cur_path == path) { 17 | // Add class to parent
  • , and enclosing
  • if in dropdown 18 | var menu_anchor = $(value); 19 | menu_anchor.parent().addClass("active"); 20 | menu_anchor.closest("li.dropdown").addClass("active"); 21 | } 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.3.1 2 | pkgdown: 1.3.0 3 | pkgdown_sha: ~ 4 | articles: 5 | wine_quality: wine_quality.html 6 | 7 | -------------------------------------------------------------------------------- /docs/reference/calculate_weights.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Calculate weights for explanation model — calculate_weights • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Calculate weights for explanation model

    104 | 105 | 106 |
    calculate_weights(simulated_dataset, explained_instance, kernel)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
    simulated_dataset

    Dataset simulated by sample_locally function.

    explained_instance

    Instance to be explained.

    kernel

    Chosen kernel function.

    124 | 125 |

    Value

    126 | 127 |

    Numeric vector of weights for each row in simulated dataset.

    128 | 129 | 130 |
    131 | 140 |
    141 | 142 |
    143 | 146 | 147 |
    148 |

    Site built with pkgdown.

    149 |
    150 | 151 |
    152 |
    153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/reference/check_conditions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Check if data, explained instance and size make sense. — check_conditions • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Check if data, explained instance and size make sense.

    104 | 105 | 106 |
    check_conditions(data, explained_instance, size)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
    data

    Data frame from which observations will be sampled.

    explained_instance

    Instance around which points will be sampled.

    size

    Number of observation in simulated dataset

    124 | 125 |

    Value

    126 | 127 |

    Produces an error if any of conditions aren't met.

    128 | 129 | 130 |
    131 | 140 |
    141 | 142 |
    143 | 146 | 147 |
    148 |

    Site built with pkgdown.

    149 |
    150 | 151 |
    152 |
    153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/reference/check_for_na.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Alert user if NAs are present — check_for_na • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Alert user if NAs are present

    104 | 105 | 106 |
    check_for_na(data, explained_instance)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
    data

    Data frame from which observations are generated by sample_locally.

    explained_instance

    A row in an original data frame (as a data.frame).

    120 | 121 |

    Value

    122 | 123 |

    Warning message

    124 | 125 | 126 |
    127 | 136 |
    137 | 138 |
    139 | 142 | 143 |
    144 |

    Site built with pkgdown.

    145 |
    146 | 147 |
    148 |
    149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/reference/create_task.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Create regression or classification task. — create_task • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Create regression or classification task.

    104 | 105 | 106 |
    create_task(model, dataset, target_var, weights = NULL)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 |
    model

    Name of a used model in mlr format.

    dataset

    Data frame on which model will be trained.

    target_var

    Name of column in dataset containing explained variable.

    weights

    Weights for observations.

    128 | 129 |

    Value

    130 | 131 |

    mlr task object

    132 | 133 | 134 |
    135 | 144 |
    145 | 146 |
    147 | 150 | 151 |
    152 |

    Site built with pkgdown.

    153 |
    154 | 155 |
    156 |
    157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /docs/reference/euclidean_kernel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | LIME kernel equal to the inverse of euclidean distance. — euclidean_kernel • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    LIME kernel equal to the inverse of euclidean distance.

    104 | 105 | 106 |
    euclidean_kernel(explained_instance, simulated_instance)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
    explained_instance

    explained instance

    simulated_instance

    new observation

    120 | 121 |

    Value

    122 | 123 |

    numeric

    124 | 125 | 126 |
    127 | 136 |
    137 | 138 |
    139 | 142 | 143 |
    144 |

    Site built with pkgdown.

    145 |
    146 | 147 |
    148 |
    149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/reference/gaussian_kernel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | LIME kernel from the original article with sigma = 1. — gaussian_kernel • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    LIME kernel from the original article with sigma = 1.

    104 | 105 | 106 |
    gaussian_kernel(explained_instance, simulated_instance)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
    explained_instance

    explained instance

    simulated_instance

    new observation

    120 | 121 |

    Value

    122 | 123 |

    numeric

    124 | 125 | 126 |
    127 | 136 |
    137 | 138 |
    139 | 142 | 143 |
    144 |

    Site built with pkgdown.

    145 |
    146 | 147 |
    148 |
    149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/reference/generate_neighbourhood.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | LIME: sampling for local exploration — generate_neighbourhood • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    LIME: sampling for local exploration

    104 | 105 | 106 |
    generate_neighbourhood(data, explained_instance, size)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
    data

    Data frame from which observations will be generated.

    explained_instance

    A row in an original data frame (as a data.frame).

    size

    Number of observations to be generated.

    124 | 125 |

    Value

    126 | 127 |

    data.frame

    128 | 129 | 130 |
    131 | 140 |
    141 | 142 |
    143 | 146 | 147 |
    148 |

    Site built with pkgdown.

    149 |
    150 | 151 |
    152 |
    153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/reference/identity_kernel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | LIME kernel that treats all observations as equally similar to 10 | observation of interest. — identity_kernel • live 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | 36 | 37 | 38 | 39 |
    40 |
    41 | 94 | 95 | 96 |
    97 | 98 |
    99 |
    100 | 104 | 105 | 106 |

    LIME kernel that treats all observations as equally similar to 107 | observation of interest.

    108 | 109 | 110 |
    identity_kernel(explained_instance, simulated_instance)
    111 | 112 |

    Arguments

    113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
    explained_instance

    explained instance

    simulated_instance

    new observation

    124 | 125 |

    Value

    126 | 127 |

    numeric

    128 | 129 | 130 |
    131 | 140 |
    141 | 142 |
    143 | 146 | 147 |
    148 |

    Site built with pkgdown.

    149 |
    150 | 151 |
    152 |
    153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/reference/live_shiny.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Function that starts a Shiny app which helps use LIVE. — live_shiny • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Function that starts a Shiny app which helps use LIVE.

    104 | 105 | 106 |
    live_shiny(train_data, black_box_model, target,
    107 |   explained_data = train_data)
    108 | 109 |

    Arguments

    110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
    train_data

    dataset from which observations will be sampled.

    black_box_model

    Pre-trained model with predict interface.

    target

    character, name of the response variable.

    explained_data

    Data frame with predictions to explain.

    129 | 130 |

    Value

    131 | 132 |

    shiny app

    133 | 134 | 135 |
    136 | 145 |
    146 | 147 |
    148 | 151 | 152 |
    153 |

    Site built with pkgdown.

    154 |
    155 | 156 |
    157 |
    158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /docs/reference/permutation_neighbourhood.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | LIME: sampling for local exploration by permuting all columns. — permutation_neighbourhood • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    LIME: sampling for local exploration by permuting all columns.

    104 | 105 | 106 |
    permutation_neighbourhood(data, explained_instance, size, fixed_variables,
    107 |   seed = NULL)
    108 | 109 |

    Arguments

    110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 |
    data

    Data frame from which observations will be generated.

    explained_instance

    A row in an original data frame (as a data.frame).

    size

    Number of observations to be generated.

    fixed_variables

    Names of column which will not be changed while sampling.

    seed

    Seed to set before sampling. If NULL, results will not be reproducible.

    133 | 134 |

    Value

    135 | 136 |

    data frame

    137 | 138 | 139 |
    140 | 149 |
    150 | 151 |
    152 | 155 | 156 |
    157 |

    Site built with pkgdown.

    158 |
    159 | 160 |
    161 |
    162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/reference/plot.local_permutation_importance.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Plot local permutation importance — plot.local_permutation_importance • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Plot local permutation importance

    104 | 105 | 106 |
    # S3 method for local_permutation_importance
    107 | plot(x, ...)
    108 | 109 |

    Arguments

    110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
    x

    Object of class local_permutation_importance

    ...

    Optional arguments, currently ignored

    121 | 122 |

    Value

    123 | 124 |

    ggplot2 object

    125 | 126 | 127 |
    128 | 137 |
    138 | 139 |
    140 | 143 | 144 |
    145 |

    Site built with pkgdown.

    146 |
    147 | 148 |
    149 |
    150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/reference/plot_regression.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Waterfall plot or forestplot for lm/glm explanations. — plot_regression • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    DEPRECATED

    104 | 105 | 106 |
    plot_regression(plot_type, fitted_model, explained_instance, classif)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
    plot_type

    Chr, "forestplot" or "waterfallplot" depending 114 | on which type of plot is to be created.

    fitted_model

    glm or lm object.

    explained_instance

    Observation around which model was fitted.

    classif

    logical, if TRUE, probabilities will be plotted

    129 | 130 |

    Value

    131 | 132 |

    plot (ggplot2 or lattice)

    133 | 134 | 135 |
    136 | 145 |
    146 | 147 |
    148 | 151 | 152 |
    153 |

    Site built with pkgdown.

    154 |
    155 | 156 |
    157 |
    158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /docs/reference/plot_regression2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Waterfall plot or forestplot for lm/glm explanations. — plot_regression2 • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Waterfall plot or forestplot for lm/glm explanations.

    104 | 105 | 106 |
    plot_regression2(plot_type, fitted_model, explained_instance, classif)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
    plot_type

    Chr, "forest" or "waterfall" depending 114 | on which type of plot is to be created.

    fitted_model

    glm or lm object.

    explained_instance

    Observation around which model was fitted.

    classif

    logical, if TRUE, probabilities will be plotted

    129 | 130 |

    Value

    131 | 132 |

    plot (ggplot2 or lattice)

    133 | 134 | 135 |
    136 | 145 |
    146 | 147 |
    148 | 151 | 152 |
    153 |

    Site built with pkgdown.

    154 |
    155 | 156 |
    157 |
    158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /docs/reference/prepare_forestplot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Draw a forest plot with proper annotations. — prepare_forestplot • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 |
    41 |
    42 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Draw a forest plot with proper annotations.

    104 | 105 | 106 |
    prepare_forestplot(model)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 |
    model

    lm/glm object

    116 | 117 | 118 |
    119 | 126 |
    127 | 128 |
    129 | 132 | 133 |
    134 |

    Site built with pkgdown.

    135 |
    136 | 137 |
    138 |
    139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /docs/reference/print.live_explainer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Generic print function for live explainer — print.live_explainer • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Generic print function for live explainer

    104 | 105 | 106 |
    # S3 method for live_explainer
    107 | print(x, ...)
    108 | 109 |

    Arguments

    110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
    x

    Object created using fit_explanation function

    ...

    other arguments

    121 | 122 | 123 |
    124 | 131 |
    132 | 133 |
    134 | 137 | 138 |
    139 |

    Site built with pkgdown.

    140 |
    141 | 142 |
    143 |
    144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/reference/print.live_explorer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Generic print function for class live_explorer — print.live_explorer • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Generic print function for class live_explorer

    104 | 105 | 106 |
    # S3 method for live_explorer
    107 | print(x, ...)
    108 | 109 |

    Arguments

    110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
    x

    Object created by sample_locally function or add_predictions function

    ...

    Other arguments

    121 | 122 | 123 |
    124 | 131 |
    132 | 133 |
    134 | 137 | 138 |
    139 |

    Site built with pkgdown.

    140 |
    141 | 142 |
    143 |
    144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/reference/print.local_permutation_importance.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Print method for local_permutation_importance class — print.local_permutation_importance • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Print method for local_permutation_importance class

    104 | 105 | 106 |
    # S3 method for local_permutation_importance
    107 | print(x, ...)
    108 | 109 |

    Arguments

    110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
    x

    Object of class local_permutation_importance

    ...

    Optional arguments, currently ignored

    121 | 122 | 123 |
    124 | 131 |
    132 | 133 |
    134 | 137 | 138 |
    139 |

    Site built with pkgdown.

    140 |
    141 | 142 |
    143 |
    144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/reference/replace_items_by_rows.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Replace one element of each row with a random element from given data frame. — replace_items_by_rows • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 |
    41 |
    42 | 89 | 90 | 91 |
    92 | 93 |
    94 |
    95 | 98 | 99 | 100 |

    Replace one element of each row with a random element from given data frame.

    101 | 102 | 103 |
    replace_items_by_rows(chosen_vars, data, target)
    104 | 105 |

    Arguments

    106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
    chosen_vars

    Columns to sample from [as positions/numbers].

    data

    Data frame to sample from.

    target

    Data frame in which the replacement is done.

    121 | 122 |

    Value

    123 | 124 |

    data.frame

    125 | 126 | 127 |
    128 | 137 |
    138 | 139 |
    140 | 143 | 144 |
    145 |

    Site built with pkgdown.

    146 |
    147 | 148 |
    149 |
    150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/reference/select_variables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Select variables for explanation model. — select_variables • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Select variables for explanation model.

    104 | 105 | 106 |
    select_variables(source_data, target, response_family)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
    source_data

    Simulated dataset.

    target

    Name of the response variable.

    response_family

    Name of distribution family to be used in lasso/glm fit.

    124 | 125 |

    Value

    126 | 127 |

    Character vector of names of selected variables

    128 | 129 | 130 |
    131 | 140 |
    141 | 142 |
    143 | 146 | 147 |
    148 |

    Site built with pkgdown.

    149 |
    150 | 151 |
    152 |
    153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/reference/set_constant_dates.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Set date values to one value — set_constant_dates • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Set date values to one value

    104 | 105 | 106 |
    set_constant_dates(data, explained_instance)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
    data

    Data frame to change.

    explained_instance

    1-row data frame with instance of interest.

    120 | 121 | 122 |
    123 | 130 |
    131 | 132 |
    133 | 136 | 137 |
    138 |

    Site built with pkgdown.

    139 |
    140 | 141 |
    142 |
    143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /docs/reference/set_constant_variables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Set date values to one value — set_constant_variables • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Set date values to one value

    104 | 105 | 106 |
    set_constant_variables(data, explained_instance, col_names)
    107 | 108 |

    Arguments

    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
    data

    Data frame to change.

    explained_instance

    Instance that will be explained.

    col_names

    Names of columns to be fixed

    124 | 125 | 126 |
    127 | 134 |
    135 | 136 |
    137 | 140 | 141 |
    142 |

    Site built with pkgdown.

    143 |
    144 | 145 |
    146 |
    147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /docs/reference/wine.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Red wine characteristics and quality. — wine • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 92 | 93 | 94 |
    95 | 96 |
    97 |
    98 | 101 | 102 | 103 |

    Popular dataset related to wine samples from north Portugal.

    104 | 105 | 106 |
    wine
    107 | 108 |

    Format

    109 | 110 |

    Data frame with 1599 rows and 12 columns.

    111 | 112 |

    References

    113 | 114 |

    P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis. 115 | Modeling wine preferences by data mining from physicochemical properties. 116 | In Decision Support Systems, Elsevier, 47(4):547-553, 2009.

    117 | 118 | 119 |
    120 | 130 |
    131 | 132 |
    133 | 136 | 137 |
    138 |

    Site built with pkgdown.

    139 |
    140 | 141 |
    142 |
    143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /docs/reference/winequality_red.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Red wine characteristics and quality. — winequality_red • live 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 |
    41 |
    42 | 97 | 98 | 99 |
    100 | 101 |
    102 |
    103 | 106 | 107 | 108 |

    Popular dataset related to wine samples from north Portugal.

    109 | 110 | 111 |
    winequality_red
    112 | 113 |

    Format

    114 | 115 |

    Data frame with 1599 rows and 12 columns.

    116 | 117 |

    References

    118 | 119 |

    P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis. 120 | Modeling wine preferences by data mining from physicochemical properties. 121 | In Decision Support Systems, Elsevier, 47(4):547-553, 2009.

    122 | 123 | 124 |
    125 | 135 |
    136 | 137 |
    138 | 141 | 142 |
    143 |

    Site built with pkgdown.

    144 |
    145 | 146 |
    147 |
    148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | bibentry(bibtype = "Article", 2 | key = "RJ-2018-072", 3 | title = "Explanations of Model Predictions with live and breakDown Packages", 4 | author = c(person(given = "Mateusz", 5 | family = "Staniak"), 6 | person(given = "Przemysław", 7 | family = "Biecek")), 8 | year = "2018", 9 | journal = "The R Journal", 10 | doi = "10.32614/RJ-2018-072", 11 | url = "https://doi.org/10.32614/RJ-2018-072", 12 | pages = "395--409", 13 | volume = "10", 14 | number = "2", 15 | header = "To cite live in publications use:" 16 | ) 17 | -------------------------------------------------------------------------------- /live.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | -------------------------------------------------------------------------------- /man/add_predictions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/explore.R 3 | \name{add_predictions} 4 | \alias{add_predictions} 5 | \title{Add black box predictions to generated dataset} 6 | \usage{ 7 | add_predictions(to_explain, black_box_model, data = NULL, 8 | predict_fun = predict, hyperparams = list(), ...) 9 | } 10 | \arguments{ 11 | \item{to_explain}{List return by sample_locally function.} 12 | 13 | \item{black_box_model}{String with mlr signature of a learner or a model with predict interface.} 14 | 15 | \item{data}{Original data frame used to generate new dataset. 16 | Need not be provided when a trained model is passed in 17 | black_box_model argument.} 18 | 19 | \item{predict_fun}{Either a "predict" function that returns a vector of the 20 | same type as response or custom function that takes a model as a first argument, 21 | and data used to calculate predictions as a second argument 22 | and returns a vector of the same type as respone. 23 | Will be used only if a model object was provided in the black_box argument.} 24 | 25 | \item{hyperparams}{Optional list of (hyper)parameters to be passed to mlr::makeLearner.} 26 | 27 | \item{...}{Additional parameters to be passed to predict function.} 28 | } 29 | \value{ 30 | list of class "live_explorer" consisting of 31 | \item{data}{Dataset generated by sample_locally function with response variable.} 32 | \item{target}{Name of the response variable.} 33 | \item{model}{Black box model which is being explained.} 34 | \item{explained_instance}{Instance that is being explained.} 35 | \item{sampling_method}{Name of used sampling method} 36 | \item{fixed_variables}{Names of variables which were not sampled} 37 | \item{sdevations}{Standard deviations of numerical variables} 38 | } 39 | \description{ 40 | Add black box predictions to generated dataset 41 | } 42 | \examples{ 43 | \dontrun{ 44 | # Train a model inside add_predictions call. 45 | local_exploration1 <- add_predictions(dataset_for_local_exploration, 46 | black_box_model = "regr.svm", 47 | data = wine) 48 | # Pass trained model to the function. 49 | svm_model <- svm(quality ~., data = wine) 50 | local_exploration2 <- add_predictions(dataset_for_local_exploration, 51 | black_box_model = svm_model) 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /man/euclidean_kernel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/kernels.R 3 | \name{euclidean_kernel} 4 | \alias{euclidean_kernel} 5 | \title{LIME kernel equal to the inverse of euclidean distance.} 6 | \usage{ 7 | euclidean_kernel(explained_instance, simulated_instance) 8 | } 9 | \arguments{ 10 | \item{explained_instance}{explained instance} 11 | 12 | \item{simulated_instance}{new observation} 13 | } 14 | \value{ 15 | numeric 16 | } 17 | \description{ 18 | LIME kernel equal to the inverse of euclidean distance. 19 | } 20 | -------------------------------------------------------------------------------- /man/fit_explanation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/explain.R 3 | \name{fit_explanation} 4 | \alias{fit_explanation} 5 | \title{Fit white box model to the simulated data.} 6 | \usage{ 7 | fit_explanation(live_object, white_box = "regr.lm", 8 | kernel = gaussian_kernel, standardize = FALSE, selection = FALSE, 9 | response_family = "gaussian", predict_type = "response", 10 | hyperpars = list()) 11 | } 12 | \arguments{ 13 | \item{live_object}{List return by add_predictions function.} 14 | 15 | \item{white_box}{String, learner name recognized by mlr package.} 16 | 17 | \item{kernel}{function which will be used to calculate distance between simulated 18 | observations and explained instance.} 19 | 20 | \item{standardize}{If TRUE, numerical variables will be scaled to have mean 0, variance 1 21 | before fitting explanation model.} 22 | 23 | \item{selection}{If TRUE, variable selection based on glmnet implementation of LASSO 24 | will be performed.} 25 | 26 | \item{response_family}{family argument to glmnet (and then glm) function. 27 | Default value is "gaussian"} 28 | 29 | \item{predict_type}{Argument passed to mlr::makeLearner() argument "predict.type". 30 | Defaults to "response".} 31 | 32 | \item{hyperpars}{Optional list of values of hyperparameteres of a model.} 33 | } 34 | \value{ 35 | List of class "live_explainer" that consists of 36 | \item{data}{Dataset used to fit explanation model (may have less column than the original)} 37 | \item{model}{Fitted explanation model} 38 | \item{explained_instance}{Instance that is being explained} 39 | \item{weights}{Weights used in model fitting} 40 | \item{selected_variables}{Names of selected variables} 41 | } 42 | \description{ 43 | Fit white box model to the simulated data. 44 | } 45 | \examples{ 46 | \dontrun{ 47 | fitted_explanation <- fit_explanation(local_exploration1, "regr.lm", selection = TRUE) 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /man/gaussian_kernel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/kernels.R 3 | \name{gaussian_kernel} 4 | \alias{gaussian_kernel} 5 | \title{LIME kernel from the original article with sigma = 1.} 6 | \usage{ 7 | gaussian_kernel(explained_instance, simulated_instance) 8 | } 9 | \arguments{ 10 | \item{explained_instance}{explained instance} 11 | 12 | \item{simulated_instance}{new observation} 13 | } 14 | \value{ 15 | numeric 16 | } 17 | \description{ 18 | LIME kernel from the original article with sigma = 1. 19 | } 20 | -------------------------------------------------------------------------------- /man/identity_kernel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/kernels.R 3 | \name{identity_kernel} 4 | \alias{identity_kernel} 5 | \title{LIME kernel that treats all observations as equally similar to 6 | observation of interest.} 7 | \usage{ 8 | identity_kernel(explained_instance, simulated_instance) 9 | } 10 | \arguments{ 11 | \item{explained_instance}{explained instance} 12 | 13 | \item{simulated_instance}{new observation} 14 | } 15 | \value{ 16 | numeric 17 | } 18 | \description{ 19 | LIME kernel that treats all observations as equally similar to 20 | observation of interest. 21 | } 22 | -------------------------------------------------------------------------------- /man/live.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/live.R 3 | \docType{package} 4 | \name{live} 5 | \alias{live} 6 | \alias{live-package} 7 | \title{live: visualizing interpretable models to explain black box models.} 8 | \description{ 9 | This package aims to help locally fit and visualize interpretable models similarly to LIME methodology. 10 | Interface provided by mlr package is used. Tools are provided to create a simulated dataset of 11 | similar observations, fit chosen white box models (GLM and CART in particular) and visualize 12 | them. The methodology is based on Tulio Ribeiro, Singh, Guestrin (2016) . 13 | More details can be found in Staniak, Biecek (2018) https://arxiv.org/abs/1804.01955. 14 | } 15 | \section{Important functions}{ 16 | 17 | \code{\link{sample_locally}} generates a dataset that will be used for local exploration. 18 | \code{\link{add_predictions}} adds black box model predictions to simulated dataset. 19 | \code{\link{fit_explanation}} fits a chosen white box model to simulated dataset. 20 | generic \code{\link{plot}} function visualizes fitted model. 21 | \code{\link{local_approximation}} function can be used with DALEX explainers to perform 22 | all the steps of local model exploration. 23 | } 24 | 25 | \section{Example datasets}{ 26 | 27 | \code{wine} Data on wine quality taken from 28 | Modeling wine preferences by data mining from physicochemical properties 29 | } 30 | 31 | -------------------------------------------------------------------------------- /man/live_shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/app.R 3 | \name{live_shiny} 4 | \alias{live_shiny} 5 | \title{Function that starts a Shiny app which helps use LIVE.} 6 | \usage{ 7 | live_shiny(train_data, black_box_model, target, 8 | explained_data = train_data) 9 | } 10 | \arguments{ 11 | \item{train_data}{dataset from which observations will be sampled.} 12 | 13 | \item{black_box_model}{Pre-trained model with predict interface.} 14 | 15 | \item{target}{character, name of the response variable.} 16 | 17 | \item{explained_data}{Data frame with predictions to explain.} 18 | } 19 | \value{ 20 | shiny app 21 | } 22 | \description{ 23 | Function that starts a Shiny app which helps use LIVE. 24 | } 25 | -------------------------------------------------------------------------------- /man/local_approximation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dalex_shortcut.R 3 | \name{local_approximation} 4 | \alias{local_approximation} 5 | \title{Fit local model around the observation: shortcut for DALEX explainer objects} 6 | \usage{ 7 | local_approximation(explainer, observation, target_variable_name, 8 | n_new_obs, local_model = "regr.lm", select_variables = F, 9 | predict_type = "response", kernel_type = gaussian_kernel, ...) 10 | } 11 | \arguments{ 12 | \item{explainer}{a model to be explained, preprocessed by the DALEX::explain function} 13 | 14 | \item{observation}{a new observation for which predictions need to be explained} 15 | 16 | \item{target_variable_name}{name of the response variablea as a character} 17 | 18 | \item{n_new_obs}{Number of observation in the simulated dataset} 19 | 20 | \item{local_model}{Character specyfing mlr learner to be used as a local model} 21 | 22 | \item{select_variables}{If TRUE, variable selection will be performed while 23 | fitting the local linear model} 24 | 25 | \item{predict_type}{Argument passed to mlr::makeLearner() argument "predict.type" 26 | while fitting the local model. Defaults to "response"} 27 | 28 | \item{kernel_type}{Function which will be used to calculate distances from 29 | simulated observation to explained instance} 30 | 31 | \item{...}{Arguments to be passed to sample_locally function} 32 | } 33 | \value{ 34 | object of class live_explainer. More details in fit_explanation function help. 35 | } 36 | \description{ 37 | Fit local model around the observation: shortcut for DALEX explainer objects 38 | } 39 | \examples{ 40 | \dontrun{ 41 | data('wine') 42 | library(randomForest) 43 | library(DALEX) 44 | rf <- randomForest(quality~., data = wine) 45 | expl <- explain(rf, wine, wine$quality) 46 | live_expl <- local_approximation(expl, wine[5, ], "quality", 500) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /man/local_permutation_importance.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/local_perimp.R 3 | \name{local_permutation_importance} 4 | \alias{local_permutation_importance} 5 | \title{Local permutation variable importance} 6 | \usage{ 7 | local_permutation_importance(explained_instance, data, explained_var, 8 | model, top_n = nrow(data)) 9 | } 10 | \arguments{ 11 | \item{explained_instance}{Data frame with one observation for which 12 | prediction will be explained} 13 | 14 | \item{data}{Data from with the same columns as explained_instance} 15 | 16 | \item{explained_var}{Character with the names of response variable} 17 | 18 | \item{model}{Model to be explained} 19 | 20 | \item{top_n}{Number of observation that will be used to calculate 21 | local variable importance} 22 | } 23 | \value{ 24 | list of class "local_permutation_importance" that consists of 25 | \item{residuals}{Data frame with names of variables in the dataset ("label") and 26 | values of drop-out loss ("dropout_loss")} 27 | \item{weighted_local_mse}{Value of weighted MSE for the whole dataset with weights 28 | given by 1 - Gower distance from the explained instance} 29 | \item{explained_instance}{Explained instance as a data frame} 30 | } 31 | \description{ 32 | This function calculates local variable importance (variable drop-out) 33 | by finding top_n observations closest to the explained instance, 34 | performing permutation variable importance and using weighted mean square 35 | error as loss function with weights equal to 1 - Gower distances of the 36 | closest observations to the explainedi instance. 37 | } 38 | \examples{ 39 | \dontrun{ 40 | local_permutation_importance(wine[5, ], wine, 41 | randomForest(quality~., data = wine), 42 | top_n = 1000) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /man/plot.live_explainer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot.live_explainer} 4 | \alias{plot.live_explainer} 5 | \title{Plotting white box models.} 6 | \usage{ 7 | \method{plot}{live_explainer}(x, type = "waterfall", ...) 8 | } 9 | \arguments{ 10 | \item{x}{List returned by fit_explanation function.} 11 | 12 | \item{type}{Chr, "forest" or "waterfall" depending 13 | on which type of plot is to be created. 14 | if lm/glm model is used as interpretable approximation.} 15 | 16 | \item{...}{Additional parameters that will be passed to plot.broken or plot method. 17 | In particular, when number of features is large, top_features argument can 18 | be set in plot.broken.} 19 | } 20 | \value{ 21 | plot (ggplot2 or base) 22 | } 23 | \description{ 24 | Plotting white box models. 25 | } 26 | \examples{ 27 | \dontrun{ 28 | # Forest plot for regression 29 | plot(fitted_explanation1, type = "forest") 30 | # Waterfall plot 31 | plot(fitted_explanation1, type = "waterfall") 32 | # Plot decision tree 33 | plot(fitted_explanation2) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /man/plot.local_permutation_importance.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/local_perimp.R 3 | \name{plot.local_permutation_importance} 4 | \alias{plot.local_permutation_importance} 5 | \title{Plot local permutation importance} 6 | \usage{ 7 | \method{plot}{local_permutation_importance}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Object of class local_permutation_importance} 11 | 12 | \item{...}{Optional arguments, currently ignored} 13 | } 14 | \value{ 15 | ggplot2 object 16 | } 17 | \description{ 18 | Plot local permutation importance 19 | } 20 | -------------------------------------------------------------------------------- /man/print.live_explainer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.R 3 | \name{print.live_explainer} 4 | \alias{print.live_explainer} 5 | \title{Generic print function for live explainer} 6 | \usage{ 7 | \method{print}{live_explainer}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Object created using fit_explanation function} 11 | 12 | \item{...}{other arguments} 13 | } 14 | \description{ 15 | Generic print function for live explainer 16 | } 17 | -------------------------------------------------------------------------------- /man/print.live_explorer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.R 3 | \name{print.live_explorer} 4 | \alias{print.live_explorer} 5 | \title{Generic print function for class live_explorer} 6 | \usage{ 7 | \method{print}{live_explorer}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Object created by sample_locally function or add_predictions function} 11 | 12 | \item{...}{Other arguments} 13 | } 14 | \description{ 15 | Generic print function for class live_explorer 16 | } 17 | -------------------------------------------------------------------------------- /man/print.local_permutation_importance.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/local_perimp.R 3 | \name{print.local_permutation_importance} 4 | \alias{print.local_permutation_importance} 5 | \title{Print method for local_permutation_importance class} 6 | \usage{ 7 | \method{print}{local_permutation_importance}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Object of class local_permutation_importance} 11 | 12 | \item{...}{Optional arguments, currently ignored} 13 | } 14 | \description{ 15 | Print method for local_permutation_importance class 16 | } 17 | -------------------------------------------------------------------------------- /man/sample_locally.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/explore.R 3 | \name{sample_locally} 4 | \alias{sample_locally} 5 | \title{Generate dataset for local exploration.} 6 | \usage{ 7 | sample_locally(data, explained_instance, explained_var, size, 8 | method = "live", fixed_variables = NULL, seed = NULL, ...) 9 | } 10 | \arguments{ 11 | \item{data}{Data frame from which new dataset will be simulated.} 12 | 13 | \item{explained_instance}{One row data frame with the same variables 14 | as in data argument. Local exploration will be performed around this observation.} 15 | 16 | \item{explained_var}{Name of a column with the variable to be predicted.} 17 | 18 | \item{size}{Number of observations is a simulated dataset.} 19 | 20 | \item{method}{If "live", new observations will be created by changing one value 21 | per observation. If "permute", new observation will be created by permuting all 22 | columns of data. If "normal", numerical features will be sampled from multivariate 23 | normal distribution specified by ... arguments mu and Sigma.} 24 | 25 | \item{fixed_variables}{names or numeric indexes of columns which will not be changed 26 | while sampling.} 27 | 28 | \item{seed}{Seed to set before sampling. If NULL, results will not be reproducible.} 29 | 30 | \item{...}{Mean and covariance matrix for normal sampling method.} 31 | } 32 | \value{ 33 | list of class "live_explorer" consisting of 34 | \item{data}{Dataset generated by sample_locally function with response variable.} 35 | \item{target}{Name of the response variable.} 36 | \item{explained_instance}{Instance that is being explained.} 37 | \item{sampling_method}{Name of used sampling method} 38 | \item{fixed_variables}{Names of variables which were not sampled} 39 | \item{sdevations}{Standard deviations of numerical variables} 40 | } 41 | \description{ 42 | Generate dataset for local exploration. 43 | } 44 | \examples{ 45 | \dontrun{ 46 | dataset_for_local_exploration <- sample_locally(data = wine, 47 | explained_instance = wine[5, ], 48 | explained_var = "quality", 49 | size = 50) 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /man/wine.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/live.R 3 | \docType{data} 4 | \name{wine} 5 | \alias{wine} 6 | \title{Red wine characteristics and quality.} 7 | \format{Data frame with 1599 rows and 12 columns.} 8 | \usage{ 9 | wine 10 | } 11 | \description{ 12 | Popular dataset related to wine samples from north Portugal. 13 | } 14 | \references{ 15 | P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis. 16 | Modeling wine preferences by data mining from physicochemical properties. 17 | In Decision Support Systems, Elsevier, 47(4):547-553, 2009. 18 | } 19 | \keyword{datasets} 20 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(live) 3 | library(mlr) 4 | library(DALEX) 5 | library(data.table) 6 | 7 | set.seed(1) 8 | X <- as.data.frame(matrix(runif(5500), ncol = 11, nrow = 500)) 9 | X2 <- X 10 | X2$V1 <- as.factor(as.character(X2$V1 > 0.5)) 11 | local <- sample_locally(data = X, 12 | explained_instance = X[3, ], 13 | explained_var = "V1", 14 | size = 50) 15 | local1 <- add_predictions(local, "regr.svm", X) 16 | local_explained <- fit_explanation(local1, "regr.lm") 17 | local_explained2 <- fit_explanation(local1, "regr.svm", kernel = identity_kernel) 18 | 19 | X_old <- X 20 | X2_old <- X_old 21 | X2_old$V1 <- as.factor(as.character(X2_old$V1 > 0.5)) 22 | 23 | local2 <- sample_locally(data = X2, explained_instance = X2[3, ], 24 | explained_var = "V1", size = 500) 25 | local3 <- add_predictions(local2, "classif.svm", X2) 26 | local_explained3 <- fit_explanation(local3, "classif.logreg", predict_type = "prob") 27 | 28 | X$V3 <- as.factor(as.character(round(X$V3))) 29 | local4 <- sample_locally(data = X, 30 | explained_instance = X[3, ], 31 | explained_var = "V1", 32 | size = 50) 33 | local4 <- add_predictions(local4, "regr.svm", X) 34 | 35 | X_factors <- X 36 | X_factors$V4 <- as.factor(as.character(round(X_factors$V4))) 37 | 38 | count_diffs_in_rows <- function(table, row, explained_var) { 39 | col_no <- which(colnames(row) == explained_var) 40 | lapply(1:nrow(table), function(x) { 41 | row_of_table <- table[x, ] 42 | sum(row_of_table != row[, -col_no]) 43 | }) %>% 44 | unlist() %>% 45 | sum() 46 | } 47 | 48 | test_check("live") 49 | 50 | -------------------------------------------------------------------------------- /tests/testthat/test_explaining.R: -------------------------------------------------------------------------------- 1 | context("Fitting and plotting explanations") 2 | 3 | test_that("White box model is fitted correctly", { 4 | expect_is(local_explained, "live_explainer") 5 | expect_silent(live:::create_task("classif.logreg", X2, "V1")) 6 | expect_is(mlr::getLearnerModel(local_explained$model), "lm") 7 | expect_error(fit_explanation(sample_locally(X, X[3, ], "V1", 50))) 8 | local1_tmp <- local1 9 | local1_tmp$data$V1 <- rep(1, 50) 10 | expect_error(fit_explanation(local1_tmp)) 11 | expect_silent(fit_explanation(local1, "regr.glm", 12 | response_family = "gaussian")) 13 | }) 14 | 15 | test_that("Kernels are okay", { 16 | expect_equal(identity_kernel(1:10, 1:10), 1) 17 | expect_equal(gaussian_kernel(1:10, 1:10), 1) 18 | expect_equal(euclidean_kernel(1:10, 1:10), 1) 19 | expect_true(identity_kernel(1:10, 1:10) == 1) 20 | expect_true(gaussian_kernel(1:10, runif(10)) != 1) 21 | expect_true(euclidean_kernel(1:10, runif(10)) != 1) 22 | }) 23 | 24 | test_that("Plots are created without problems", { 25 | expect_output(plot(local_explained, type = "waterfall"), regexp = NA) 26 | expect_output(plot(local_explained, type = "forest"), regexp = NA) 27 | expect_output(plot(local_explained2), regexp = NA) 28 | expect_is(plot(local_explained3, type = "waterfall"), "ggplot") 29 | }) 30 | 31 | 32 | test_that("Generics work", { 33 | expect_output(print(local1)) 34 | expect_output(print(sample_locally(X, X[3, ], "V1", 50))) 35 | expect_output(print(local_explained)) 36 | expect_output(print(fit_explanation(local1, selection = T))) 37 | expect_output(print(fit_explanation(local4, selection = T))) 38 | expect_output(print(fit_explanation(local1, kernel = identity_kernel))) 39 | expect_output(print(fit_explanation(local1, "regr.svm"))) 40 | expect_output(print(add_predictions(local3, e1071::svm(V1~.,data = X2)))) 41 | }) 42 | 43 | test_that("Shiny app is fine", { 44 | expect_silent(live_shiny(X, e1071::svm(V1 ~., data = X))) 45 | }) 46 | 47 | test_that("Variable selection", { 48 | expect_silent(fit_explanation(local1, selection = TRUE)) 49 | expect_silent(fit_explanation(local4, selection = TRUE)) 50 | expect_is(select_variables(X_factors, "V1", "gaussian"), "character") 51 | }) 52 | 53 | test_that("Standardize option works", { 54 | set.seed(17) 55 | Xs <- as.data.frame(matrix(runif(5500), ncol = 11, nrow = 500)) 56 | locals <- sample_locally(Xs, Xs[4, ], "V1", 50) 57 | locals <- add_predictions(locals, "regr.lm", Xs) 58 | locals_expl <- fit_explanation(locals, standardize = TRUE) 59 | d1 <- locals$data[, 1:10] 60 | d2 <- locals_expl$data[, 1:10] 61 | expect_equal(as.data.frame(sapply(d1, function(x) scale(x, scale = F))), d2[, 1:10]) 62 | expect_silent(fit_explanation(local4, standardize = TRUE)) 63 | }) 64 | -------------------------------------------------------------------------------- /tests/testthat/test_local_varimp.R: -------------------------------------------------------------------------------- 1 | context("Test local permutation importance") 2 | 3 | X_old_long_names <- X_old 4 | colnames(X_old_long_names) <- paste0(colnames(X_old), "aaaaaaaa") 5 | lm_model <- lm(V1 ~., data = X_old) 6 | lm_model2 <- lm(V1aaaaaaaa ~., data = X_old_long_names) 7 | 8 | varimp <- local_permutation_importance(X_old[3, ], X_old, "V1", lm_model, 50) 9 | varimp2 <- local_permutation_importance(X_old_long_names[3, ], 10 | X_old_long_names, "V1aaaaaaaa", 11 | lm_model2, 50) 12 | 13 | testthat::test_that("S3 method are okay", { 14 | testthat::expect_output(print(varimp)) 15 | testthat::expect_output(print(varimp2)) 16 | testthat::expect_silent(plot(varimp)) 17 | }) 18 | 19 | testthat::test_that("Variable importance works", { 20 | testthat::expect_is(varimp, "local_permutation_importance") 21 | testthat::expect_is(varimp$residuals, "data.frame") 22 | }) 23 | 24 | -------------------------------------------------------------------------------- /tests/testthat/test_shortcut.R: -------------------------------------------------------------------------------- 1 | context("Test shortcut for DALEX explainers") 2 | 3 | mlm <- lm(quality ~., data = live::wine) 4 | expl <- DALEX::explain(mlm, live::wine, live::wine$quality) 5 | 6 | testthat::test_that("DALEX integration is okay", { 7 | testthat::expect_is( 8 | local_approximation(expl, live::wine[5, ], "quality", 500), 9 | "live_explainer" 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /tests/testthat/test_simulating.R: -------------------------------------------------------------------------------- 1 | context("Creating simulated dataset of similar observations") 2 | 3 | set.seed(1) 4 | X <- as.data.frame(matrix(runif(5500), ncol = 11, nrow = 500)) 5 | 6 | count_diffs_in_rows <- function(table, row, explained_var) { 7 | col_no <- which(colnames(row) == explained_var) 8 | lapply(1:nrow(table), function(x) { 9 | row_of_table <- table[x, ] 10 | sum(row_of_table != row[, -col_no]) 11 | }) %>% 12 | unlist() %>% 13 | sum() 14 | } 15 | 16 | test_that("Any changes are made", { 17 | expect_gt( 18 | count_diffs_in_rows((live::sample_locally(data = X, 19 | explained_instance = X[3, ], 20 | explained_var = "V1", 21 | size = 50)$data), X[3, ], "V1"), 0) 22 | }) 23 | 24 | test_that("Not too many changes are made", { 25 | expect_lte( 26 | count_diffs_in_rows((live::sample_locally(data = X, 27 | explained_instance = X[3, ], 28 | explained_var = "V1", 29 | size = 50)$data), X[3, ], "V1"), 50) 30 | expect_lte( 31 | count_diffs_in_rows((live::sample_locally(data = X, 32 | explained_instance = X[3, ], 33 | explained_var = "V1", 34 | size = 100)$data), X[3, ], "V1"), 100) 35 | expect_lte( 36 | count_diffs_in_rows((live::sample_locally(data = X, 37 | explained_instance = X[3, ], 38 | explained_var = "V1", 39 | size = 20)$data), X[3, ], "V1"), 100) 40 | 41 | }) 42 | 43 | test_that("Other sampling methods are okay", { 44 | expect_is(sample_locally(X, X[3, ], "V1", 50, method = "permute"), "live_explorer") 45 | Xtmp <- X 46 | expect_is(normal_neighbourhood(Xtmp, Xtmp[3, ], 50, NULL, 47 | mu = rep(1, 11), Sigma = diag(1, 11)), 48 | "data.frame") 49 | Xtmp$cat <- sample(letters, nrow(Xtmp), replace = T) 50 | expect_is(normal_neighbourhood(Xtmp, Xtmp[3, ], 50, NULL, 51 | mu = rep(1, 11), Sigma = diag(1, 11)), 52 | "data.frame") 53 | expect_is(normal_neighbourhood(Xtmp, Xtmp[3, ], 2000, NULL, 54 | mu = rep(1, 11), Sigma = diag(1, 11)), 55 | "data.frame") 56 | expect_is(sample_locally(X, X[3, ], "V1", 50, method = "normal", 57 | NULL, mu = rep(1, 10), Sigma = diag(1, 10)), 58 | "live_explorer") 59 | }) 60 | 61 | test_that("Missing data are detected warning is given", { 62 | Y <- X 63 | Y[1, 1] <- NA 64 | expect_warning(live:::check_for_na(Y, Y[1, ])) 65 | expect_warning(live:::check_for_na(X, X[4, ]), regexp = NA) 66 | }) 67 | 68 | test_that("Checks are performed, variables are set constant", { 69 | expect_error(live:::check_conditions(X[10, FALSE], X[4, ], 50)) 70 | expect_error(live:::check_conditions(X, X[4, ], -10)) 71 | expect_error(live:::check_conditions(X[FALSE, 10, drop = F], X[4, ], 50)) 72 | expect_error(live:::check_conditions(X[, -5, drop = F], X[4, -6], 50)) 73 | expect_silent(sample_locally(X, X[4, ], "V1", 50, fixed_variables = c("V5", "V6"))) 74 | }) 75 | 76 | test_that("Predictions are added", { 77 | local_dataset <- live::sample_locally(data = X, 78 | explained_instance = X[3, ], 79 | explained_var = "V1", 80 | size = 50) 81 | local_dataset1 <- add_predictions(local_dataset, "regr.lm", X) 82 | expect_output(add_predictions(local_dataset, "regr.lm", X), regexp = NA) 83 | expect_is(local_dataset1$data[[local_dataset1$target]], "numeric") 84 | expect_is(local_dataset1$target, "character") 85 | local_dataset2 <- add_predictions(local_dataset, lm(V1 ~., data = X)) 86 | expect_output(add_predictions(local_dataset, lm(V1 ~., data = X)), regexp = NA) 87 | expect_is(local_dataset2$data[[local_dataset2$target]], "numeric") 88 | expect_is(local_dataset2$target, "character") 89 | expect_error(add_predictions(local_dataset, "regr.lm")) 90 | }) 91 | 92 | test_that("Results are reproducible", { 93 | expect_true(any(sample_locally(X, X[3, ], "V1", 50)$data != sample_locally(X, X[3, ], "V1", 50)$data)) 94 | expect_true(all(sample_locally(X, X[3, ], "V1", 50, seed = 17)$data == sample_locally(X, X[3, ], "V1", 50, seed = 17)$data)) 95 | expect_true(all(sample_locally(X, X[3, ], "V1", 50, method = "permute", seed = 17)$data == sample_locally(X, X[3, ], "V1", 50, method = "permute", seed = 17)$data)) 96 | expect_true(all(sample_locally(X, X[3, ], "V1", 50, method = "normal", seed = 17, mu = rep(0, 10), Sigma = diag(1, 10))$data == sample_locally(X, X[3, ], "V1", 50, method = "normal", seed = 17, mu = rep(0, 10), Sigma = diag(1, 10))$data)) 97 | }) 98 | 99 | --------------------------------------------------------------------------------