Линейная регрессия с разделением LOOCV в R возвращает ошибку - PullRequest
0 голосов
/ 10 июля 2019

Я попытался подогнать линейную модель, используя Оставить одно разделение перекрестной проверки.

Я использовал это DATASET , набор данных имеет 517 строк и 13 столбцов(две из них являются категориальными переменными).Зависимая переменная - это «площадь».

Я хотел бы построить модель с категориальными переменными и без них.Затем рассчитать средние коэффициенты.Когда я удалил категориальные переменные, код работает нормально, но когда я их сохранил, я получил следующую ошибку "Ошибка в estcoef [i,] <- coef (model1): количество заменяемых элементов некратная длины замены "</em>

Мой код выглядит следующим образом

wdbc<- read.csv("forestfires.csv") ## upload the dataset
wdbc<-wdbc[-(3:4)] ## If I want to build the model without the catogrical variables
#####################################

fitted_value <- rep(0,nrow(wdbc))
estcoef<-matrix(0,nrow=nrow(wdbc),ncol=ncol(wdbc)) #estimation coefficients

# LOOCV split leave one out cross validation 
for(i in 1:nrow(wdbc)){
  validation<-wdbc[i,]
  training<-wdbc[-i,]
  model1<-lm(area ~ ., data = training)
  fitted_value[i] <- predict(model1, newdata = validation) 
  estcoef[i,]<-coef(model1) 
}

meancoef<-colMeans(estcoef) #coefficent means

Может ли кто-нибудь помочь мне с этой проблемой, пожалуйста?

Ярады предоставить любую другую дополнительную информацию.

ОБНОВЛЕНО

Я включил первые 10 строк своих данных

  X Y month day FFMC   DMC    DC  ISI temp RH wind rain area
1  7 5   mar fri 86.2  26.2  94.3  5.1  8.2 51  6.7  0.0    0
2  7 4   oct tue 90.6  35.4 669.1  6.7 18.0 33  0.9  0.0    0
3  7 4   oct sat 90.6  43.7 686.9  6.7 14.6 33  1.3  0.0    0
4  8 6   mar fri 91.7  33.3  77.5  9.0  8.3 97  4.0  0.2    0
5  8 6   mar sun 89.3  51.3 102.2  9.6 11.4 99  1.8  0.0    0
6  8 6   aug sun 92.3  85.3 488.0 14.7 22.2 29  5.4  0.0    0
7  8 6   aug mon 92.3  88.9 495.6  8.5 24.1 27  3.1  0.0    0
8  8 6   aug mon 91.5 145.4 608.2 10.7  8.0 86  2.2  0.0    0
9  8 6   sep tue 91.0 129.5 692.6  7.0 13.1 63  5.4  0.0    0
10 7 5   sep sat 92.5  88.0 698.6  7.1 22.8 40  4.0  0.0    0

Я также включил последние 10 строк, которые показывают, что у нас есть только одна строка с месяцем = ноябрь (последняя строка), которая возвращает ошибки даже с предоставленным ответом.

> tail(wdbc,10)
    X Y month day FFMC   DMC    DC  ISI temp RH wind rain  area
508 2 4   aug fri 91.0 166.9 752.6  7.1 25.9 41  3.6  0.0  0.00
509 1 2   aug fri 91.0 166.9 752.6  7.1 25.9 41  3.6  0.0  0.00
510 5 4   aug fri 91.0 166.9 752.6  7.1 21.1 71  7.6  1.4  2.17
511 6 5   aug fri 91.0 166.9 752.6  7.1 18.2 62  5.4  0.0  0.43
512 8 6   aug sun 81.6  56.7 665.6  1.9 27.8 35  2.7  0.0  0.00
513 4 3   aug sun 81.6  56.7 665.6  1.9 27.8 32  2.7  0.0  6.44
514 2 4   aug sun 81.6  56.7 665.6  1.9 21.9 71  5.8  0.0 54.29
515 7 4   aug sun 81.6  56.7 665.6  1.9 21.2 70  6.7  0.0 11.16
516 1 4   aug sat 94.4 146.0 614.7 11.3 25.6 42  4.0  0.0  0.00
517 6 3   nov tue 79.5   3.0 106.7  1.1 11.8 31  4.5  0.0  0.00

1 Ответ

1 голос
/ 10 июля 2019

Проблема легко решается, если вместо создания матрицы для хранения коэффициентов они сохраняются в list.Таким образом, не будет никаких предметов для замены, обо всем позаботятся позже.

В следующем коде я использую встроенный набор данных iris, меняя имя ответа на area.

wdbc <- iris
names(wdbc)[1] <- "area"

fitted_value <- rep(0, nrow(wdbc))
estcoef <- vector("list", length = nrow(wdbc))

# LOOCV split leave one out cross validation 
for(i in 1:nrow(wdbc)){
  validation <- wdbc[i,]
  training <- wdbc[-i, ]
  model1 <- lm(area ~ ., data = training)
  fitted_value[i] <- predict(model1, newdata = validation) 
  estcoef[[i]] <- coef(model1) 
}

estcoef <- do.call(rbind, estcoef)
meancoef <- colMeans(estcoef) # coefficent means

Edit.

Оператор жалуется на ошибку:

Ошибка в model.frame.default (Условия, новые данные, na.action = na.action, xlev = object $ xlevels):
фактор месяц имеет новый уровень nov

Это связано с тем, что в наборе данных имеется только одна строка с month == "nov", поэтому при подборе модели с этой одной опущенной строкой набор данных validation имеетзначение в столбце month, которого нет в наборе данных training и predict не знает, что с ним делать.

Решение состоит в том, чтобы использовать tryCatch, чтобы перехватить ошибку и позволить коду продолжить работу.Функция ниже - это повторение кода выше с вызовом tryCatch.Возвращает средние коэффициенты и подогнанные значения.Когда predict выдает ошибку, возвращается значение NaN.Измените это по желанию.

fitModelLOOCV <- function(DF){

  fitted_value <- rep(0, nrow(DF))
  estcoef <- vector("list", length = nrow(DF))

  # LOOCV split leave one out cross validation 
  for(i in 1:nrow(DF)){
    validation <- DF[i,]
    training <- DF[-i, ]
    model1 <- lm(area ~ ., data = training)
    fitted_value[i] <- tryCatch(predict(model1, newdata = validation),
                                error = function(e) {print(e); NaN})
    estcoef[[i]] <- coef(model1) 
  }

  estcoef <- do.call(rbind, estcoef)
  meancoef <- colMeans(estcoef) # coefficent means
  list(meancoef = meancoef, fitted = fitted_value)
}

fitModelLOOCV(wdbc)

Альтернативой является удаление значения проблемы перед запуском функции.(Может быть, только одна точка данных не так важна.)

wdbc2 <- wdbc[-which(wdbc$month == "nov"), ]
fitModelLOOCV(wdbc2)
...