Почему R рассматривает этот объект data.frame как список? - PullRequest
1 голос
/ 20 января 2020

Я пытаюсь запустить анализ наименьшего дискриминанта (lda()) для data.frame, который я создал, разделив несколько переменных на дополнительную переменную масштабирования (здесь не показана) в R с использованием пакета MASS. Ниже приведен пример набора данных и пример кода, который я использую, который воспроизводит ошибку.

class   Var1    Var2    Var3    Var4
2   0.732459522 0.973014649 0.612952968 0.127216654
3   0.76692254  0.990230286 0.629448709 0.104675506
2   0.847487002 1.021663778 0.649046794 0.187175043
3   0.823583181 1.050274223 0.673674589 0.170018282
1   0.796279894 1.058458813 0.583702391 0.222320638
2   0.925681255 1.009909166 0.636663914 0.205615194
2   0.627334465 1.074702886 0.59762309  0.23344652
3   0.980376124 1.011447261 0.646770237 0.232215863
3   0.79342723  1.048826291 0.750234742 0.248826291
1   0.960655738 1.042622951 0.6 0.262295082
2   0.963788301 1.005571031 0.590529248 0.233983287
1   1.013157895 1.049342105 0.657894737 0.223684211
2   1.211538462 1.060897436 0.733974359 0.288461538
3   1.25083612  1.023411371 0.759197324 0.311036789
3   0.959196485 1.009416196 0.635907094 0.12868801
1   0.823681936 1.005185825 0.590319793 0.219533276
2   0.777508091 0.998381877 0.624595469 0.165048544
3   0.749114103 0.985825656 0.585400425 0.133947555
1   0.816999133 1.036426713 0.604509974 0.197745013
data<-read.csv("data.csv",header=TRUE)
data_train<-na.omit(data)
scores_train<-data_train[-c(1)]
lda_train<-lda(data_train$class~scores_train,prior = c(1,1,1)/3,CV=TRUE)
scores_test<-data[-c(1)]
lda_test<-predict(lda_train,as.data.frame(scores_test),prior = c(1,1,1)/3)

lda_train<-lda(data_train$class~as.matrix(scores_train),prior = c(1,1,1)/3,CV=TRUE)
class(scores_train)
class(scores_test)

Когда я пытаюсь выполнить lda с использованием набора данных, я получаю следующее сообщение об ошибке.

Error in model.frame.default(formula = data_train$class ~ scores_train) : 
  invalid type (list) for variable 'scores_train'

Я могу заставить данные работать, приведя их в матричный формат, используя as.matrix. Примечательно, что попытка сделать что-то подобное с использованием as.data.frame() и data.frame() не работает. Однако затем, когда я пытаюсь применить результирующую дискриминантную функцию к общему набору данных, я получаю следующее сообщение ...

Error in UseMethod("predict") : 
  no applicable method for 'predict' applied to an object of class "list"

Однако, когда я проверяю класс объектов, использующих class(), он говорит, что оба объекта в формате data.frame. Я проверил набор данных, чтобы увидеть, есть ли какие-нибудь неполные строки или столбцы, которые могут заставить его обрабатывать их как серию списков вместо одного data.frame, но нет пропущенных значений. Точно так же это, кажется, не связано с именами каких-либо переменных.

Я не уверен, почему R рассматривает объект как список вместо data.frame (и тем самым вызывает анализ с наименьшим дискриминантом fail), тем более что он распознает объекты класса data.frame.

Ответы [ 2 ]

3 голосов
/ 20 января 2020

для lda, вы должны указать формулу, поэтому нижеприведенное действие сработает, если вы предоставите фрейм данных:

lda_train<-lda(class ~ .,data=data_train,prior = c(1,1,1)/3,CV=TRUE)

В противном случае, если вы не предоставите формулу, выполните:

lda(grouping=data_train$class,x=data_train[,-1],prior = c(1,1,1)/3, CV=TRUE)

Когда вы используете CV = TRUE, он использует перекрестную проверку с пропуском, чтобы дать вам задний план, но, к сожалению, он не может сохранить модель, и вы можете видеть это:

class(lda_train)
[1] "list"

Чтобы предсказать, вам нужно тренироваться с CV = FALSE. Вы предоставляете data.frame или матрицу, которая имеет тот же столбец, который использовался для обучения, и в вашем случае это будет:

lda_train<-lda(class ~ .,data=data_train,prior = c(1,1,1)/3)
data_test=data.frame(Var1=rnorm(10),Var2=rnorm(10),
Var3=rnorm(10),Var4=rnorm(10))
predict(lda_train,data_test)

Для lda из MASS, нет гиперпараметр, который будет получен во время обучения, так что, может быть, вы хотите уточнить, зачем вам нужна перекрестная проверка?

Если вы хотите изучить ее, вот как вы можете запустить перекрестную проверку для lda ( обратите внимание, используя lda2):

data_train$class =factor(data$class)
lda_train = train(class ~ .,data=data_train,method="lda2",
trControl = trainControl(method = "cv"))
predict(lda_train,data_test)
1 голос
/ 20 января 2020

Аргумент formula ищет структурированную формулу, описывающую, как связаны переменные. Каждая именованная переменная должна быть вектором. Вы можете передать все имена в одном и том же фрейме данных, одновременно объявляя аргумент данных:

lda(class ~ Var1 + Var2 + Var3 + Var4, 
    data = data, prior = c(1,1,1)/3, CV=TRUE)

или передавая столбцы отдельно:

lda(data$class ~ scores_train$Var1 +  
      scores_train$Var2 + 
      scores_train$Var3 + 
      scores_train$Var4, 
    prior = c(1,1,1)/3, CV=TRUE)

Для проблемы predict не принимать его в качестве объекта вам нужно изменить CV на FALSE, в противном случае он возвращает только список (не объект lda, который нужен predict):

model <- lda(data$class ~ scores_train$Var1 +  
      scores_train$Var2 + 
      scores_train$Var3 + 
      scores_train$Var4, 
    prior = c(1,1,1)/3, CV=FALSE)

predict(model)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...