Skip to content

Commit a280caa

Browse files
committed
mlRpart method added
1 parent 6f7bcdf commit a280caa

6 files changed

Lines changed: 101 additions & 5 deletions

File tree

DESCRIPTION

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
Package: mlearning
22
Type: Package
3-
Version: 1.1.1
4-
Date: 2022-04-26
3+
Version: 1.2.0
54
Title: Machine Learning Algorithms with Unified Interface and Confusion Matrices
65
Description: A unified interface is provided to various machine learning
76
algorithms like like linear or quadratic discriminant analysis, k-nearest
@@ -20,7 +19,7 @@ Authors@R: c(
2019
email = "kevin.denis@umons.ac.be"))
2120
Maintainer: Philippe Grosjean <phgrosjean@sciviews.org>
2221
Depends: R (>= 3.0.4)
23-
Imports: stats, grDevices, class, nnet, MASS, e1071, randomForest, ipred
22+
Imports: stats, grDevices, class, nnet, MASS, e1071, randomForest, ipred, rpart
2423
Suggests: mlbench, datasets, RColorBrewer, spelling, knitr, rmarkdown, covr
2524
URL: https://www.sciviews.org/mlearning/
2625
BugReports: https://github.com/SciViews/mlearning/issues

NAMESPACE

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import(MASS)
99
import(e1071)
1010
import(randomForest)
1111
import(ipred)
12+
import(rpart)
1213
#import(klaR)
1314
#import(RWeka)
1415

@@ -19,6 +20,7 @@ export(mlRforest)
1920
export(mlKnn)
2021
export(mlLvq)
2122
export(mlNnet)
23+
export(mlRpart)
2224
export(mlSvm)
2325
export(mlNaiveBayes)
2426
#export(mlNaiveBayesWeka)
@@ -67,6 +69,7 @@ S3method(mlRforest, default)
6769
S3method(mlKnn, default)
6870
S3method(mlLvq, default)
6971
S3method(mlNnet, default)
72+
S3method(mlRpart, default)
7073
S3method(mlSvm, default)
7174
S3method(mlNaiveBayes, default)
7275
#S3method(mlNaiveBayesWeka, default)
@@ -78,6 +81,7 @@ S3method(mlKnn, formula)
7881
S3method(mlLvq, formula)
7982
S3method(mlNnet, formula)
8083
S3method(mlSvm, formula)
84+
S3method(mlRpart, formula)
8185
S3method(mlNaiveBayes, formula)
8286
#S3method(mlNaiveBayesWeka, formula)
8387

@@ -88,4 +92,5 @@ S3method(predict, mlKnn)
8892
S3method(predict, mlLvq)
8993
S3method(predict, mlNnet)
9094
S3method(predict, mlSvm)
95+
S3method(predict, mlRpart)
9196
S3method(predict, mlNaiveBayes)

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# mlearning 1.2.0
2+
3+
- The `mlRpart()` function implements `rpart::rpart()` for using decision trees.
4+
15
# mlearning 1.1.1
26

37
- The description is extended.

R/mlearning.R

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,68 @@ prior = object$prior, method = c("plug-in", "predictive", "debiased", "looCV",
626626
stop("unrecognized 'type' (must be 'class', 'membership' or 'both')"))
627627
}
628628

