@@ -1312,3 +1312,104 @@ na.action = na.exclude, threshold = 0.001, eps = 0, ...) {
13121312# algorithm = "Weka naive Bayes classifier",
13131313# class = c("mlNaiveBayesWeka", "mlearning", "Weka_classifier"))
13141314# }
1315+
1316+ mlKnn <- function (train , ... )
1317+ UseMethod(" mlKnn" )
1318+
1319+ mlKnn.formula <- function (formula , data , k.nn = 5 , ... , subset , na.action ) {
1320+ mlearning(formula , data = data , method = " mlKnn" , model.args =
1321+ list (formula = formula , data = substitute(data ),
1322+ subset = substitute(subset )), call = match.call(), k.nn = k.nn , ... ,
1323+ subset = subset , na.action = substitute(na.action ))
1324+ }
1325+
1326+ mlKnn.default <- function (train , response , k.nn = 5 , ... ) {
1327+ if (! is.factor(response ))
1328+ stop(" only factor response (classification) accepted for mlKnn" )
1329+
1330+ dots <- list (... )
1331+ .args. <- dots $ .args.
1332+ dots $ .args. <- NULL
1333+ dots $ k.nn <- k.nn
1334+ if (! length(.args. ))
1335+ .args. <- list (levels = levels(response ),
1336+ n = c(intial = NROW(train ), final = NROW(train )),
1337+ type = " classification" , na.action = " na.pass" ,
1338+ mlearning.call = match.call(), method = " mlKnn" )
1339+
1340+ # matrix of numeric values
1341+ if (any(sapply(train , is.factor ))) {
1342+ warning(" force conversion from factor to numeric; may be not optimal or suitable" )
1343+ train <- sapply(train , as.numeric )
1344+ }
1345+
1346+ # Create an object similar to the one obtained with ipred::ipredknn
1347+ res <- list (learn = list (y = response , X = train ))
1348+ res $ k <- k.nn
1349+ class(res ) <- " simpleKnn"
1350+
1351+ # Return a mlearning object
1352+ structure(res , formula = .args. $ formula , train = train ,
1353+ response = response , levels = .args. $ levels , n = .args. $ n , args = dots ,
1354+ optim = .args. $ optim , numeric.only = TRUE , type = .args. $ type ,
1355+ pred.type = c(class = " class" , prob = " prob" ), summary = NULL ,
1356+ na.action = .args. $ na.action ,
1357+ mlearning.call = .args. $ mlearning.call , method = .args. $ method ,
1358+ algorithm = " k-nearest neighbours" ,
1359+ class = c(" mlKnn" , " mlearning" , class(res )))
1360+ }
1361+
1362+ # summary.mlKnn <- function(object, ...)
1363+ # structure(cbind(Class = object$cl, as.data.frame(object$x)),
1364+ # class = c("summary.mlKnn", "data.frame"))
1365+
1366+ # print.summary.mlKnn <- function(x, ...) {
1367+ # cat("Train dataset:\n")
1368+ # print(as.data.frame(x))
1369+ # invisible(x)
1370+ # }
1371+
1372+ predict.mlKnn <- function (object , newdata ,
1373+ type = c(" class" , " prob" , " both" ),
1374+ method = c(" direct" , " cv" ), na.action = na.exclude , ... ) {
1375+ if (! inherits(object , " mlKnn" ))
1376+ stop(" 'object' must be a 'mlKnn' object" )
1377+
1378+ # If method == "cv", delegate to cvpredict()
1379+ method <- as.character(method )[1 ]
1380+ if (method == " cv" ) {
1381+ if (! missing(newdata ))
1382+ stop(" cannot handle new data with method = 'cv'" )
1383+ return (cvpredict(object = object , type = type , na.action = na.action , ... ))
1384+ }
1385+
1386+ # Recalculate newdata according to formula...
1387+ if (missing(newdata ))
1388+ newdata <- object $ learn $ X # Use train
1389+ # Use model.frame but eliminate dependent variable, not required
1390+ # (second item in the formula)
1391+ newdata <- model.frame(formula = attr(object , " formula" )[- 2 ],
1392+ data = newdata , na.action = na.pass )[, names(object $ learn $ X )]
1393+ # Only numerical predictors
1394+ newdata <- sapply(as.data.frame(newdata ), as.numeric )
1395+
1396+ # Determine how many data and perform na.action
1397+ n <- NROW(newdata )
1398+ newdata <- match.fun(na.action )(newdata )
1399+ ndrop <- attr(newdata , " na.action" )
1400+
1401+ if (inherits(object , " simpleKnn" )) {
1402+ res <- class :: knn(object $ learn $ X , newdata , object $ learn $ y , k = object $ k ,
1403+ prob = TRUE )
1404+ } else {# ipred::ipredknn
1405+ res <- ipred :: predict.ipredknn(object , newdata , type = " class" )
1406+ }
1407+ type <- as.character(type [1 ])
1408+ if (type == " prob" ) {
1409+ return (attr(res , " prob" ))
1410+ } else if (type == " class" ) {
1411+ attr(res , " prob" ) <- NULL
1412+ }
1413+
1414+ .expandFactor(res , n , ndrop )
1415+ }
0 commit comments