Skip to content

Commit a33a26e

Browse files
authored
Merge pull request #145 from ModelOriented/cran-submission
CRAN submission
2 parents e6559f3 + f183e1c commit a33a26e

10 files changed

+88
-109
lines changed

CRAN-SUBMISSION

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
Version: 0.9.3
2-
Date: 2024-01-12 11:21:47 UTC
3-
SHA: d2f329e540177df778e787a27dec50d34cb5ed5c
1+
Version: 0.9.4
2+
Date: 2024-08-20 20:00:54 UTC
3+
SHA: 6269666c0bc2dbb48fd4193adec46b9fbf4fdccd

NAMESPACE

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ S3method(shapviz,explain)
3131
S3method(shapviz,kernelshap)
3232
S3method(shapviz,lgb.Booster)
3333
S3method(shapviz,matrix)
34-
S3method(shapviz,permshap)
3534
S3method(shapviz,predict_parts)
3635
S3method(shapviz,shapr)
3736
S3method(shapviz,treeshap)

NEWS.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# shapviz 0.9.4
22

3-
## API improvements
3+
### API improvements
44

5-
- Support both XGBoost 1.x.x as well as XGBoost 2.x.x, implemented in #144.
5+
- Support both XGBoost 1.x.x as well as XGBoost 2.x.x, implemented in [#144](https://github.com/ModelOriented/shapviz/pull/144).
66

7-
## Improvements
7+
### Other improvements
88

9-
- New argument `sort_features = TRUE` in `sv_importance()` and `sv_interaction()`. Set to `FALSE` to show the features as they appear in your SHAP matrix. In that case, the plots will show the *first* `max_display` features, not the *most important* features. Implements #136.
9+
- New argument `sort_features = TRUE` in `sv_importance()` and `sv_interaction()`. Set to `FALSE` to show the features as they appear in your SHAP matrix. In that case, the plots will show the *first* `max_display` features, not the *most important* features. Implements [#137](https://github.com/ModelOriented/shapviz/pull/137).
1010

1111
### Bug fixes
1212

13-
- `shapviz.xgboost()` would fail if a single row is passed. This has been fixed in #142. Thanks @sebsilas for reporting.
13+
- `shapviz.xgboost()` would fail if a single row is passed. This has been fixed in [#142](https://github.com/ModelOriented/shapviz/pull/142). Thanks @sebsilas for reporting.
1414

1515
# shapviz 0.9.3
1616

R/potential_interactions.R

+3-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@
4242
#' @returns A named vector of decreasing interaction strengths.
4343
#' @export
4444
#' @seealso [sv_dependence()]
45-
potential_interactions <- function(obj, v, nbins = NULL, color_num = TRUE,
46-
scale = FALSE, adjusted = FALSE) {
45+
potential_interactions <- function(
46+
obj, v, nbins = NULL, color_num = TRUE, scale = FALSE, adjusted = FALSE
47+
) {
4748
stopifnot(is.shapviz(obj))
4849
S <- get_shap_values(obj)
4950
S_inter <- get_shap_interactions(obj)

R/shapviz.R

+35-28
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
#' - `shapr::explain()`,
1313
#' - `treeshap::treeshap()`,
1414
#' - `DALEX::predict_parts()`,
15-
#' - `kernelshap::kernelshap()`, and
16-
#' - `kernelshap::permshap()`,
15+
#' - `kernelshap::kernelshap()`,
16+
#' - `kernelshap::permshap()`, and
17+
#' - `kernelshap::additive_shap()`,
1718
#'
1819
#' check the vignettes for examples.
1920
#'
@@ -85,8 +86,9 @@ shapviz.default = function(object, ...) {
8586
#' @describeIn shapviz
8687
#' Creates a "shapviz" object from a matrix of SHAP values.
8788
#' @export
88-
shapviz.matrix = function(object, X, baseline = 0, collapse = NULL,
89-
S_inter = NULL, ...) {
89+
shapviz.matrix = function(
90+
object, X, baseline = 0, collapse = NULL, S_inter = NULL, ...
91+
) {
9092
if (!is.null(collapse)) {
9193
object <- collapse_shap(object, collapse = collapse)
9294
if (!is.null(S_inter)) {
@@ -183,8 +185,15 @@ shapviz.matrix = function(object, X, baseline = 0, collapse = NULL,
183185
#' mx
184186
#' all.equal(mx[[3]], x)
185187
#' }
186-
shapviz.xgb.Booster = function(object, X_pred, X = X_pred, which_class = NULL,
187-
collapse = NULL, interactions = FALSE, ...) {
188+
shapviz.xgb.Booster = function(
189+
object,
190+
X_pred,
191+
X = X_pred,
192+
which_class = NULL,
193+
collapse = NULL,
194+
interactions = FALSE,
195+
...
196+
) {
188197
stopifnot(
189198
"X must be a matrix or data.frame. It can't be an object of class xgb.DMatrix" =
190199
is.matrix(X) || is.data.frame(X),
@@ -269,8 +278,9 @@ shapviz.xgb.Booster = function(object, X_pred, X = X_pred, which_class = NULL,
269278
#' @describeIn shapviz
270279
#' Creates a "shapviz" object from a LightGBM model.
271280
#' @export
272-
shapviz.lgb.Booster = function(object, X_pred, X = X_pred,
273-
which_class = NULL, collapse = NULL, ...) {
281+
shapviz.lgb.Booster = function(
282+
object, X_pred, X = X_pred, which_class = NULL, collapse = NULL, ...
283+
) {
274284
if (!requireNamespace("lightgbm", quietly = TRUE)) {
275285
stop("Package 'lightgbm' not installed")
276286
}
@@ -352,8 +362,9 @@ shapviz.explain <- function(object, X = NULL, baseline = NULL, collapse = NULL,
352362
#' @describeIn shapviz
353363
#' Creates a "shapviz" object from `treeshap::treeshap()`.
354364
#' @export
355-
shapviz.treeshap <- function(object, X = object[["observations"]],
356-
baseline = 0, collapse = NULL, ...) {
365+
shapviz.treeshap <- function(
366+
object, X = object[["observations"]], baseline = 0, collapse = NULL, ...
367+
) {
357368
S_inter <- object[["interactions"]]
358369
if (!is.null(S_inter)) {
359370
S_inter <- aperm(S_inter, c(3L, 1:2))
@@ -410,10 +421,12 @@ shapviz.shapr <- function(object, X = object[["x_test"]], collapse = NULL, ...)
410421
}
411422

412423
#' @describeIn shapviz
413-
#' Creates a "shapviz" object from `kernelshap::kernelshap()`.
424+
#' Creates a "shapviz" object from an object of class 'kernelshap'. This includes
425+
#' results of `kernelshap()`, `permshap()`, and `additive_shap()`.
414426
#' @export
415-
shapviz.kernelshap <- function(object, X = object[["X"]],
416-
which_class = NULL, collapse = NULL, ...) {
427+
shapviz.kernelshap <- function(
428+
object, X = object[["X"]], which_class = NULL, collapse = NULL, ...
429+
) {
417430
S <- object[["S"]]
418431
b <- object[["baseline"]]
419432

@@ -440,36 +453,30 @@ shapviz.kernelshap <- function(object, X = object[["X"]],
440453
shapviz.matrix(object = S, X = X, baseline = b, collapse = collapse)
441454
}
442455

443-
#' @describeIn shapviz
444-
#' Creates a "shapviz" object from `kernelshap::permshap()`.
445-
#' @export
446-
shapviz.permshap <- function(object, X = object[["X"]],
447-
which_class = NULL, collapse = NULL, ...) {
448-
# The output structure of permshap is identical to kernelshap
449-
shapviz.kernelshap(object, X = X, which_class = which_class, collapse = collapse, ...)
450-
}
451-
452456
#' @describeIn shapviz
453457
#' Creates a "shapviz" object from a (tree-based) H2O regression model.
454458
#' @export
455-
shapviz.H2ORegressionModel = function(object, X_pred, X = as.data.frame(X_pred),
456-
collapse = NULL, ...) {
459+
shapviz.H2ORegressionModel = function(
460+
object, X_pred, X = as.data.frame(X_pred), collapse = NULL, ...
461+
) {
457462
shapviz.H2OModel(object = object, X_pred = X_pred, X = X, collapse = collapse, ...)
458463
}
459464

460465
#' @describeIn shapviz
461466
#' Creates a "shapviz" object from a (tree-based) H2O binary classification model.
462467
#' @export
463-
shapviz.H2OBinomialModel = function(object, X_pred, X = as.data.frame(X_pred),
464-
collapse = NULL, ...) {
468+
shapviz.H2OBinomialModel = function(
469+
object, X_pred, X = as.data.frame(X_pred), collapse = NULL, ...
470+
) {
465471
shapviz.H2OModel(object = object, X_pred = X_pred, X = X, collapse = collapse, ...)
466472
}
467473

468474
#' @describeIn shapviz
469475
#' Creates a "shapviz" object from a (tree-based) H2O model (base class).
470476
#' @export
471-
shapviz.H2OModel = function(object, X_pred, X = as.data.frame(X_pred),
472-
collapse = NULL, ...) {
477+
shapviz.H2OModel = function(
478+
object, X_pred, X = as.data.frame(X_pred), collapse = NULL, ...
479+
) {
473480
if (!requireNamespace("h2o", quietly = TRUE)) {
474481
stop("Package 'h2o' not installed")
475482
}

cran-comments.md

+11-22
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,24 @@
1-
# shapviz 0.9.3
1+
# shapviz 0.9.4
22

3-
Hi CRAN team
3+
Dear CRAN team
44

5-
This is a relatively small update, but offers much more flexibility in the interaction heuristic.
5+
This update mainly ensures that upcoming XGBoost version 2.x.x will work.
66

7-
## Checks look good
87

9-
### check(manual = TRUE, cran = TRUE)
8+
### Local checks
109

11-
Ok
10+
Ok, with note
1211

13-
### RHub (usual notes)
14-
15-
* checking package dependencies ... NOTE
16-
Packages which this enhances but not available for checking:
17-
'fastshap', 'h2o', 'lightgbm'
18-
* checking HTML version of manual ... NOTE
19-
Skipping checking math rendering: package 'V8' unavailable
20-
* checking for non-standard things in the check directory ... NOTE
21-
Found the following files/directories:
22-
''NULL''
23-
* checking for detritus in the temp directory ... NOTE
24-
Found the following files/directories:
25-
'lastMiKTeXException'
26-
12+
Packages which this enhances but not available for checking: 'fastshap', 'h2o'
2713

2814
### Winbuilder()
2915

3016
Status: OK
3117

3218
## Reverse dependencies (2)
3319

34-
- OK: 2
35-
- BROKEN: 0
20+
- fastshap 0.1.1 ── E: 0 | W: 1 | N: 1
21+
- lowml 0.1.3 ── E: 0 | W: 0 | N: 0
22+
23+
OK: 2
24+
BROKEN: 0

man/shapviz.Rd

+5-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packaging.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ if (FALSE) {
112112
check_rhub(platforms = "debian-gcc-devel")
113113

114114
# Takes long
115-
revdepcheck::revdep_check(num_workers = 4)
115+
revdepcheck::revdep_check(num_workers = 4, bioc = FALSE)
116116

117117
# Wait until above checks are passed without relevant notes/warnings
118118
# then submit to CRAN

revdep/README.md

+22-22
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,64 @@
22

33
|field |value |
44
|:--------|:--------------------------------------------------------|
5-
|version |R version 4.3.0 (2023-04-21 ucrt) |
6-
|os |Windows 11 x64 (build 22621) |
5+
|version |R version 4.4.1 (2024-06-14 ucrt) |
6+
|os |Windows 11 x64 (build 22631) |
77
|system |x86_64, mingw32 |
88
|ui |RStudio |
99
|language |(EN) |
1010
|collate |German_Switzerland.utf8 |
1111
|ctype |German_Switzerland.utf8 |
1212
|tz |Europe/Zurich |
13-
|date |2024-01-12 |
14-
|rstudio |2023.06.1+524 Mountain Hydrangea (desktop) |
13+
|date |2024-08-20 |
14+
|rstudio |2024.04.2+764 Chocolate Cosmos (desktop) |
1515
|pandoc |3.1.6 @ C:\Users\Michael\AppData\Local\Pandoc\pandoc.exe |
1616

1717
# Dependencies
1818

1919
|package |old |new |Δ |
2020
|:------------|:-------|:-------|:--|
21-
|shapviz |0.9.2 |0.9.3 |* |
22-
|cli |3.6.2 |3.6.2 | |
23-
|colorspace |2.1-0 |2.1-0 | |
24-
|commonmark |1.9.0 |1.9.0 | |
25-
|curl |5.2.0 |5.2.0 | |
26-
|data.table |1.14.10 |1.14.10 | |
21+
|shapviz |0.9.3 |0.9.4 |* |
22+
|cli |3.6.3 |3.6.3 | |
23+
|colorspace |2.1-1 |2.1-1 | |
24+
|commonmark |1.9.1 |1.9.1 | |
25+
|curl |5.2.1 |5.2.1 | |
26+
|data.table |1.15.4 |1.15.4 | |
2727
|fansi |1.0.6 |1.0.6 | |
28-
|farver |2.1.1 |2.1.1 | |
29-
|ggfittext |0.10.1 |0.10.1 | |
28+
|farver |2.1.2 |2.1.2 | |
29+
|ggfittext |0.10.2 |0.10.2 | |
3030
|gggenes |0.5.1 |0.5.1 | |
31-
|ggplot2 |3.4.4 |3.4.4 | |
31+
|ggplot2 |3.5.1 |3.5.1 | |
3232
|ggrepel |0.9.5 |0.9.5 | |
3333
|glue |1.7.0 |1.7.0 | |
3434
|gridtext |0.1.5 |0.1.5 | |
35-
|gtable |0.3.4 |0.3.4 | |
35+
|gtable |0.3.5 |0.3.5 | |
3636
|isoband |0.2.7 |0.2.7 | |
3737
|jpeg |0.1-10 |0.1-10 | |
3838
|jsonlite |1.8.8 |1.8.8 | |
3939
|labeling |0.4.3 |0.4.3 | |
4040
|lifecycle |1.0.4 |1.0.4 | |
4141
|magrittr |2.0.3 |2.0.3 | |
42-
|markdown |1.12 |1.12 | |
43-
|munsell |0.5.0 |0.5.0 | |
42+
|markdown |1.13 |1.13 | |
43+
|munsell |0.5.1 |0.5.1 | |
4444
|patchwork |1.2.0 |1.2.0 | |
4545
|pillar |1.9.0 |1.9.0 | |
4646
|pkgconfig |2.0.3 |2.0.3 | |
4747
|png |0.1-8 |0.1-8 | |
4848
|R6 |2.5.1 |2.5.1 | |
4949
|RColorBrewer |1.1-3 |1.1-3 | |
50-
|Rcpp |1.0.12 |1.0.12 | |
51-
|rlang |1.1.3 |1.1.3 | |
50+
|Rcpp |1.0.13 |1.0.13 | |
51+
|rlang |1.1.4 |1.1.4 | |
5252
|scales |1.3.0 |1.3.0 | |
5353
|shades |1.4.0 |1.4.0 | |
54-
|stringi |1.8.3 |1.8.3 | |
54+
|stringi |1.8.4 |1.8.4 | |
5555
|stringr |1.5.1 |1.5.1 | |
5656
|tibble |3.2.1 |3.2.1 | |
5757
|utf8 |1.2.4 |1.2.4 | |
5858
|vctrs |0.6.5 |0.6.5 | |
5959
|viridisLite |0.4.2 |0.4.2 | |
60-
|withr |2.5.2 |2.5.2 | |
61-
|xfun |0.41 |0.41 | |
62-
|xgboost |1.7.6.1 |1.7.6.1 | |
60+
|withr |3.0.1 |3.0.1 | |
61+
|xfun |0.47 |0.47 | |
62+
|xgboost |1.7.8.1 |1.7.8.1 | |
6363
|xml2 |1.3.6 |1.3.6 | |
6464

6565
# Revdeps

vignettes/geographic.Rmd

+3-17
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,10 @@ params <- list(
7878
learning_rate = 0.2, objective = "reg:squarederror", max_depth = 5, nthread = 1
7979
)
8080
81-
fit <- xgb.train(
82-
params = params,
83-
data = dtrain,
84-
watchlist = list(valid = dvalid),
85-
early_stopping_rounds = 20,
86-
nrounds = 1000,
87-
callbacks = list(cb.print.evaluation(period = 100))
88-
)
81+
fit <- xgb.train(params = params, data = dtrain, nrounds = 200)
8982
```
9083

91-
Let's first study selected SHAP dependence plots, evaluated on the validation dataset with around 2800 observations. Note that we could as well use the training data for this purpose, but it is a bit too large.
84+
Let's first study selected SHAP dependence plots, evaluated on the validation dataset with around 2800 observations. Note that we could as well use (a subset of) the training data for this purpose.
9285

9386
```{r}
9487
sv <- shapviz(fit, X_pred = X_valid)
@@ -139,14 +132,7 @@ ic <- c(
139132
# Modify parameters
140133
params$interaction_constraints <- ic
141134
142-
fit2 <- xgb.train(
143-
params = params,
144-
data = dtrain2,
145-
watchlist = list(valid = dvalid2),
146-
early_stopping_rounds = 20,
147-
nrounds = 1000,
148-
callbacks = list(cb.print.evaluation(period = 100))
149-
)
135+
fit2 <- xgb.train(params = params, data = dtrain2, nrounds = 200)
150136
151137
# SHAP analysis
152138
sv2 <- shapviz(fit2, X_pred = X_valid2)

0 commit comments

Comments
 (0)