Получение границы решения для классификатора KNN с использованием R - PullRequest
8 голосов
/ 10 марта 2019

Я пытаюсь подогнать модель KNN и получить границу решения, используя набор данных Auto в пакете ISLR в R.

Здесь мне трудно определить границу решения для задачи 3 класса. Пока это мой код. Я не получаю границы решения.

Я видел где-то еще на этом сайте, ответ на этот вопрос с помощью ggplot. Но я хочу получить ответ классическим способом, используя функцию сюжета.

 library("ISLR")

trainxx=Auto[,c(1,3)]
trainyy=(Auto[,8])

n.grid1 <- 50

x1.grid1 <- seq(f = min(trainxx[, 1]), t = max(trainxx[, 1]), l = n.grid1)
x2.grid1 <- seq(f = min(trainxx[, 2]), t = max(trainxx[, 2]), l = n.grid1)
grid <- expand.grid(x1.grid1, x2.grid1)

library("class")
mod.opt <- knn(trainxx, grid, trainyy, k = 10, prob = T)

prob_knn <- attr(mod.opt, "prob") 

Моя проблема в основном после этого сегмента кода. Я почти уверен, что должен изменить следующий сегмент. Но я не знаю как. Нужно ли использовать «вложенный, если» здесь?

prob_knn <- ifelse(mod.opt == "3", prob_knn, 1 - prob_knn) 



prob_knn <- matrix(prob_knn, n.grid1, n.grid1)


plot(trainxx, col = ifelse(trainyy == "3", "green",ifelse(trainyy=="2", "red","blue")))
title(main = "plot of training data with Desicion boundary K=80")
contour(x1.grid1, x2.grid1, prob_knn, levels = 0.5, labels = "", xlab = "", ylab = "", 
        main = "", add = T , pch=20)

Будет очень полезно, если кто-нибудь может дать предложение по решению этой проблемы.

В основном мне нужно что-то подобное для задачи 3 класса https://stats.stackexchange.com/questions/21572/how-to-plot-decision-boundary-of-a-k-nearest-neighbor-classifier-from-elements-o

Ответы [ 2 ]

3 голосов
/ 19 марта 2019

Вот измененный подход, который рисует границы решения в виде линий.Я думал, что для этого потребуется прогнозируемая вероятность для каждого класса, но после прочтения этого ответа выясняется, что вы можете просто отметить прогнозируемую вероятность для каждого класса как 1, где бы этот класс не был предсказан, и ноль в противном случае.

# Create matrices for each class where p = 1 for any point
#   where that class was predicted, 0 otherwise
n_classes = 3
class_regions = lapply(1:n_classes, function(class_num) {
    indicator = ifelse(mod.opt == class_num, 1, 0)
    mat = matrix(indicator, n.grid1, n.grid1)
})

# Set up colours
class_colors = c("#4E79A7", "#F28E2B", "#E15759")
# Add some transparency to make the fill colours less bright
fill_colors = paste0(class_colors, "60")

# Use image to plot the predicted class at each point
classes = matrix(as.numeric(mod.opt), n.grid1, n.grid1)
image(x1.grid1, x2.grid1, classes, col = fill_colors, 
      main = "plot of training data with decision boundary",
      xlab = colnames(trainxx)[1], ylab = colnames(trainxx)[2])
# Draw contours separately for each class
lapply(1:n_classes, function(class_num) {
    contour(x1.grid1, x2.grid1, class_regions[[class_num]], 
            col = class_colors[class_num],
            nlevels = TRUE, add = TRUE, lwd = 2, drawlabels = FALSE)
})
# Using pch = 21 for bordered points that stand out a bit better
points(trainxx, bg = class_colors[trainyy], 
       col = "black",
       pch = 21)

Полученный участок:

Plot with lines for decision boundaries

0 голосов
/ 14 марта 2019

Я думаю, что вместо того, чтобы пытаться построить границу решения как линию, может быть проще просто использовать прогнозируемый класс в каждой точке сетки и построить его как заполненную область:

# Use the predicted class at each point
classes = matrix(as.numeric(mod.opt), n.grid1, n.grid1)

class_colors = c("#4E79A7", "#F28E2B", "#E15759")
# Add some transparency to make the fill colours less bright
fill_colors = paste0(class_colors, "88")
# Use image to plot the predicted class at each point
image(x1.grid1, x2.grid1, classes, col = fill_colors, 
      main = "plot of training data with decision boundary",
      xlab = colnames(trainxx)[1], ylab = colnames(trainxx)[2])
points(trainxx, col = class_colors[trainyy], pch = 16)

Обратите внимание, что здесь я увеличил n.grid1 в вашем коде до 200, чтобы получить более подробные границы для регионов.

Вывод:

Plot with filled regions

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