在我的几个分析中,我一直在使用mahal分类器功能(r中的Dismo包),最近我发现它似乎给出了与分类器训练中使用的点相同的点的明显错误的距离结果。对于背景,根据我对基于马哈拉诺比斯的分类器的理解,他们使用马哈拉诺比斯距离来描述非分类点的相似性,通过测量点与训练集质量中心的距离(同时考虑尺度和协方差的差异)等)。马哈拉诺比斯距离得分从-inf变为1,其中一个表示未分类点与训练集定义的质心之间没有距离。然而,我发现,对于具有与训练点相同的预测值的所有点,我仍然得到1的分数,就好像该例程作为最近邻分类器一样工作。这是一个非常令人不安的行为,因为它有可能人为地增加我整体分类的信心。
有没有人遇到过这种行为?有关如何修复/避免此行为的任何想法?
我在下面写了一个小脚本,清楚地展示了奇怪的行为:
rm(list = ls()) #remove all past worksheet variables
library(dismo)
logo <- stack(system.file("external/rlogo.grd", package="raster"))
#presence data (points that fall within the 'r' in the R logo)
pts <- matrix(c(48.243420, 48.243420, 47.985820, 52.880230, 49.531423, 46.182616,
54.168232, 69.624263, 83.792291, 85.337894, 74.261072, 83.792291, 95.126713,
84.565092, 66.275456, 41.803408, 25.832176, 3.936132, 18.876962, 17.331359,
7.048974, 13.648543, 26.093446, 28.544714, 39.104026, 44.572240, 51.171810,
56.262906, 46.269272, 38.161230, 30.618865, 21.945145, 34.390047, 59.656971,
69.839163, 73.233228, 63.239594, 45.892154, 43.252326, 28.356155), ncol=2)
# fit model
m <- mahal(logo, pts)
#using model, predict train data
training_vals=extract(logo, pts)
x <- predict(m, training_vals)
x #results show a perfect 1 prediction, which is highly unlikely
现在,我尝试对直接相邻点对的平均值进行预测 我这样做是因为: (1)用于训练模型的每一对的每个点都具有完美的适用性和 (2)这些平均点中的至少一些可能与原始对中的马哈拉诺比斯中心的中心接近 (3)我预计至少有一些平均点也具有完美的适用性。
#pick two adjacent points and fit model
adjacent_pts=pts
adjacent_pts[,2]=adjacent_pts[,2]+1
adjacent_training_vals=extract(logo, adjacent_pts)
new_pts=rbind(pts, adjacent_pts)
plot(logo[[1]]) #plot predictor raster and response point pairs
points(new_pts[,1],new_pts[,2])
#use model to predict mahalanobis score for new training data (point pairs)
m <- mahal(logo, new_pts)
new_training_vals=extract(logo, new_pts)
x <- predict(m, new_training_vals)
x
正如所描述的奇怪行为所预期的那样,所有训练点的距离得分均为1.但是,让我们尝试预测每对的平均值:
mid_vals=(adjacent_training_vals+training_vals)/2
x <- predict(m, mid_vals)
x #NONE DO!
这对我来说进一步表明,Mahal例程将为任何与用于训练模型的任何点具有相同值的数据点提供完美分数
以下是不合适的,但只是证明这一点的另一种方式: 在这里,我预测相同的原始列车数据,其中只有一个预测变量的值几乎没有显着的“预算”值,并且表明得到的分数变化非常大。
mod_training_vals=training_vals
mod_training_vals[,1]=mod_training_vals[,1]*1.01
x <- predict(m, mod_training_vals)
x #predictions suddenly are far from perfect predictions