paobranco / ubl Goto Github PK
View Code? Open in Web Editor NEWAn R package for utility-based learning
An R package for utility-based learning
Hi!
Thanks for making the UBL package available to all.
I had a problem with the package, but it was just a typo.
I could not figure out how to delete the issue I opened, so I will just use it to greet the world, and send special cheers to the UBL authors, the vaccine developers and all people who have improved my mood in these pandemic days with funny videos and memes!!!
Thanks for your research article on regression tasks for " UBL: an R Package for Utility-Based Learning". It helps me a lot!!!
I wonder how to handle with multiple target values resampling. For all examples in your article refer to one target value. So i tried to use your package to resample data with one target each time. But after resampling, the data amount is different when i use different target value.I want to how to solve it!
Looking forward to your reply!
Hi,
Thanks for such great package!
With my data set and following the code example in the documentation, I bumped into this error message:
Please, redefine your relevance function
I could not understand what is the meaning of this message. I am using R 3.6.3 on a windows machine and UBL 0.0.6
I attached a copy of the script and input data.
Thanks for your help,
Ivan
Hi,
I've been trying to use the UBL package for data balancing in a medium sized dataset. The data has 96 mixed variables and an output variable that is an ordered factor:
> str(hd2)
'data.frame': 3244 obs. of 97 variables:
$ FUNC_STAT_TCR : int 1 2 996 2 2 996 996 996 996 996 ...
$ REGION : Factor w/ 11 levels "1","2","3","4",..: 2 1 4 4 2 5 4 3 11 10 ...
.
.
.
$ ANTICONV_DON : Factor w/ 2 levels "N","Y": 1 1 1 1 1 1 1 1 1 1 ...
$ GENDER : Factor w/ 2 levels "F","M": 2 2 1 2 2 2 2 2 2 2 ...
$ HIST_HYPERTENS_DON : Factor w/ 2 levels "N","Y": 1 1 1 2 1 2 1 1 2 1 ...
$ MALIG : Factor w/ 2 levels "N","Y": 1 2 1 1 1 1 1 1 1 1 ...
$ LIFE_SUP : Factor w/ 2 levels "N","Y": 1 2 2 1 1 1 2 2 2 2 ...
$ OUTPUT : Ord.factor w/ 5 levels "y0y0.25"<"y0.25y1"<..: 5 4 4 5 5 1 1 5 5 1 ...
GaussNoiseClassif
works well with this data, but SmoteClassif
keeps giving me warnings:
Warning messages:
1: In if (class(data[, tgt]) == "numeric" & p <= -4) stop("distance measure selected only available for classification tasks") :
the condition has length > 1 and only the first element will be used
2: In if (class(data[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
3: In if (class(tgtData) != "numeric") { :
the condition has length > 1 and only the first element will be used
4: In if (class(data[, tgt]) == "numeric" & p <= -4) stop("distance measure selected only available for classification tasks") :
the condition has length > 1 and only the first element will be used
5: In if (class(data[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
6: In if (class(tgtData) != "numeric") { :
the condition has length > 1 and only the first element will be used
7: In if (class(data[, tgt]) == "numeric" & p <= -4) stop("distance measure selected only available for classification tasks") :
the condition has length > 1 and only the first element will be used
8: In if (class(data[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
9: In if (class(tgtData) != "numeric") { :
the condition has length > 1 and only the first element will be used
I've tried both HEOM and HVDM and both give the same warnings. The warnings themselves arent a big problem. The real problem is when I try to use SmoteClassif
with caret
sampling. I've created this function:
ublsmote <- list(name = "Custom SMOTE",
func = function (x, y) {
set.seed(1001)
library(UBL)
dat <- if (is.data.frame(x)) x else as.data.frame(x)
dat$.y <- y
dat <- SmoteClassif(.y ~ ., dat = dat, C.perc = "balance", dist = "HEOM")
list(x = dat[, !grepl(".y", colnames(dat), fixed = TRUE)],
y = dat$.y)
},
first = TRUE)
A similar function with GaussNoiseClassif
works fine, but with smote, it crashes the R session. I'll highly appreciate any guidance on how to get rid of this error.
Hi guys, I got the following error:
"The percentages provided must be the same length as the number of bumps!"
as I utilize a custom relevance function and C.perc arguments. The documentation does not say anything about bumbs.
The connection between relevance function and bumbs is still not clear to me, because the error occurs when I change the following line:
from:
s <- boxplot.stats(data$y)$stats
rel <- matrix(0, ncol = 3, nrow = 0)
# line of interest
rel <- rbind(rel, c(0.9*s[1], 0.6, 0))
# end line of interest
rel <- rbind(rel, c(s[2], 1, 0))
rel <- rbind(rel, c(0.9*s[3],1,0))
rel <- rbind(rel, c(s[4],0,0))
into:
s <- boxplot.stats(data$y)$stats
rel <- matrix(0, ncol = 3, nrow = 0)
# line of interest
rel <- rbind(rel, c(0.9*s[1], 0.2, 0))
# end line of interest
rel <- rbind(rel, c(s[2], 1, 0))
rel <- rbind(rel, c(0.9*s[3],1,0))
rel <- rbind(rel, c(s[4],0,0))
So my original intention is to reduce the relevance of point 0.9*s[1] from the value 0.6 to anything else. However, WERCSRegress now counts a different number of classes. That makes no sense to me. Can you might give an explaination what's the issue here?
The number of bumbs seems somehow related to number of elements consisted by C.perp list argument.
However, the number of points in my relevance functions never equals the number of elements in C.perc.
The function takes offense at the value of relevance, which I should actually be able to determine freely.
set.seed(123)
test <-WERCSRegress(frml, data,
rel = rel, thr.rel = 0.6, O = 0.8, U = 0.0,
C.perc = list(2.5,0.2))
At the time of loading the UBL package, it shows the following warning:
Loading required package: MBA
Loading required package: gstat
The legacy packages maptools, rgdal, and rgeos, underpinning the sp package,
which was just loaded, will retire in October 2023.
Please refer to R-spatial evolution reports for details, especially
https://r-spatial.org/r/2023/05/15/evolution4.html.
It may be desirable to make the sf package available;
package maintainers should consider adding sf to Suggests:.
The sp package is now running under evolution status 2
(status 2 uses the sf package in place of rgdal)
Loading required package: automap
Loading required package: sp
Loading required package: randomForest
randomForest 4.7-1.1
I think the "sf" package should be updated instead of the "sp" package
Lines 228 to 232 in e796812
This part of the code does not seem to be correct, because d1 and d2 are overwritten in every iteration of the loop. Am I mistaken?
SmoteRegress may have some difficulty succeeding on some numeric features.
xy <- data.frame(x = 1:100, y = 1:100)
SmoteRegress(y ~ ., xy)
Error in SmoteRegress(y ~ ., xy) : All the points have relevance 0.
Please, redefine your relevance function!
SmoteRegress may have some difficulty succeeding on some numeric nominal and numeric features.
data("diamonds", package = "ggplot2")
SmoteRegress(z ~ ., diamonds)
Error in neighbours(tgt, dat, dist, p, k) :
NA/NaN/Inf in foreign function call (arg 2)
In addition: Warning messages:
1: In if (class(dat[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
2: In if (class(dat[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
3: In if (class(dat[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
4: In if (class(dat[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
5: In if (class(dat[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
6: In if (class(dat[, col]) %in% c("factor", "character")) { :
the condition has length > 1 and only the first element will be used
7: In storage.mode(numData) <- "double" : NAs introduced by coercion
May have some difficulty succeeding on some numeric nominal features.
SmoteRegress(cut ~ ., diamonds[,c("cut","color","clarity")])
Error in if (extr$stats[3] != r[1]) { :
missing value where TRUE/FALSE needed
In addition: Warning message:
In Ops.ordered(x[floor(d)], x[ceiling(d)]) :
'+' is not meaningful for ordered factors
Another challenge.
diamonds2 <- diamonds
diamonds2$cut <- factor(diamonds2$cut, ordered = FALSE)
diamonds2$color <- factor(diamonds2$color, ordered = FALSE)
diamonds2$clarity <- factor(diamonds2$clarity, ordered = FALSE)
SmoteRegress(cut ~ ., diamonds2[,c("cut","color","clarity")])
Error in Summary.factor(c(5L, 4L, 2L, 4L, 2L, 3L, 3L, 3L, 1L, 3L, 2L, :
'range' not meaningful for factors
In addition: Warning message:
In Ops.factor(x[floor(d)], x[ceiling(d)]) : '+' not meaningful for factors
SmoteRegress(z ~ ., diamonds2[,c("cut","color","clarity","z")])
Error in neighbours(tgt, dat, dist, p, k) :
Can not compute Euclidean distance with nominal attributes!
SmoteRegress(z ~ ., diamonds2[,c("cut","color","clarity","y","z")], rel = "HEOM")
Error in SmoteRegress(z ~ ., diamonds2[, c("cut", "color", "clarity", :
future work!
> SmoteRegress(cut ~ ., diamonds2[,c("cut","y","z")], rel = "HEOM")
Error in SmoteRegress(cut ~ ., diamonds2[, c("cut", "y", "z")], rel = "HEOM") :
future work!
> devtools::session_info()
Session info ------------------------------------------------------------------
setting value
version R version 3.4.4 (2018-03-15)
system x86_64, mingw32
ui RTerm
language (EN)
collate English_United States.1252
tz America/Chicago
date 2018-03-17
Packages ----------------------------------------------------------------------
package * version date source
automap * 1.0-14 2013-08-29 CRAN (R 3.4.0)
base * 3.4.4 2018-03-15 local
compiler 3.4.4 2018-03-15 local
datasets * 3.4.4 2018-03-15 local
devtools 1.13.5 2018-02-18 CRAN (R 3.4.3)
digest 0.6.15 2018-01-28 CRAN (R 3.4.3)
FNN 1.1 2013-07-31 CRAN (R 3.4.0)
graphics * 3.4.4 2018-03-15 local
grDevices * 3.4.4 2018-03-15 local
grid 3.4.4 2018-03-15 local
gstat * 1.1-5 2017-03-12 CRAN (R 3.4.0)
intervals 0.15.1 2015-08-27 CRAN (R 3.4.0)
lattice 0.20-35 2017-03-25 CRAN (R 3.4.4)
magrittr * 1.5 2014-11-22 CRAN (R 3.4.0)
MBA * 0.0-9 2017-03-08 CRAN (R 3.4.1)
memoise 1.1.0 2017-04-21 CRAN (R 3.4.0)
methods * 3.4.4 2018-03-15 local
plyr 1.8.4 2016-06-08 CRAN (R 3.4.0)
randomForest * 4.6-12 2015-10-07 CRAN (R 3.4.0)
Rcpp 0.12.16 2018-03-13 CRAN (R 3.4.3)
reshape 0.8.7 2017-08-06 CRAN (R 3.4.1)
sp * 1.2-7 2018-01-19 CRAN (R 3.4.3)
spacetime 1.2-1 2017-09-24 CRAN (R 3.4.1)
stats * 3.4.4 2018-03-15 local
tools 3.4.4 2018-03-15 local
UBL * 0.0.6 2017-07-13 CRAN (R 3.4.1)
utils * 3.4.4 2018-03-15 local
withr 2.1.2 2018-03-15 CRAN (R 3.4.3)
xts 0.10-2 2018-03-14 CRAN (R 3.4.3)
zoo 1.8-1 2018-01-08 CRAN (R 3.4.3)
>
Hi,
I have used AdasynClassif function for several times without any problem. But now I experienced weird behavior. I got this error:
"Error in matrix(nrow = sum(unlist(g)), ncol = nC) : invalid 'nrow' value (too large or NA)"
It’s only happening for some combination of samples and features (please find attached - "a","b" and "c" are features and "target" is class, baseClass = 4). Additionally, setting different base class has an effect on it. I wanted to dive deeper into the function and find out what’s going on, but I couldn’t figure out from where class.freq function came from.
(That’s another mystery for me, how is it possible that AdasynClassif is running without having installed a package with class.freq function?)
ADAS_examples.zip
Perhaps I'm missing something but it appears the distances of the numeric variables are not accumulating and only the distance of the last column is stored in d1
and d2
before moving on:
Line 265 in ce3789c
Shouldn't that be d1 <- d1 + abs(T[i, x] - newM[(i - 1) * nexs + n, x])/ranges[x]
? Likewise for d2?
Hi,
I have a question. When I generate new data or replicated data using UBL functions, does the new/replicated data ever get created out side the range of the original data?
For example, if my input data is, for example, 2 values, 1 and 10, if I use an UBL function, e.g. SmoteRegress or other, does any new data get created outside the range of 1 and 10, for example, new data at 0.5 or 10.5?
This is important because, in, for example, a time series, the train data, test data, and validation data can not leak into any of each others areas, for example test data leaking into validation data, for example new generated train data at 10.5 would have leaked into the test area.
If new data is created at 10.5, is there an easy-early way to detect (or better: prevent), this from happening?
The example code doesn't work if you change the target from Sepal.Width to any other variables. For example, change to Sepal.Length:
smoteBalan.iris <- SmoteRegress(Sepal.Length~., ir, dist = "HEOM",
C.perc = "balance")
It returns:
> smoteBalan.iris <- SmoteRegress(Sepal.Length~., ir, dist = "HEOM",
+ C.perc = "balance")
Error in SmoteRegress(Sepal.Length ~ ., ir, dist = "HEOM", C.perc = "balance") :
All the points have relevance 0.
Please, redefine your relevance function!
Execution halted
I think maybe it is a problem of the probability distribution? Because Sepal.Length is the only variable that looks continuous in the whole domain:
But I'm not sure what exactly happens. Please give me some hint.
Hello Paula
Thanks for this very helpful piece of software.I have been looking for quite sometime for software to generate synthetic data for regression problems. I have one question. Suppose i have a highly imbalanced high dimensional data set and trying to predict a continuous value, how can i achieve this with UBL ? more details here in my question
i see that using the R functions, GaussianNoise, RandomOverSampline, Undersampling like:
mygn.alg=GaussNoiseRegress(clean.algae$a7~., clean.algae, C.perc="balance")
generates a subset from the original data whose values are the same as the original data sample. I was hoping that, the functions generate synthetic data in bins where data distribution is less or even nil. Is this achievable using UBL? can you please give an example of the same?
Thank you.
Thanks for all your work on this useful package! I was surprised to see that Euclidean distance could not be used on a formula that contained only numeric variables. The function seems to care if the dataset contains factors, even when they're not used in the formula. That may be as designed, so I'm just reporting this in case you view it as an error.
library("UBL")
Loading required package: MBA
Loading required package: gstat
Registered S3 method overwritten by 'xts':
method from
as.zoo.xts zoo
Loading required package: automap
Loading required package: sp
Loading required package: randomForest
randomForest 4.6-14
Type rfNews() to see new features/changes/bug fixes.
library(MASS)
data(cats)
head(cats)
Sex Bwt Hwt
1 F 2.0 7.0
2 F 2.0 7.4
3 F 2.0 9.5
4 F 2.1 7.2
5 F 2.1 7.3
6 F 2.1 7.6
length(cats$Sex)
[1] 144I'm adding a factor for color:
cats$color <- gl(n = 2, k=1, length = 144, label = c("black","white") )
head(cats)
Sex Bwt Hwt color
1 F 2.0 7.0 black
2 F 2.0 7.4 white
3 F 2.0 9.5 black
4 F 2.1 7.2 white
5 F 2.1 7.3 black
6 F 2.1 7.6 whiteI'm not using color, but it yields an error message anyway:
mysmote.cats <- SmoteClassif(Sex ~ Bwt + Hwt, cats, list(M = 0.8, F = 1.8))
Error in neighbours(tgt, dat, dist, p, k) :
Can not compute Euclidean distance with nominal attributes!HEOM fixes it:
mysmote.cats <- SmoteClassif(Sex ~ Bwt + Hwt, cats, list(M = 0.8, F = 1.8), dist = "HEOM")
sessionInfo()
R version 3.6.2 (2019-12-12)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] UBL_0.0.6 randomForest_4.6-14 automap_1.0-14 sp_1.3-2 gstat_2.0-4
[6] MBA_0.0-9 MASS_7.3-51.4 devtools_2.2.1 usethis_1.5.1
loaded via a namespace (and not attached):
[1] Rcpp_1.0.3 plyr_1.8.5 compiler_3.6.2 prettyunits_1.1.1 remotes_2.1.0 tools_3.6.2
[7] xts_0.11-2 testthat_2.3.1 digest_0.6.23 pkgbuild_1.0.6 pkgload_1.0.2 memoise_1.1.0
[13] lattice_0.20-38 rlang_0.4.4 cli_2.0.1.9000 rstudioapi_0.10 curl_4.3 withr_2.1.2
[19] desc_1.2.0 fs_1.3.1 rprojroot_1.3-2 grid_3.6.2 reshape_0.8.8 spacetime_1.2-2
[25] glue_1.3.1 R6_2.4.1 processx_3.4.1 fansi_0.4.1 sessioninfo_1.1.1 callr_3.4.0
[31] magrittr_1.5 intervals_0.15.1 backports_1.1.5 ps_1.3.0 ellipsis_0.3.0 assertthat_0.2.1
[37] FNN_1.1.3 crayon_1.3.4 zoo_1.8-7
I got this error running SmoteClassif(). I'm trying to understand this error so I can work around the issue. Is there a function I could use where given the number of columns in the dataset and various parameter settings of the function, it would provide the maximum number of rows I could have in my dataset for the function to work (i.e. not pass long vectors to Fortran)? Understanding this would help me scale my analysis.
For what it's worth I just asked the question on stackexchange as well. It provides an example of the problem I encountered. In short, the function worked with ~357,000 rows/~150 columns but fails with ~186,000 rows/~190 columns -- which made me wonder about the math behind the function that influences the vector lengths. Thanks so much for any input you may have and for providing a such a great function!
great code
but do you know python implementation for UBL ?
I have a dataset by which I am interest to apply SMOGN/SMOTER to it. The dataset has both numerical and nominal features. I am using machine learning models from sklearn and keras (yes in python, I am using rpy2 to apply SMOGN/SMOTER for communication between R and python) and they expect no strings at all in the data. Thats why I convert my nominal features to one hot encodings. However If I use 'HEOM' distance, noise is added and instead of having vectors of either 1 or 0 I am having 1.00001, 0.999, etc. How can I fix this ?? Please find below a snapshot of a 'SMOGN'-ed dataset:
The one hot encoded vectors are from columns service_General Medicine --> mohafaza_NE
I found your UBL package. This is helping me a lot. However, I am having problems with the HVDM distance with nominal features. I looked at the code on github, I did a lot of testing, but I can't understand what's going on. Attached I am sending some tests I did to understand. The distance values are not what I expected. Could you help me understand what's going on?
Code
col1 <- factor(c("a", "a", "c", "c"))
col2 <- factor(c("b", "d", "d", "g"))
col3 <- factor(c("c", "b", "e", "h"))
col4 <- factor(c("x", "x", "y", "y"))
df <- data.frame(col1, col2, col3, col4)
dist2 <- distances(4, df, "HVDM")
dist2
Hello,
The caret and recipes libraries allow one to define customised evaluation metrics for models. I am trying to combine UBL::EvalRegressMetrics with the workflow using caret and recipes.
I was wondering if you (or anyone) has had any success with this, or would be able to comment on my attempts (using glmnet).
I define the following functions:
return.phi<-function(dat, control.parms=phiF.argsR){
#Inputs:
#dat: vector
#control.parms: matrix definining relevance surface
# output:
# phi: phi value for each point in da
dat_sort<-sort(dat)
idx<-rank(dat)
phi <- phi(dat_sort,control.parms = phiF.argsR)
phi <- phi[idx]
return(phi)
}
And model_stats to be evaluated in the form required by recipe (see https://topepo.github.io/caret/using-recipes-with-train.html)
model_stats <- function(data, lev = NULL, model = NULL) {
#Adds EvalRegressMetrics to defaultSummary
stats <- defaultSummary(data, lev = lev, model = model)
utils=UBL::EvalRegressMetrics(data$pred, data$obs, util.vals=data$utility )
c(FPhi = utils$FPhi, totUtil=utils$totUtil, MUtil=utils$MUtil, stats)
}
Then applying to Boston data
require(glmnet)
library(recipes)
library(caret)
library(UBL)
data(Boston, package = "MASS")
#Create utility surface
phiF.argsR <- phi.control(Boston[,tgt], method="extremes", extr.type="both")
#train/test split
tgt <- which(colnames(Boston) == "medv")
set.seed(101)
sp <- sample(1:nrow(Boston), as.integer(0.7*nrow(Boston)))
train <- Boston[sp,]
test <- Boston[-sp,]
#Add utility for each data point based on tgt
train <- train %>%
mutate(utility = return.phi(medv, control.parms=phiF.argsR))
#Define recipe
tr_recipe <- recipe(medv ~ ., data = train) %>%
add_role(utility, new_role="performance var") %>%
step_center(all_predictors()) %>%
step_scale(all_predictors())
tr_recipe
head(train)
glmnet_control<-trainControl(method="cv",
number=10,
savePredictions = "all",
summaryFunction = model_stats)
#Fit the model using the recipe
set.seed(1)
glmnet_fit<-train(tr_recipe, data=train,
method="glmnet",
trControl=glmnet_control,
metric=c("MUtil")
)
glmnet_fit$results
While the default measures such as RMSE vary for the different models tested, the EvalRegressMetrics are constant over models.
This has been the case for various models and datasets that I have tested.
I am uncertain if my problems lie in UBL, caret, or recipes. But if you do have any thoughts as to what might be generating this behaviour, it would be much appreciated.
Thanks
Iris
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.