Визуализация KNN - Как нарисовать круг вокруг точки данных, соединяющейся с N ближайшими точками, используя R - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть точечная диаграмма, которую я генерирую, используя приведенный ниже код

set.seed(10)
mydata <- data.frame(x1 = rnorm(1000), x2 = rnorm(1000))

ind <- replicate(3, sample(nrow(mydata), 500))
head(ind)

feature1 = mydata[ind[,1], "x1"]
feature2 = mydata[ind[,2], "x2"]

# start with a plot
plot(feature1, feature2, pch=4 , col="black")

enter image description here

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

plot(feature1, feature2, pch=4, col=ifelse((feature1 > 2.6 & feature1 < 2.7 ), "red", "black"))

enter image description here

Теперь я хотел бы нарисовать круг вокруг этой точки (которая отмечена наКРАСНЫЙ) и соедините ближайшие соседние точки N с этой точкой (где N должна быть переменной)

Как я могу сделать это, используя R?

Вот что я намерен получить в своем выводе

enter image description here

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Давайте сначала поместим ваши данные в матрицу p, определим вашу точку интереса p0 и определим количество общих соседей интереса k.

p <- cbind(feature1, feature2)
idx <- p[, 1] > 2.6 & p[, 1] < 2.7
p0 <- p[idx, ]
k <- 10
plot(feature1, feature2, pch = 4, col = ifelse(idx, "red", "black"))

Затем мы найдем теk ближайших соседей и нарисуйте круг (используя circleFun из этот ответ ) и сегменты:

kNN <- p[order(colMeans((t(p) - p0)^2))[1 + 1:k], ]
crc <- circleFun(p0, diameter = 2 * sqrt(sum((kNN[k, ] - p0)^2)))
lines(x = crc$x, y = crc$y, col = 'red', lty = 2)
segments(x0 = p0[1], y0 = p0[2], x1 = kNN[, 1], y1 = kNN[, 2], col = "red")

enter image description here

0 голосов
/ 05 декабря 2018

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

edit : я удалил зависимость от plotrix библиотеки для рисования кругов, которая давала неверный результат.

draw_neighbors <- function(dat, focal_pt_index, n) {
  require(sp)

  # Calculate distances to focal point.
  dists <- spDistsN1(pts = dat, pt = dat[focal_pt_index,])

  # Sort points by distance.
  dat <- cbind(dat, dist = dists)
  dat <- dat[order(dat[,'dist']), ]

  # Plot points
  plot(dat[,1], dat[,2], pch=4 , col=ifelse(dat[,'dist'] == 0, "red", "black"), asp = 1)

  # Draw a line to each neighbor
  neighbors <- dat[2:(n+1), ]
  for (i in 1:nrow(neighbors)) {
    lines(x = c(dat[1,1], neighbors[i,1]), y = c(dat[1,2], neighbors[i,2]), col = 'red')
  }

  # Draw a circle at the radius equal to the largest distance within the n nearest neighbors.
  radius <- dat[n+1, 'dist']
  angles <- seq(0,2*pi,length=1000)
  coords <- cbind(dat[1,1] + sin(angles) * radius, dat[1,2] + cos(angles)* radius)
  points(coords, type = 'l', lty = 2, col = 'red')

}

Вот что вы получаете, используя свои данныедля n = 10.

Звоните:
draw_neighbors(dat = cbind(feature1, feature2), focal_pt_index = which(feature1 > 2.6 & feature1 < 2.7), n = 10)

enter image description here

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