2015-09-08 13 views
5

私は、Caretパッケージによって作成されたモデルの決定境界をプロットしたいと思います。理想的には、私は、Caretの任意のクラシファイアモデルの一般的なケースメソッドを希望します。しかし、私は現在kNNメソッドを使って作業しています。私はUCIのワイン品質データセットを使用していますが、これは私が今作業しているコードです。CaretパッケージのkNNモデルの決定境界グラフを作成する方法は?

私はRで一般的なk最近傍の方法で動作するこの方法を見つけましたが、キャレットにマッピングする方法を見つけ出すことはできません - >https://stats.stackexchange.com/questions/21572/how-to-plot-decision-boundary-of-a-k-nearest-neighbor-classifier-from-elements-o/21602#21602

library(caret) 

    set.seed(300) 

    wine.r <- read.csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv', sep=';') 
    wine.w <- read.csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv', sep=';') 

    wine.r$style <- "red" 
    wine.w$style <- "white" 

    wine <- rbind(wine.r, wine.w) 

    wine$style <- as.factor(wine$style) 

    formula <- as.formula(quality ~ .) 

    dummies <- dummyVars(formula, data = wine) 
    dummied <- data.frame(predict(dummies, newdata = wine)) 
    dummied$quality <- wine$quality 

    wine <- dummied 

    numCols <- !colnames(wine) %in% c('quality', 'style.red', 'style.white') 

    low <- wine$quality <= 6 
    high <- wine$quality > 6 
    wine$quality[low] = "low" 
    wine$quality[high] = "high" 
    wine$quality <- as.factor(wine$quality) 

    indxTrain <- createDataPartition(y = wine[, names(wine) == "quality"], p = 0.7, list = F) 

    train <- wine[indxTrain,] 
    test <- wine[-indxTrain,] 

    corrMat <- cor(train[, numCols]) 
    correlated <- findCorrelation(corrMat, cutoff = 0.6) 

    ctrl <- trainControl(
         method="repeatedcv", 
         repeats=5, 
         number=10, 
         classProbs = T 
         ) 

    t1 <- train[, -correlated] 
    grid <- expand.grid(.k = c(1:20)) 

    knnModel <- train(formula, 
         data = t1, 
         method = 'knn', 
         trControl = ctrl, 
         tuneGrid = grid, 
         preProcess = 'range' 
        ) 

    t2 <- test[, -correlated] 
    knnPred <- predict(knnModel, newdata = t2) 

    # How do I render the decision boundary? 

答えて

5

最初のステップは、実際にどのようなコードを理解することですリンクしています!実際には、KNNと関係のないこのようなグラフを生成することができます。

たとえば、データの下位象限を「色付け」するだけのサンプルデータがあります。

ステップ1

グリッドを生成します。基本的にグラフの仕組みは、各座標にポイントを作成し、どのグループに属しているかを知ることです。 Rでは、可能な限りすべての点を調べるためにexpand.gridを使用します。これがKNNた場合

x1 <- 1:200 
x2 <- 50:250 

cgrid <- expand.grid(x1=x1, x2=x2) 
# our "prediction" colours the bottom left quadrant 
cgrid$prob <- 1 
cgrid[cgrid$x1 < 100 & cgrid$x2 < 170, c("prob")] <- 0 

、それはprobは、その特定の時点の予測になるだろう。今では比較的簡単であるプロット

ステップ2

contour関数に準拠する必要があるため、最初に確率で行列を作成します。

matrix_val <- matrix(cgrid$prob, 
        length(x1), 
        length(x2)) 

ステップ3

次に、あなたのリンクが何をしたかのように進行することができます

contour(x1, x2, matrix_val, levels=0.5, labels="", xlab="", ylab="", main= 
      "Some Picture", lwd=2, axes=FALSE) 
gd <- expand.grid(x=x1, y=x2) 
points(gd, pch=".", cex=1.2, col=ifelse(prob==1, "coral", "cornflowerblue")) 
box() 

出力:

somepic


その後、特定の例に戻ります。私は虹彩を使うつもりです。なぜなら、あなたのデータは見るのが面白くないからです。同じ原理が適用されます。グリッドを作成するには、x-y軸を選択し、それ以外はすべて固定しておく必要があります。

