통계 학습의 요소에서 k- 최근 접 이웃 분류기의 결정 경계를 그리는 방법은 무엇입니까?


31

Trevor Hastie & Robert Tibshirani와 Jerome Friedman의 ElemStatLearn 책 "통계학 학습의 요소 : 데이터 마이닝, 추론 및 예측 2 판"에 설명 된 줄거리를 만들고 싶습니다. 줄거리는 다음과 같습니다

여기에 이미지 설명을 입력하십시오

에서 정확한 그래프를 생성하는 방법이 궁금합니다 R. 특히 그리드 그래픽과 계산을 참고하여 경계를 표시하십시오.



1
@StasK : 그렇습니다. 줄거리를 생성하는 방법? 도와 주시겠습니까? 많은 감사합니다!
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-Monica Monica 복원

다시 : "R 코드 블록을 붙여 넣는 방법". 게시물을 편집 할 때 작은 메뉴 표시 줄에 액세스 할 수 있습니다 .
chl

또한 코드 블록을 쉽게 들여 쓸 수있는 편집기를 사용하지 않는 경우 하나를 전환해도 좋을 것 같습니다. 예를 들어 Rstudio에서 코드를 선택하고 탭을 누르면 코드가 들여 쓰기됩니다. vim에서는 다음과 같이 할 수 있습니다 5>>.
Mark
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.