Skip to content

Commit 462137a

Browse files
committed
codex code review
1 parent c4dcfe3 commit 462137a

File tree

5 files changed

+60
-11
lines changed

5 files changed

+60
-11
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Added support for internal validation tasks to `PipeOpFeatureUnion`.
77
* feat: `PipeOpLearnerCV` can reuse the cross-validation models during prediction by averaging their outputs (`resampling.predict_method = "cv_ensemble"`).
88
* feat: `PipeOpRegrAvg` gets new `se_aggr` and `se_aggr_rho` hyperparameters and now allows various forms of SE aggregation.
9+
* Fix: `PipeOpInfo` now prints a bounded task preview (respecting target/feature ordering and row ids) and collapses logger output to single messages.
10+
* Fix: `PipeOpIsomap` only operates on numeric or integer features and its parameter documentation was corrected.
911

1012
# mlr3pipelines 0.9.0
1113

R/PipeOpInfo.R

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,13 @@ PipeOpInfo = R6Class("PipeOpInfo",
8282
)
8383
original_printer = list(
8484
Task = crate(function(x) {
85-
list(task = x, data = x$data()[, 1:min(10, ncol(x$data()))])
85+
row_preview = head(x$row_ids, 10L)
86+
col_preview = head(c(x$target_names, x$feature_names), 10L)
87+
data_preview = x$data(rows = row_preview, cols = col_preview)
88+
list(
89+
task = x,
90+
data_preview = data_preview
91+
)
8692
}),
8793
Prediction = crate(function(x) {
8894
tryCatch(list(prediction = x, score = x$score()), error = function(e) {list(prediction = x)})
@@ -108,7 +114,7 @@ PipeOpInfo = R6Class("PipeOpInfo",
108114
.printer = NULL,
109115
.log_target = NULL,
110116
.output = function(inputs, stage) {
111-
input_class = class(inputs[[1]])
117+
input_class = class(inputs[[1]])
112118
leftmost_class =
113119
if (any(input_class %in% names(private$.printer))) {
114120
input_class[input_class %in% names(private$.printer)][[1]]
@@ -125,19 +131,20 @@ PipeOpInfo = R6Class("PipeOpInfo",
125131
cat(stage_string, "\n\n")
126132
specific_printer(inputs[[1]])
127133
})
134+
message_text = paste(print_string, collapse = "\n")
128135
if (log_target_split[[1]] == "lgr") {
129136
logger = lgr::get_logger(log_target_split[[2]])
130137
log_level = log_target_split[[3]]
131-
logger$log(log_level, msg = print_string)
138+
logger$log(log_level, msg = message_text)
132139
} else if (private$.log_target == "cat") {
133-
cat(paste(print_string, collapse = "\n"))
140+
cat(message_text)
134141
} else if (private$.log_target == "message") {
135-
message(paste(print_string, collapse = "\n"))
142+
message(message_text)
136143
} else if (private$.log_target == "warning") {
137-
warning(paste(print_string, collapse = "\n"))
144+
warning(message_text)
138145
} else if (private$.log_target == "none") {
139146
} else {
140-
stopf("Invalid log_target '%s'.", log_target)
147+
stopf("Invalid log_target '%s'.", private$.log_target)
141148
}
142149
},
143150
.train = function(inputs, stage = "Training") {

R/PipeOpIsomap.R

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,18 @@
3333
#'
3434
#' @section Parameters:
3535
#' The parameters are the parameters inherited from [`PipeOpTaskPreproc`], as well as:
36-
#' * `knn` :: `numeric(1)`\cr
36+
#' * `knn` :: `integer(1)`\cr
3737
#' The number of nearest neighbors in the graph.
3838
#' Initialized to 50.
39-
#' * `ndim` :: `numeric(1)`\cr
39+
#' * `ndim` :: `integer(1)`\cr
4040
#' The number of embedding dimensions.
4141
#' Initialized to 2.
4242
#' * `get_geod` :: `logical(1)`\cr
4343
#' Determines whether the distance matrix should be kept in the `$state`.
4444
#' Initialized to `FALSE`.
4545
#' * `.mute` :: `character`\cr
4646
#' A character vector of elements to mute during training (e.g. c("message", "output")).
47-
#' Default: `character(0)`.
47+
#' Initialized to `NULL`.
4848
#'
4949
#' @section Internals:
5050
#' Applies the Isomap embedding from the `dimRed`-package.
@@ -78,7 +78,8 @@ PipeOpIsomap = R6Class("PipeOpIsomap",
7878
get_geod = p_lgl(default = FALSE, tags = c("train", "isomap")),
7979
.mute = p_uty(init = NULL, tags = c("train", "isomap"))
8080
)
81-
super$initialize(id = id, param_set = ps, param_vals = param_vals, packages = c("dimRed", "stats"))
81+
super$initialize(id = id, param_set = ps, param_vals = param_vals,
82+
packages = c("dimRed", "stats"), feature_types = c("numeric", "integer"))
8283
}
8384
),
8485
private = list(

tests/testthat/test_pipeop_info.R

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,12 @@ test_that("logger is addressed when log_target is set to a logger", {
6666
for (j in input) {
6767
poinfo$train(list(j))
6868
logfile_posttrain = appender_buffer$data$msg
69+
expect_equal(length(logfile_posttrain), 1L)
6970
expect_match(logfile_posttrain, "Object passing through PipeOp info - Training", all = FALSE)
7071
appender_buffer$flush()
7172
poinfo$predict(list(j))
7273
logfile_postprediction = appender_buffer$data$msg
74+
expect_equal(length(logfile_postprediction), 1L)
7375
expect_match(logfile_postprediction, "Object passing through PipeOp info - Prediction", all = FALSE)
7476
appender_buffer$flush()
7577
}
@@ -103,6 +105,19 @@ test_that("PipeOp recognizes class of input objects and prints information accor
103105
}
104106
})
105107

108+
test_that("Task printer only displays a preview", {
109+
task = tsk("iris")
110+
poinfo = po("info")
111+
preview = poinfo$printer$Task(task)
112+
row_preview = head(task$row_ids, 10L)
113+
col_preview = head(c(task$target_names, task$feature_names), 10L)
114+
expect_true(is.list(preview))
115+
expect_identical(names(preview), c("task", "data_preview"))
116+
expect_identical(preview$task, task)
117+
expect_equal(preview$data_preview,
118+
task$data(rows = row_preview, cols = col_preview))
119+
})
120+
106121
test_that("malformed log_target handled accordingly", {
107122
malformed_log_target = list("malformed", "::", "::::::", "log::", "log::log_level", "log::log_level::", "log::log_level::message::", "::log")
108123
for (i in seq_along(malformed_log_target)) {

tests/testthat/test_pipeop_isomap.R

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ context("PipeOpIsomap")
22

33
test_that("PipeOpIsomap - basic properties", {
44
skip_if_not_installed("dimRed")
5+
skip_if_not_installed("RSpectra")
56
skip_if_not_installed("stats")
67
op = po("isomap", .mute = "message")
78
task = mlr_tasks$get("iris")
@@ -11,6 +12,7 @@ test_that("PipeOpIsomap - basic properties", {
1112

1213
test_that("compare to dimRed::isomap", {
1314
skip_if_not_installed("dimRed")
15+
skip_if_not_installed("RSpectra")
1416
skip_if_not_installed("stats")
1517
# Part 1 - Train-method
1618
# Version 1 - PipeOpIsomap
@@ -40,15 +42,35 @@ test_that("compare to dimRed::isomap", {
4042

4143
test_that("isomap algorithm requires data to be numeric", {
4244
skip_if_not_installed("dimRed")
45+
skip_if_not_installed("RSpectra")
4346
skip_if_not_installed("stats")
4447
po = po("isomap")
4548
task = tsk("penguins")
4649
task$filter(which(complete.cases(task$data())))
4750
expect_error(po$train(list(task)))
4851
})
4952

53+
test_that("isomap leaves non-numeric features untouched", {
54+
skip_if_not_installed("dimRed")
55+
skip_if_not_installed("RSpectra")
56+
skip_if_not_installed("stats")
57+
backend = data.table::as.data.table(tsk("iris")$data())
58+
backend$species_factor = factor(rep(letters[1:3], length.out = nrow(backend)))
59+
task = mlr3::TaskClassif$new("iris_factor", backend = backend, target = "Species")
60+
po = po("isomap", ndim = 3)
61+
trained_task = po$train(list(task))[[1]]
62+
predicted_task = po$predict(list(task))[[1]]
63+
64+
expect_true("species_factor" %in% trained_task$feature_names)
65+
expect_equal(trained_task$data(cols = "species_factor"), task$data(cols = "species_factor"))
66+
expect_equal(predicted_task$data(cols = "species_factor"), task$data(cols = "species_factor"))
67+
expect_equal(sum(grepl("^iso ", trained_task$feature_names)), 3L)
68+
expect_equal(sum(grepl("^iso ", predicted_task$feature_names)), 3L)
69+
})
70+
5071
test_that("hyperparameter ndim", {
5172
skip_if_not_installed("dimRed")
73+
skip_if_not_installed("RSpectra")
5274
skip_if_not_installed("stats")
5375
for (i in seq_len(length(tsk("iris")$feature_names))) {
5476
po = po("isomap", ndim = i)
@@ -59,6 +81,7 @@ test_that("hyperparameter ndim", {
5981

6082
test_that("hyperparameter get_geod", {
6183
skip_if_not_installed("dimRed")
84+
skip_if_not_installed("RSpectra")
6285
skip_if_not_installed("stats")
6386
# Check 1 - get_geod = FALSE behaves as expected
6487
po_no_geod = po("isomap", get_geod = FALSE)
@@ -76,6 +99,7 @@ test_that("hyperparameter get_geod", {
7699

77100
test_that("hyperparameter .mute", {
78101
skip_if_not_installed("dimRed")
102+
skip_if_not_installed("RSpectra")
79103
skip_if_not_installed("stats")
80104
po = po("isomap", .mute = c("message", "output"))
81105
# expect_silent(po$train(list(tsk("iris")))) # does not work because of testthat #1480

0 commit comments

Comments
 (0)