Как я могу использовать алгоритм SOM ​​для предсказания классификации

Я хотел бы узнать, можно ли использовать алгоритм SOM ​​для предсказания классификации. Я использовал код ниже, но вижу, что результаты классификации далеки от правильных. Например, в тестовом наборе данных я получаю гораздо больше, чем просто 3 значения, которые у меня есть в целевой переменной обучения. Как я могу создать модель прогнозирования, которая будет согласована с целевой переменной обучения?

library(kohonen)
    library(HDclassif)
    data(wine)
    set.seed(7)

    training <- sample(nrow(wine), 120)
    Xtraining <- scale(wine[training, ])
    Xtest <- scale(wine[-training, ],
                   center = attr(Xtraining, "scaled:center"),
                   scale = attr(Xtraining, "scaled:scale"))

    som.wine <- som(Xtraining, grid = somgrid(5, 5, "hexagonal"))


som.prediction$pred <- predict(som.wine, newdata = Xtest,
                          trainX = Xtraining,
                          trainY = factor(Xtraining$class))

И результат:

$unit.classif

 [1]  7  7  1  7  1 11  6  2  2  7  7 12 11 11 12  2  7  7  7  1  2  7  2 16 20 24 25 16 13 17 23 22
[33] 24 18  8 22 17 16 22 18 22 22 18 23 22 18 18 13 10 14 15  4  4 14 14 15 15  4

person mql4beginner    schedule 14.07.2017    source источник


Ответы (1)


Это может помочь:

  • SOM - это неконтролируемый алгоритм классификации, поэтому вы не должны ожидать, что он будет обучен на наборе данных, который содержит метку классификатора (если вы это сделаете, ему понадобится эта информация для работы, и она будет бесполезна с наборами данных без меток)
  • Идея состоит в том, что он как бы «преобразует» входной числовой вектор в номер сетевого блока (попробуйте снова запустить свой код с сеткой 1 на 3, и вы получите ожидаемый результат)
  • Затем вам нужно будет преобразовать эти номера сетевых единиц обратно в категории, которые вы ищете (это ключевая часть, отсутствующая в вашем коде).

Воспроизводимый пример ниже выдаст классическую ошибку классификации. Он включает в себя один вариант реализации для части «обратного преобразования», отсутствующей в вашем исходном сообщении.

Хотя для этого конкретного набора данных модель довольно быстро адаптируется: 3 единицы дают наилучшие результаты.

#Set and scale a training set (-1 to drop the classes)
data(wine)
set.seed(7)
training <- sample(nrow(wine), 120)
Xtraining <- scale(wine[training, -1])

#Scale a test set (-1 to drop the classes)
Xtest <- scale(wine[-training, -1],
               center = attr(Xtraining, "scaled:center"),
               scale = attr(Xtraining, "scaled:scale"))

#Set 2D grid resolution
#WARNING: it overfits pretty quickly
#Errors are 36% for 1 unit, 63% for 2, 93% for 3, 89% for 4
som_grid <- somgrid(xdim = 1, ydim=3, topo="hexagonal")

#Create a trained model
som_model <- som(Xtraining, som_grid)

#Make a prediction on test data
som.prediction <- predict(som_model, newdata = Xtest)

#Put together original classes and SOM classifications
error.df <- data.frame(real = wine[-training, 1],
                       predicted = som.prediction$unit.classif)

#Return the category number that has the strongest association with the unit
#number (0 stands for ambiguous)
switch <- sapply(unique(som_model$unit.classif), function(x, df){
  cat <- as.numeric(names(which.max(table(
    error.df[error.df$predicted==x,1]))))
  if(length(cat)<1){
    cat <- 0
  }
  return(c(x, cat))
}, df = data.frame(real = wine[training, 1], predicted = som_model$unit.classif))

#Translate units numbers into classes
error.df$corrected <- apply(error.df, MARGIN = 1, function(x, switch){
  cat <- switch[2, which(switch[1,] == x["predicted"])]
  if(length(cat)<1){
    cat <- 0
  }
  return(cat)
}, switch = switch)

#Compute a classification error
sum(error.df$corrected == error.df$real)/length(error.df$real)
person Community    schedule 22.07.2017
comment
Спасибо @Kevin Dallaporta за пример кода. У меня есть 2 вопроса, сначала я использовал trainY = factor (Xtraining $ class), но я не вижу его в вашей функции прогнозирования. Во-вторых, как я могу прикрепить результаты прогнозирования классов к набору тестовых данных? - person mql4beginner; 22.07.2017
comment
Я рада, что помогло! Кажется, что аргумент trainY = factor существовал в V2.X кохонена и исчез в V3.X. Я не знаю, что он должен был делать, но с возвратом или без, возврат идентичен, и в документации за март 2017 года нет никаких следов. В коде, который я предоставил, результаты прогнозов находятся в error.df$corrected, поэтому вы можете прикрепить его к тесту с помощью: test$predicted <- error.df$corrected - person ; 22.07.2017