R 为什么MASS::lda的行为是非确定性的?
我最近做了一些工作,详细研究了lda的行为,发现对于接近决策边界的观测,predict.lda返回非确定性类。起初我认为这可能是一个数字精度问题,但从决策边界来看,预测数据似乎在1e-6的数量级上,远远高于双精度。。。。我编写了一个最小(ish)示例,请参见以下内容:R 为什么MASS::lda的行为是非确定性的?,r,R,我最近做了一些工作,详细研究了lda的行为,发现对于接近决策边界的观测,predict.lda返回非确定性类。起初我认为这可能是一个数字精度问题,但从决策边界来看,预测数据似乎在1e-6的数量级上,远远高于双精度。。。。我编写了一个最小(ish)示例,请参见以下内容: # Fit an LDA model to a subset of Fisher's Iris data x = as.matrix(iris[iris$Species != 'setosa', 1:4]) y = as.fact
# Fit an LDA model to a subset of Fisher's Iris data
x = as.matrix(iris[iris$Species != 'setosa', 1:4])
y = as.factor(as.character(iris[iris$Species != 'setosa', 'Species']))
m = MASS::lda(x, y)
# Generate data near the decision boundary
d = m$scaling
ord = order(x %*% d)
y.pred = MASS:::predict.lda(m, newdata = x)$class
ind = min(which(y.pred[ord] == 'virginica'))
# Interpolate between the two data points on either side of the decision boundary
s = seq(0, 1, length.out = 100001)
s = s[47479:47484] # Zoom on the decision boundary
x.test = (as.matrix(s) %*% t(x[ord[ind - 1], ])) + (as.matrix(1 - s) %*% t(x[ord[ind], ]))
# running predict.lda() on x.test seems to generate non-deterministic results.
# set.seed(123) # set.seed here seems to remove the non-determinism.
for (i in 1:10) {
y.pred = MASS:::predict.lda(m, newdata = x.test)$class
print(as.character(y.pred))
}
如果有什么不同,下面是sessionInfo输出:
> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.3 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1
locale:
[1] LC_CTYPE=en_AU.UTF-8 LC_NUMERIC=C LC_TIME=en_AU.UTF-8 LC_COLLATE=en_AU.UTF-8 LC_MONETARY=en_AU.UTF-8
[6] LC_MESSAGES=en_AU.UTF-8 LC_PAPER=en_AU.UTF-8 LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_AU.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] MASS_7.3-51.4 compiler_3.6.1 tools_3.6.1
predict
方法是寻找联系,并使用随机选择来打破联系。这就是为什么设置随机种子使其具有确定性
为了找到随机性的来源,我编辑了一份MASS:::predict.lda
的副本以添加如下行:
cat("after cl:"); print(rnorm(1)); set.seed(123); print(rnorm(1)); set.seed(123)
如果在此之后使用随机数生成器,则rnorm(1)
的下一个值将不同于直接在set.seed(123)
调用之后的值
下面是编辑后的predict.lda
源代码的一部分,说明了这个问题:
posterior <- dist/drop(dist %*% rep(1, ng))
cat("after posterior:"); print(rnorm(1)); set.seed(123); print(rnorm(1)); set.seed(123)
nm <- names(object$prior)
cl <- factor(nm[max.col(posterior)], levels = object$lev)
cat("after cl:"); print(rnorm(1)); set.seed(123); print(rnorm(1)); set.seed(123)
然后,如果查看cl
计算中使用的max.col
帮助,您可以看到
当ties.method=“random”时,默认情况下,在
随机的在这种情况下,平局的确定假设
条目为概率:存在1e-5的相对公差,
相对于数据中的最大(数量级,省略无穷大)条目
划船
回答得好!非常感谢。
after posterior:[1] -0.5604756
[1] -0.5604756
after cl:[1] 1.558708
[1] -0.5604756
[1] "virginica" "virginica" "versicolor" "virginica"
[5] "versicolor" "versicolor"