knnModel <- train(Species ~., 
        data = iris, 
        method = 'knn') 

lgrid <- expand.grid(Petal.Length=seq(1, 5, by=0.1), 
        Petal.Width=seq(0.1, 1.8, by=0.1), 
        Sepal.Length = 5.4, 
        Sepal.Width=3.1) 

次に、上記のように、予測機能を使用します。

knnPredGrid <- predict(knnModel, newdata=lgrid) 
knnPredGrid = as.numeric(knnPredGrid) # 1 2 3 

そしてグラフを構築する:あなたのモデルからテスト/電車の結果を追加するには

iris


、:

pl = seq(1, 5, by=0.1) 
pw = seq(0.1, 1.8, by=0.1) 

probs <- matrix(knnPredGrid, length(pl), 
       length(pw)) 

contour(pl, pw, probs, labels="", xlab="", ylab="", main= 
      "X-nearest neighbour", axes=FALSE) 

gd <- expand.grid(x=pl, y=pw) 

points(gd, pch=".", cex=5, col=probs) 
box() 

これは、このような出力が得られるはずあなたは私がやったことに従うことができます。 。

enter image description here

代わりに使用することができます唯一の違いは、あなたがこの境界を生成するために使用されたグリッドと同じではありません(予測ポイントを追加する必要があります

library(caret) 
data(iris) 

indxTrain <- createDataPartition(y = iris[, names(iris) == "Species"], p = 0.7, list = F) 

train <- iris[indxTrain,] 
test <- iris[-indxTrain,] 

knnModel <- train(Species ~., 
        data = train, 
        method = 'knn') 

pl = seq(min(test$Petal.Length), max(test$Petal.Length), by=0.1) 
pw = seq(min(test$Petal.Width), max(test$Petal.Width), by=0.1) 

# generates the boundaries for your graph 
lgrid <- expand.grid(Petal.Length=pl, 
        Petal.Width=pw, 
        Sepal.Length = 5.4, 
        Sepal.Width=3.1) 

knnPredGrid <- predict(knnModel, newdata=lgrid) 
knnPredGrid = as.numeric(knnPredGrid) 

# get the points from the test data... 
testPred <- predict(knnModel, newdata=test) 
testPred <- as.numeric(testPred) 
# this gets the points for the testPred... 
test$Pred <- testPred 

probs <- matrix(knnPredGrid, length(pl), length(pw)) 

contour(pl, pw, probs, labels="", xlab="", ylab="", main="X-Nearest Neighbor", axes=F) 
gd <- expand.grid(x=pl, y=pw) 

points(gd, pch=".", cex=5, col=probs) 

# add the test points to the graph 
points(test$Petal.Length, test$Petal.Width, col=test$Pred, cex=2) 
box() 

出力であります

ggplot(data=lgrid) + stat_contour(aes(x=Petal.Length, y=Petal.Width, z=knnPredGrid), 
          bins=2) + 
    geom_point(aes(x=Petal.Length, y=Petal.Width, colour=as.factor(knnPredGrid))) + 
    geom_point(data=test, aes(x=test$Petal.Length, y=test$Petal.Width, colour=as.factor(test$Pred)), 
      size=5, alpha=0.5, shape=1)+ 
    theme_bw() 

が出力:

方が簡単な場合がありますグラフを行うには

enter image description here

+0

これは非常に良い応答であり、私ははるかに近いと思います。決定境界をプロットしようとした私のコードの要点を更新しました:https://gist.github.com/jameskyle/729945f6fa38a343b8ab。しかし、私が得るグラフは、怪物のような格子縞の混乱です(http://i.imgur.com/TYCpleT.png)。 これは実装上のエラーによるものですか、それともデータそのものですか?アルコール+塩化物を私のx、yとして選んだのは、それが最も重要な特徴であったからです。 –

+0

私は、テストセットを生成するのではなく、虹彩データを分割するスクリプトを虹彩に基づいて作成しました。私は同様の分数グラフを取得します。意思決定の境界線がどのようにうまくいくのかと思うのですか? スクリプト:https://gist.github.com/jameskyle/ffed976dfef1cbc778d5 グラフ:http://i.imgur.com/UX1xmp9.png –

+0

新しいデータ部分では、データはグリッドのようにする必要があります。私は私の答えを更新します。 – chappers

関連する問題