LDA分类:测试数据集中的零预测能力是真实的,还是误差的假象

时间:2017-08-03 16:54:36

标签: r classification lda

我有一个制表符分隔文件,包含70行数据和34列特征,其中前60行如下所示:

groups x1    x2     x3    x4   x5 (etc, up to x34)
0    0.1    0.5    0.5   0.4  0.2
1    0.2    0.3    0.8   0.4  0.1
0    0.4    0.7    0.6   0.2  0.1
1    0.4    0.4    0.7   0.1  0.4

最后10行看起来像这样:

groups x1    x2     x3    x4   x5
?    0.2    0.1    0.5   0.4  0.2
?    0.2    0.1    0.8   0.4  0.1
?    0.2    0.2    0.6   0.2  0.1
?    0.2    0.3    0.7   0.1  0.4

组是二进制的(即每行属于组0或组1)。目的是使用前60行作为我的训练数据集,最后10行作为我的测试数据集;将最后10行分类为0或1组。

我按照here描述的方法写了这个:

data <-read.table("data_challenge_test.tab",header=TRUE)
train <-sample(1:60)
data.train <-data[train,]
data.test <-data[-train,]
odd.lda <-lda(groups ~ x1+x2+x3+x4+x5, data.train)
pred.train <- predict(odd.lda,data.train)$class
pred.test <- predict(odd.lda,data.test)$class

training_prediction = mean(pred.train == data.train$groups)
testing_prediction = mean(pred.test == data.test$groups)

在“odd.lda”行之后,我收到警告:

Warning message:
In lda.default(x, grouping, ...) : group ? is empty

问题是我的测试训练数据集不应该有“?”组在它中(因为我的训练数据集是前60行,所有这些行都被分组为0或1)。

然后,我的training_prediction值为0.9,但我的test_prediction值为0.

我明白我也可以考虑其他分类方法(我也在研究glm),但我想确保从test_prediction数据集中获得的0预测能力是真实的,而不是错误的假象(即我上面提到的群组编号的问题)。

我是否已正确完成此分析,或上述代码中是否存在导致上述警告的错误,以及测试数据集的0预测能力。

编辑1: 由于评论中的讨论,为了计算模型的预测能力,我复制了here描述的方法,随机选择60行中的50行,估计训练参数,然后对剩余的10个样本进行分类。这重复了100次。

n = 60
nt = 50
neval = n-nt
rep=100
errlin = dim(rep)

set.seed(123456789)
data <-read.table("data_challenge_test.tab",header=TRUE)
data <-data[1:60,]
for (k in 1:rep) {
train = sample(1:n,nt)
data.train <-data[train,]
data.test <-data[-train,]
m1 = lda(groups ~ x1+x2+x3+x4+x5,data.train)
tablin = table(data$groups[-train],predict(m1,data.test)$class)
errlin[k] = (neval-sum(diag(tablin)))/neval
}
merrlin=mean(errlin)
merrlin

就我而言,merrlin是0.454;这意味着有45%的错误分类。

Iris数据集上使用的确切代码(请参阅下面的评论):

n = 120
nt = 90
neval = n-nt
rep=100
errlin = dim(rep)
set.seed(123456789)
data <-iris
for (k in 1:rep) {
  train = sample(1:n,nt)
  data.train <-data[train,]
  data.test <-data[-train,]
  m1 = lda(Species ~ .,data.train)
  tablin = table(data$Species[-train],predict(m1,data.test)$class)
  errlin[k] = (neval-sum(diag(tablin)))/neval
}

merrlin=mean(errlin)
merrlin

1 个答案:

答案 0 :(得分:0)

跟进上述评论的回答......

在使用iris的示例中,如果将n设置为120,则必须将数据限制为第一行n,否则data[-train,]将包含行121:150以及您期待的那些。

我在下面做了一些小改动......

library(MASS)
n = 120
nt = 90
neval = n-nt
rep=100
errlin = dim(rep)
set.seed(123456789)
data <-iris[1:n,] # here is where you need to keep your data to n rows
for (k in 1:rep) {
  train = sample(1:n,nt)
  data.train <-data[train,]
  data.test <-data[-train,] #now excludes iris[(n+1):150,]
  m1 = lda(Species ~ .,data.train)
  tablin = table(data.test$Species,predict(m1,data.test)$class) #edited first term
  errlin[k] = (neval-sum(diag(tablin)))/neval
}

merrlin=mean(errlin)
merrlin

[1] 0.019

这是一个更好的错误率!