วิธีการกำหนดขอบเขตการตัดสินใจของลักษณนามเพื่อนบ้านใกล้เคียง k- ที่ใกล้ที่สุดจากองค์ประกอบของการเรียนรู้ทางสถิติ


31

ฉันต้องการสร้างพล็อตที่อธิบายไว้ในหนังสือ ElemStatLearn "องค์ประกอบของการเรียนรู้ทางสถิติ: การทำเหมืองข้อมูลการอนุมานและการทำนายรุ่นที่สอง" โดย Trevor Hastie & Robert Tibshirani & Jerome Friedman เนื้อเรื่องคือ:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันสงสัยว่าฉันสามารถสร้างกราฟที่แน่นอนนี้ได้Rอย่างไรโดยเฉพาะบันทึกกราฟกริดและการคำนวณเพื่อแสดงขอบเขต


3
มันคืออันนี้หรือเปล่า: www-stat.stanford.edu/~tibs/ElemStatLearn/datasets/… ?
StasK

1
@ ขั้นตอน: ใช่มันเป็น จะสร้างพล็อตได้อย่างไร? คุณช่วยได้ไหม ขอบคุณมาก!
littleEinstein

คำตอบ:


35

ในการทำซ้ำภาพนี้คุณจะต้องมีแพ็คเกจElemStatLearnติดตั้งอยู่ในระบบของคุณ ชุดข้อมูลเทียมถูกสร้างขึ้นพร้อมกับmixture.example()ชี้ตาม @StasK

library(ElemStatLearn)
require(class)
x <- mixture.example$x
g <- mixture.example$y
xnew <- mixture.example$xnew
mod15 <- knn(x, xnew, g, k=15, prob=TRUE)
prob <- attr(mod15, "prob")
prob <- ifelse(mod15=="1", prob, 1-prob)
px1 <- mixture.example$px1
px2 <- mixture.example$px2
prob15 <- matrix(prob, length(px1), length(px2))
par(mar=rep(2,4))
contour(px1, px2, prob15, levels=0.5, labels="", xlab="", ylab="", main=
        "15-nearest neighbour", axes=FALSE)
points(x, col=ifelse(g==1, "coral", "cornflowerblue"))
gd <- expand.grid(x=px1, y=px2)
points(gd, pch=".", cex=1.2, col=ifelse(prob15>0.5, "coral", "cornflowerblue"))
box()

mixture.exampleแต่ทุกคำสั่งสามที่ผ่านมาจากความช่วยเหลือออนไลน์สำหรับ โปรดทราบว่าเราใช้ความจริงที่expand.gridจะจัดเรียงผลลัพธ์ด้วยการเปลี่ยนแปลงxก่อนซึ่งจะช่วยให้สามารถทำดัชนี (ตามคอลัมน์) สีในprob15เมทริกซ์ (ขนาด 69x99) ซึ่งมีสัดส่วนคะแนนโหวตสำหรับคลาสที่ชนะสำหรับแต่ละพิกัดตาข่าย ( px1, px2)

ป้อนคำอธิบายรูปภาพที่นี่


+1 ขอบคุณ! ฉันยังสงสัยว่าจะสร้างข้อมูลตามที่อธิบายไว้ในข้อความ "เปิดเผย oracle" ได้อย่างไร คุณสามารถเพิ่มสิ่งนั้นแทนการใช้ข้อมูลจากเว็บไซต์ได้หรือไม่
littleEinstein

@littleEinstein คุณหมายถึงสิ่งที่ได้รับจากความช่วยเหลือออนไลน์mixture.exampleใช่หรือไม่ ดูการตั้งค่าการจำลองด้านล่างบรรทัดที่เริ่มต้นด้วย# Reproducing figure 2.4, page 17 of the book:ในส่วนตัวอย่าง
chl

คุณช่วยบอกให้ฉันรู้ลิงค์ได้ไหม? ฉันหามันไม่เจอ.
littleEinstein

ขออภัย @littleEinstein แต่มีบางสิ่งที่ฉันอาจหายไป มันเป็นเพียงเรื่องของการพิมพ์help(mixture.example)หรือexample(mixture.example)ที่พรอมต์ R (หลังจากที่คุณโหลดแพคเกจที่จำเป็นด้วยlibrary(ElemStatLearn)) รหัสที่จะสร้างชุดข้อมูลเทียม (ที่จะไม่สร้างรูปที่ 2.4) จะถูกเขียนเป็น R ธรรมดาในส่วนตัวอย่าง
chl

1
BTW ฉันเพิ่งเจอบล็อกของ @ Shane ซึ่งเขาใช้ggplotเพื่อจุดประสงค์เดียวกัน ตรวจสอบนี้: ESL 2.1: การถดถอยเชิงเส้นกับ KNN
chl

7

