В R аргументы передаются по значению, поэтому нам не нужно ничего копировать - мы уверены, что функции не будут изменять аргументы, которые мы им передаем. И у меня странная проблема с этим. В моей функции KNN я настраиваю параметр k: я передаю аргументы функции cross_validate , которая вызывает функцию KNN ; Я делаю это в цикле и выбираю лучший параметр. Проблема в том, что я получаю ошибку с исходным аргументом после перекрестной проверки: "object 'original_training_set' not found".
if (is.data.frame(training_set))
{
original_training_set <- data.table::copy(training_set)
training_set <- data.matrix(training_set)
}
else
{
if (!is.matrix(training_set))
stop("training_set must be data frame or matrix")
}
print(original_training_set) # here everything's all right
if (is.numeric(k) && k < 1)
{ stop("k must be >= 1") }
else if (k == "all")
{ k <- nrow(training_set) }
else if (is.numeric(k))
{ k <- min(k, ncol(training_set)) }
else if (k == "best_fit")
{
best_k <- 0
best_perc <- 0
source("./source./test.R")
for (i in 1:as.integer(sqrt(nrow(training_set))))
{
perc <- cross_validate(training_set, 5, predict_param, i, metric, weighting_scheme)
if (perc > best_perc)
{
best_k <- i
best_perc <- perc
}
}
perc <- cross_validate(training_set, 5, predict_param, "all", metric, weighting_scheme)
if (perc > best_perc)
best_k <- nrow(training_set)
k <- best_k
}
else
{ stop('k must be one of: numeric, "all", "best_fit"') }
print(original_training_set) # here I get an error
Функция cross_validate возвращает только процент хорошо предсказанных значений, поэтому не будет обновлять матрицу. Первая печать работает нормально, со второй я получаю сообщение об ошибке. Я абсолютно не знаю, почему, поскольку передача по значению должна защищать меня от любых нежелательных изменений. Я даже скопировал ** training_set (** я раньше этого не делал), но получил те же результаты.
EDIT
Содержание теста. R:
cross_validate <- function(dataset, parts, predict_param, k="all", metric="hassanat", weighting_scheme="inverted")
{
percentages <- vector(length=parts)
part_size <- round(nrow(dataset) / parts)
res <- NULL
for (i in 1:parts)
{
if (i != parts)
{
left <- (i - 1) * part_size + 1
right<- i * part_size
predict_set <- dataset[left:right,]
training_set <- dataset[-(left:right),]
}
else
{
left <- (i - 1) * part_size + 1
right <- nrow(dataset)
predict_set <- dataset[left:right,]
training_set <- dataset[-(left:right),]
}
source("./source./main.R")
predicted_set <- knn(training_set, predict_set, predict_param, k, metric, weighting_scheme)
res <- rbind(res, data.frame(predicted_set))
percentages[i] <- round(100*sum(predict_set[, predict_param] == predicted_set[, predict_param]) / nrow(predict_set), digits=3)
}
write.table(res, file="./results.csv", row.names=FALSE, col.names=FALSE, sep=",", quote=FALSE)
mean(percentages)
}
Наименьший воспроизводимый пример не может быть предоставлен, так как мне пришлось бы загружать весь проект (файлы довольно длинные и взаимосвязанные). Все, что я использую до момента ошибки, находится в коде выше. Я просто использую:
mydata <- iris
perc <- cross_validate(mydata, 5, 1, k="best_fit")