Làm thế nào để vẽ ranh giới quyết định của phân loại hàng xóm gần nhất k từ Các yếu tố của học thống kê?


31

Tôi muốn tạo ra cốt truyện được mô tả trong cuốn sách ElemStatLearn "Các yếu tố của học thống kê: Khai thác dữ liệu, suy luận và dự đoán. Ấn bản thứ hai" của Trevor Hastie & Robert Tibshirani & Jerome Friedman. Cốt truyện là:

nhập mô tả hình ảnh ở đây

Tôi tự hỏi làm thế nào tôi có thể tạo ra biểu đồ chính xác này R, đặc biệt lưu ý đồ họa và tính toán lưới để hiển thị đường biên.


3
Đây có phải là cái này không: www-stat.stanford.edu/~tibs/ElemStatLearn/datasets/ Kẻ ?
StasK

1
@StasK: đúng vậy Làm thế nào để tạo ra cốt truyện? Bạn vui lòng giúp đỡ? Cảm ơn nhiều!
littleEinstein

Câu trả lời:


35

Để tái tạo hình này, bạn cần cài đặt gói ElemStatLearn trên hệ thống của bạn. Bộ dữ liệu nhân tạo được tạo ra mixture.example()như được chỉ ra bởi @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()

Tất cả trừ ba lệnh cuối cùng đến từ trợ giúp trực tuyến mixture.example. Lưu ý rằng chúng tôi đã sử dụng thực tế là expand.gridsẽ sắp xếp đầu ra của nó bằng cách thay đổi xtrước, điều này cho phép tiếp tục lập chỉ mục màu (theo cột) trong prob15ma trận (kích thước 69x99), giữ tỷ lệ phiếu bầu cho lớp chiến thắng cho mỗi tọa độ mạng ( px1, px2)

nhập mô tả hình ảnh ở đây


+1. cảm ơn! Tôi cũng đang tự hỏi làm thế nào để tạo ra dữ liệu như được mô tả trong văn bản "phơi bày lời sấm". Bạn cũng có thể vui lòng thêm điều đó, thay vì sử dụng dữ liệu từ trang web?
littleEinstein

@littleEinstein Ý bạn là những gì được đưa ra trong trợ giúp trực tuyến để làm mixture.examplegì? Nhìn vào thiết lập mô phỏng bên dưới dòng bắt đầu với # Reproducing figure 2.4, page 17 of the book:trong phần ví dụ.
chl

bạn có thể vui lòng cho tôi biết liên kết? Tôi không thể tìm thấy nó.
littleEinstein

Xin lỗi @littleEinstein, nhưng có một cái gì đó tôi có thể thiếu. Đây chỉ là vấn đề gõ help(mixture.example)hoặc example(mixture.example)tại dấu nhắc R (sau khi bạn tải gói yêu cầu với library(ElemStatLearn)). Mã để tạo tập dữ liệu nhân tạo (không tạo Hình 2.4) được viết bằng chữ R trong phần Ví dụ.
chl

1
BTW, tôi vừa xem qua weblog của @ Shane, nơi anh ta sử dụng ggplotcho mục đích tương tự. Hãy xem điều này: ESL 2.1: Hồi quy tuyến tính so với KNN .
chl

7

Tôi đang tự học tiếng Anh và cố gắng làm việc thông qua tất cả các ví dụ được cung cấp trong cuốn sách. Tôi vừa làm điều này và bạn có thể kiểm tra mã R bên dưới:

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
Để nhập mã ở đây mà không làm điều đó, bạn có thể đánh dấu văn bản là mã và sau đó nhấp vào nút "mã" gần đầu trang. Đó là trong một hàng các biểu tượng / nút. Mã một trông giống như niềng răng.
Peter Flom - Tái lập Monica

Re: "cách dán một khối mã R". Bạn có quyền truy cập vào một thanh menu nhỏ khi chỉnh sửa bài viết của mình.
chl

Ngoài ra, nếu bạn không sử dụng trình soạn thảo có thể dễ dàng thụt các khối mã, tôi nghĩ bạn sẽ vui lòng chuyển sang một trình soạn thảo. Ví dụ: trong Rstudio chọn mã và nhấn tab thụt lề, trong vim bạn có thể 5>>, v.v.
Đánh dấu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.