ฉันเรียน ESL ด้วยตนเองและพยายามทำงานผ่านตัวอย่างทั้งหมดที่มีให้ในหนังสือ ฉันเพิ่งทำสิ่งนี้และคุณสามารถตรวจสอบรหัส R ด้านล่าง:

library(MASS)
# set the seed to reproduce data generation in the future
seed <- 123456
set.seed(seed)

# generate two classes means
Sigma <- matrix(c(1,0,0,1),nrow = 2, ncol = 2)
means_1 <- mvrnorm(n = 10, mu = c(1,0), Sigma)
means_2 <- mvrnorm(n = 10, mu = c(0,1), Sigma)

# pick an m_k at random with probability 1/10
# function to generate observations
genObs <- function(classMean, classSigma, size, ...)
{
  # check input
  if(!is.matrix(classMean)) stop("classMean should be a matrix")
  nc <- ncol(classMean)
  nr <- nrow(classMean)
  if(nc != 2) stop("classMean should be a matrix with 2 columns")
  if(ncol(classSigma) != 2) stop("the dimension of classSigma is wrong")

  # mean for each obs
    # pick an m_k at random
  meanObs <- classMean[sample(1:nr, size = size, replace = TRUE),]
  obs <- t(apply(meanObs, 1, function(x) mvrnorm(n = 1, mu = x, Sigma = classSigma )) )
  colnames(obs) <- c('x1','x2')
  return(obs)
}


obs100_1 <- genObs(classMean = means_1, classSigma = Sigma/5, size = 100)
obs100_2 <- genObs(classMean = means_2, classSigma = Sigma/5, size = 100)

# generate label
y <- rep(c(0,1), each = 100)

# training data matrix
trainMat <- as.data.frame(cbind(y, rbind(obs100_1, obs100_2)))

# plot them
library(lattice)
with(trainMat, xyplot(x2 ~ x1,groups = y, col=c('blue', 'orange')))

# now fit two models

# model 1: linear regression
lmfits <- lm(y ~ x1 + x2 , data = trainMat)

# get the slope and intercept for the decision boundary
intercept <- -(lmfits$coef[1] - 0.5) / lmfits$coef[3]
slope <- - lmfits$coef[2] / lmfits$coef[3]

# Figure 2.1
xyplot(x2 ~ x1, groups = y, col = c('blue', 'orange'), data = trainMat,
       panel = function(...)
       {
        panel.xyplot(...)
        panel.abline(intercept, slope)
        },
       main = 'Linear Regression of 0/1 Response')    

# model2: k nearest-neighbor methods
library(class)
# get the range of x1 and x2
rx1 <- range(trainMat$x1)
rx2 <- range(trainMat$x2)
# get lattice points in predictor space
px1 <- seq(from = rx1[1], to = rx1[2], by = 0.1 )
px2 <- seq(from = rx2[1], to = rx2[2], by = 0.1 )
xnew <- expand.grid(x1 = px1, x2 = px2)

# get the contour map
knn15 <- knn(train = trainMat[,2:3], test = xnew, cl = trainMat[,1], k = 15, prob = TRUE)
prob <- attr(knn15, "prob")
prob <- ifelse(knn15=="1", prob, 1-prob)
prob15 <- matrix(prob, nrow = length(px1), ncol = length(px2))

# Figure 2.2
par(mar = rep(2,4))
contour(px1, px2, prob15, levels=0.5, labels="", xlab="", ylab="", main=
    "15-nearest neighbour", axes=FALSE)
points(trainMat[,2:3], col=ifelse(trainMat[,1]==1, "coral", "cornflowerblue"))
points(xnew, pch=".", cex=1.2, col=ifelse(prob15>0.5, "coral", "cornflowerblue"))
box()

1
ในการป้อนรหัสที่นี่โดยไม่ทำเช่นนั้นคุณสามารถเน้นข้อความที่เป็นรหัสแล้วคลิกที่ปุ่ม "รหัส" ใกล้ด้านบนของหน้า มันอยู่ในแถวไอคอน / ปุ่ม รหัสหนึ่งดูเหมือนว่าเครื่องหมายวงเล็บ
Peter Flom - Reinstate Monica

เรื่อง: "วิธีการวางบล็อกของรหัส R" คุณสามารถเข้าถึงแถบเมนูขนาดเล็กเมื่อแก้ไขโพสต์ของคุณ
chl

นอกจากนี้หากคุณไม่ได้ใช้โปรแกรมแก้ไขที่สามารถเยื้องบล็อกของรหัสได้อย่างง่ายดายฉันคิดว่าคุณยินดีที่จะเปลี่ยนเป็นหนึ่ง เช่นใน Rstudio เลือกรหัสและกดเยื้องแท็บมันในเป็นกลุ่มที่คุณสามารถ5>>ฯลฯ
มาร์ค
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.