2014-06-05 55 views
3

我發現ISLRFigure 2.13)或ESL做得非常好。我無法猜測作者是如何在R中做到這一點的。我知道如何很容易地獲得橙色和藍色的點。主要的困惑是背景點和紫色線。如何用R中的網格繪製非線性決策邊界?

任何想法? Fig 2.13, ISLR

下面是一些示例代碼,用灰色網格獲取黃色和橙色點。如何獲得紫色的任意非線性曲線,然後根據曲線對網格進行着色?

set.seed(pi) 
points = replicate(100, runif(2)) 
pointsColored = ifelse(apply(points, 2, sum) <= 1, "orange", "blue") 
# Confound some 
pointsColored[sample.int(length(pointsColored), 10)] = "orange" 
plot(x=points[1, ], y=points[2, ]) 
grid(nx=100, ny=100) 
# Plot points over the grid. 
points(x=points[1, ], y=points[2, ], col=pointsColored) 
+0

嗯... downvote?因爲我沒有提供我自己的嘗試? – asb

+0

提供您嘗試過的樣品數據... – vrajs5

+0

很難判斷這個圖中發生了什麼,因爲有些點跨越了似乎區分顏色變化的線。示例數據以及迄今爲止嘗試的內容將對您有所幫助。 –

回答

6

正如我在我的評論中指出的,解決方案由@chl here在stats.stackexchange.com上提供。在這裏,它適用於你的數據集。

library(class) 
set.seed(pi) 
X <- t(replicate(1000, runif(2))) 
g <- ifelse(apply(X, 1, sum) <= 1, 0, 1) 
xnew <- cbind(rep(seq(0, 1, length.out=50), 50), 
       rep(seq(0, 1, length.out=50), each=50)) 
m <- knn(X, xnew, g, k=15, prob=TRUE) 
prob <- attr(m, "prob") 
prob <- ifelse(m=="1", prob, 1-prob) 
prob15 <- matrix(prob, 50) 
par(mar=rep(3, 4)) 
contour(unique(xnew[, 1]), unique(xnew[, 2]), prob15, levels=0.5, 
     labels="", xlab='', ylab='', axes=FALSE, lwd=2.5, asp=1) 
title(xlab=expression(italic('X')[1]), ylab=expression(italic('X')[2]), 
     line=1, family='serif', cex.lab=1.5) 
points(X, bg=ifelse(g==1, "#CA002070", "#0571B070"), pch=21) 
gd <- expand.grid(x=unique(xnew[, 1]), y=unique(xnew[, 2])) 
points(gd, pch=20, cex=0.4, col=ifelse(prob15 > 0.5, "#CA0020", "#0571B0")) 
box() 

decision boundary

(更新:我改變了調色板,因爲藍色/黃色/紫色的東西是相當可怕)

+0

感謝您的鏈接到其他答案。 – asb

1

這是我在近似愚蠢的嘗試。顯然,@StephenKolassa提出的問題是有效的,而不是由這種近似處理。

myCurve1 = function (x) 
    abs(x[[1]] * sin(x[[1]]) + x[[2]] * sin(x[[2]])) 
myCurve2 = function (x) 
    abs(x[[1]] * cos(x[[1]]) + x[[2]] * cos(x[[2]])) 
myCurve3 = function (x) 
    abs(x[[1]] * tan(x[[1]]) + x[[2]] * tan(x[[2]])) 

tmp = function (myCurve, seed=99) { 
    set.seed(seed) 
    points = replicate(100, runif(2)) 
    colors = ifelse(apply(points, 2, myCurve) > 0.5, "orange", "blue") 
    # Confound some 
    swapInts = sample.int(length(colors), 6) 
    for (i in swapInts) { 
    if (colors[[i]] == "orange") { 
     colors[[i]] = "blue" 
    } else { 
     colors[[i]] = "orange" 
    } 
    } 
    gridPoints = seq(0, 1, 0.005) 
    gridPoints = as.matrix(expand.grid(gridPoints, gridPoints)) 
    gridColors = vector("character", nrow(gridPoints)) 
    gridPch = vector("character", nrow(gridPoints)) 
    for (i in 1:nrow(gridPoints)) { 
    val = myCurve(gridPoints[i, ]) 
    if (val > 0.505) { 
     gridColors[[i]] = "orange" 
     gridPch[[i]] = "." 
    } else if (val < 0.495) { 
     gridColors[[i]] = "blue" 
     gridPch[[i]] = "." 
    } else { 
     gridColors[[i]] = "purple" 
     gridPch[[i]] = "*" 
    } 
    } 
    plot(x=gridPoints[ , 1], y=gridPoints[ , 2], col=gridColors, pch=gridPch) 
    points(x=points[1, ], y=points[2, ], col=colors, lwd=2) 
} 

par(mfrow=c(1, 3)) 
tmp(myCurve1) 
tmp(myCurve2) 
tmp(myCurve3) 

enter image description here