r - 如何从 R 中的 3D 图中的分类算法绘制分区平面

标签 r classification partition plot3d

我正在尝试根据 R 中 3D 绘图中的分类算法绘制分区边界(使用 plot3D)。如果我们只有两个预测变量,则这是一个相对简单的任务,只需要绘制两个轴(例如使用 partimat 函数)。我还没有找到令人满意的方法来在 3D 空间中绘制基于三个预测变量的分类分区。

为了使问题可视化,让我们首先在 iris 数据集上使用线性判别分析 (LDA) 分类算法为两个轴构建分区:

# Load packages and subset the iris dataset:
library(klaR)

data = droplevels(iris[iris$Species != 'virginica', ])

partimat(Species ~ Sepal.Length + Sepal.Width, data, 
         method = 'lda')

我们得到一个二维图,其中两个物种之间有明确定义的分区:

Linear Discriminant Analysis results on two axes

但是,partimat 一次只能处理两个预测变量(参见 ?partimat)。现在让我们看看 3D 问题:

library(plot3D)
    
# Plot the raw data:
points3D(data$Sepal.Length, data$Sepal.Width, data$Petal.Length,
             colkey = F,
             pch = 16, cex = 2,
             theta = 30, phi = 30, 
             ticktype = 'detailed',
             col = data$Species)

3D plot of iris plant metrics

我想根据像 LDA 这样的分类算法绘制一个平面来分隔两个数据类。从 Roman Luštrik's example 中汲取灵感,这是我定义三个预测变量之间的分区的糟糕尝试。本质上,我已经建立了一个具有三个预测变量的 LDA 模型,然后将物种(setosa 或 versicolor)预测到最大值之间的多个点上。和分钟。所有三个预测变量的值。当绘制在 3D 图上时,这会生成一个点云,以不同的颜色表示根据三个预测变量应出现任何一种鸢尾花的 3D 空间:

# Build a classification model with three predictors:
m = lda(Species ~ Sepal.Length + Sepal.Width + Petal.Length, data)

# Predict 'Species' for the full range of each plant metric: 
np = 50

nx = seq(from = min(data[, 1]), to = max(data[, 1]), length.out = np)
ny = seq(from = min(data[, 2]), to = max(data[, 2]), length.out = np)
nz = seq(from = min(data[, 3]), to = max(data[, 3]), length.out = np)
nd = expand.grid(Sepal.Length = nx, Sepal.Width = ny, Petal.Length = nz)

p    = as.numeric(predict(m, newdata = nd)$class)
part = cbind(nd, Partition = p)

# Plot the partition and add the data points:  
scatter3D(part$Sepal.Length, part$Sepal.Width, part$Petal.Length, 
          colvar = part$Partition, 
          colkey = F,
          alpha = 0.5,
          pch = 16, cex = 0.3, 
          theta = 30, phi = 30, 
          ticktype = 'detailed',
          plot = F)
points3D(data$Sepal.Length, data$Sepal.Width, data$Petal.Length,
         colkey = F,
         pch = 16, cex = 2,
         theta = 30, phi = 30, 
         ticktype = 'detailed',
         col = data$Species,
         add = T)

我还添加了数据点。您可以将分区视为点云中蓝色和红色之间的模糊交集:

Linear Discriminant Analysis on three axes

这不是一个理想的解决方案,因为很难看到隐藏在点云中的数据点。点云也有点让人分心。也许一些具有透明度的点的巧妙绘图会改善事情,但我怀疑更好的解决方案是在物种类之间的交叉点(即蓝点和红点相遇的地方)绘制一个平面(类似于 regression plane ) .请注意,我最终希望使用不同的分类器(例如随机森林),以防万一存在仅限于 LDA 或类似的解决方案。

非常感谢任何解决方案或建议。

最佳答案

您可以使用 lda 模型中的系数来生成分隔判别体积的平面。实际上,平面是 3D 空间中的一组点,其中 (x, y, z) 坐标乘以它们各自的模型系数的总和等于模型的阈值(即模型可以所在的平面) '不要将一个群体与另一个群体区分开来)。

我们可以通过沿 x 轴和 y 轴创建一个 10 x 10 的等间距值网格并计算 z 值来实现这一点,该值为我们提供基于模型的阈值:

threshold <-  sum(coef(m) * data[1, 1:3]) - predict(m)$x[1] 

Sepal_Lengths <- seq(min(data$Sepal.Length), max(data$Sepal.Length), length.out = 10)
Sepal_Widths  <- seq(min(data$Sepal.Width), max(data$Sepal.Width), length.out = 10)
Petal_Lengths <- outer(Sepal_Lengths, Sepal_Widths, function(x, y) {
                  (threshold - x * coef(m)[1] - y * coef(m)[2]) / coef(m)[3]})

所以现在当我们得出我们的观点时:

points3D(data$Sepal.Length, data$Sepal.Width, data$Petal.Length,
         colkey = F,
         pch = 16, cex = 2,
         theta = 30, phi = 30, 
         ticktype = 'detailed',
         col = data$Species)

enter image description here

添加平面非常简单:

persp3D(x = Sepal_Lengths, 
        y = Sepal_Widths, 
        z = Petal_Lengths, 
        col = "gold", add = TRUE, alpha = 0.5)

enter image description here

关于r - 如何从 R 中的 3D 图中的分类算法绘制分区平面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69711554/

相关文章:

在 Azure ML 中但不在 R 本身中接收基于 R 的错误消息

r - "Error in table(pred = prediction, true = W[, 8]) : all arguments must have the same length"

mysql - 如何按列值 "user_id"和 "gps_time"对mysql进行分区?

r - 在 R 中使用 ggplot 时,如何删除绘图区域周围的边距?

java - mailR 连接被 Linux 拒绝,但 Windows 不拒绝

r - 如何使用 ggplot 创建两条线和散点图

python - 为什么 BernoulliNBC 在 iris 数据集上的表现比 GaussianNBC 或 MultinomialNBC 差?

machine-learning - 什么是最大熵?

sql - 如何从oracle服务器的分区表中获取分区列名