629+
# rpart() from {rpart}
630+
mlRpart <- function(train, ...)
631+
UseMethod("mlRpart")
632+
633+
mlRpart.formula <- function(formula, data, ..., subset, na.action) {
634+
mlearning(formula, data = data, method = "mlRpart", model.args =
635+
list(formula = formula, data = substitute(data),
636+
subset = substitute(subset)), call = match.call(), ...,
637+
subset = subset, na.action = substitute(na.action))
638+
}
639+
640+
mlRpart.default <- function(train, response, ..., .args. = NULL) {
641+
dots <- list(...)
642+
if (is.null(.args.) || !length(.args.)) {
643+
if (!length(response)) {# unsupervised
644+
stop("Unsupervised classification is not possible with mlRpart(), see hclust() instead.")
645+
} else if (is.factor(response)) {
646+
type <- "classification"
647+
} else type <- "regression"
648+
649+
.args. <- list(levels = levels(response),
650+
n = c(intial = NROW(train), final = NROW(train)),
651+
type = type, na.action = "na.pass",
652+
mlearning.call = match.call(), method = "mlRpart")
653+
}
654+
655+
# Combine train + response and use the formula interface which is the only one
656+
data <- train
657+
data$.class <- response
658+
res <- rpart::rpart(.class ~ ., data = data, ...)
659+
res$predicted <- predict(res, type = "class")
660+
661+
# Return a mlearning object
662+
structure(res, formula = .args.$formula, train = train,
663+
response = response, levels = .args.$levels, n = .args.$n, args = dots,
664+
optim = .args.$optim, numeric.only = FALSE, type = .args.$type,
665+
pred.type = c(class = "class", membership = "prob"),
666+
summary = NULL, na.action = .args.$na.action,
667+
mlearning.call = .args.$mlearning.call, method = .args.$method,
668+
algorithm = "recursive partitioning tree",
669+
class = c("mlRpart", "mlearning", "rpart"))
670+
}
671+
672+
predict.mlRpart <- function(object, newdata,
673+
type = c("class", "membership", "both"),
674+
method = c("direct", "cv"), ...) {
675+
676+
type <- as.character(type)[1]
677+
678+
# If method == "cv", delegate to cvpredict()
679+
method <- as.character(method)[1]
680+
if (method == "cv") {
681+
if (!missing(newdata))
682+
stop("cannot handle new data with method = 'cv'")
683+
return(cvpredict(object = object, type = type, ...))
684+
} else {
685+
predict.mlearning(object = object, newdata = newdata,
686+
type = type, ...)
687+
}
688+
}
689+
690+
629691
mlRforest <- function(train, ...)
630692
UseMethod("mlRforest")
631693

man/mlearning.Rd

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
\alias{mlQda.default}
1818
\alias{mlQda.formula}
1919
\alias{predict.mlQda}
20+
\alias{mlRpart}
21+
\alias{mlRpart.default}
22+
\alias{mlRpart.formula}
23+
\alias{predict.mlRpart}
2024
\alias{mlRforest}
2125
\alias{mlRforest.default}
2226
\alias{mlRforest.formula}
@@ -81,6 +85,12 @@ mlQda(train, ...)
8185
prior = object$prior, method = c("plug-in", "predictive", "debiased",
8286
"looCV", "cv"), ...)
8387

88+
mlRpart(train, ...)
89+
\method{mlRpart}{default}(train, response, ..., .args. = NULL)
90+
\method{mlRpart}{formula}(formula, data, ..., subset, na.action)
91+
\method{predict}{mlRpart}(object, newdata, type = c("class", "membership", "both"),
92+
method = c("direct", "cv"), ...)
93+
8494
mlRforest(train, ...)
8595
\method{mlRforest}{default}(train, response, ntree = 500, mtry, replace = TRUE, classwt = NULL, ...)
8696
\method{mlRforest}{formula}(formula, data, ntree = 500, mtry, replace = TRUE, classwt = NULL, ...,
@@ -217,6 +227,7 @@ train(object, ...)
217227
\item{eps}{ double for specifying an epsilon-range to apply laplace smoothing
218228
(to replace zero or close-zero probabilities by 'threshold') for Naive Bayes
219229
predictions. }
230+
\item{.args.}{ Used internally, do not provide anything here. }
220231
}
221232

222233
\value{
@@ -308,6 +319,21 @@ summary(res <- mlQda(Class ~ ., data = HouseVotes84, na.action = na.omit))
308319
confusion(res) # Self-consistency
309320

310321

322+
## Supervised classification using rpart
323+
summary(res <- mlRpart(Species ~ ., data = irisTrain))
324+
plot(res, margin = 0.03, uniform = TRUE)
325+
text(res, use.n = FALSE)
326+
predict(res) # Default type is class
327+
predict(res, type = "membership")
328+
predict(res, type = "both")
329+
confusion(res) # Self-consistency
330+
## Cross-validation prediction is a good choice when there is no test set:
331+
predict(res, method = "cv") # Idem: cvpredict(res)
332+
confusion(res, method = "cv") # Cross-validation for performances estimation
333+
## Evaluation of performances using a separate test set
334+
confusion(predict(res, newdata = irisTest), irisTest$Species) # Test set perfs
335+
336+
311337
## Supervised classification using random forest
312338
summary(res <- mlRforest(Species ~ ., data = irisTrain))
313339
plot(res)

man/mlearning.package.Rd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
\tabular{ll}{
1414
Package: \tab mlearning\cr
1515
Type: \tab Package\cr
16-
Version: \tab 1.0.3\cr
17-
Date: \tab 2017-12-12\cr
16+
Version: \tab 1.2.0\cr
17+
Date: \tab 2022-09-08\cr
1818
License: \tab GPL 2 or above at your convenience.\cr
1919
}
2020
}

0 commit comments

Comments
 (0)