1、概述

  • LDA与QDA可以简单理解为有监督的降维,将多个预测变量信息压缩成少数(类别数-1)新的预测变量。

  • 每一个新的预测变量称之为判别函数,由所有原始变量的线性组合。

    所以对类别区分贡献大的变量具有绝对值最大的系数(也称为标准判别函数系数),而包含很少或者不包含类别分离信息的变量的系数约等于0

  • 在分类时,表现最好的是第一个判别函数,其次是第二个…以此类推。

  • LDA(Linear discriminant analysis),为线性判别分析,可以学习不同类别之间的线性的决策边界;

  • QDA(Quadratic discriminant analysis),为二次判别分析,可以学习不同类别之间的曲线的决策边界

  • LDA与QDA均假设所有预测变量呈正态分布;LAD则进一步假设数据集里每一个类别,预测变量之间具有相同的协方差;而QDA没有这一假设。

协方差可以简单理解为变量之间的相关性。

  • 在分类预测时,使用贝叶斯准则预测属于每一种类别的概率,选择概率最大的类别。

image-20220404161906804

2、mlr建模

1
2
library(mlr3verse)
library(tidyverse)

2.1 葡萄酒数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# install.packages("HDclassif")
data(wine, package = "HDclassif")
wineTib = wine

# set meaning colnames
colnames(wineTib) = c("Class", "Alco", "Malic", "Ash", "Alk", "Mag", 
                      "Phe", "Flav", "Non_flav", "Proan", "Col", "Hue", 
                      "OD", "Prol")
# set class column as factor
wineTib$Class <- as.factor(wineTib$Class)
head(wineTib)
#   Class  Alco Malic  Ash  Alk Mag  Phe Flav Non_flav Proan  Col  Hue   OD Prol
# 1     1 14.23  1.71 2.43 15.6 127 2.80 3.06     0.28  2.29 5.64 1.04 3.92 1065
# 2     1 13.20  1.78 2.14 11.2 100 2.65 2.76     0.26  1.28 4.38 1.05 3.40 1050
# 3     1 13.16  2.36 2.67 18.6 101 2.80 3.24     0.30  2.81 5.68 1.03 3.17 1185
# 4     1 14.37  1.95 2.50 16.8 113 3.85 3.49     0.24  2.18 7.80 0.86 3.45 1480
# 5     1 13.24  2.59 2.87 21.0 118 2.80 2.69     0.39  1.82 4.32 1.04 2.93  735
# 6     1 14.20  1.76 2.45 15.2 112 3.27 3.39     0.34  1.97 6.75 1.05 2.85 1450
##第一列是分类信息,其余是化合物的成分含量信息

2.2 确定预测目标与训练方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#根据化合物不同成分含量信息预测葡萄酒类别
task_classif = as_task_classif(wineTib, target = "Class")
task_classif$col_roles$stratum = "Class"

#(1)使用LDA方法
learner_lda =  lrn("classif.lda", predict_type = "prob")
learner_lda$param_set
#(2)使用QDA方法
learner_qda =  lrn("classif.qda", predict_type = "prob")
learner_qda$param_set

2.3 模型训练、预测

(1)LDA模型
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
## 如下使用60%数据训练、40%数据验证
split = partition(task_classif, ratio = 0.6, stratify = T)
learner_lda$train(task_classif, row_ids = split$train)

##查看每个判别函数的原始预测变量的系数
learner_lda$model$scaling %>% head()
#                   LD1          LD2
# Alco     -0.180181333  0.635051170
# Alk       0.165256494 -0.068839677
# Ash      -0.873518671  1.616419123
# Col       0.387893842  0.430329481
# Flav     -2.612862657 -0.534148633
# Hue       0.557758645 -0.757887040

prediction = learner_lda$predict(task_classif, row_ids = split$test)
prediction$confusion
# response  1  2  3
#        1 24  0  0
#        2  0 27  0
#        3  0  1 19

##查看每个样本在新的预测变量(判别函数)的值
predict(learner_lda$model, task_classif$data())$x %>% head
#         LD1      LD2
# 1 -4.741629 2.136846
# 2 -4.106043 1.788338
# 3 -3.746176 1.510430
# 4 -3.588112 4.769435
# 5 -1.482220 0.614548
# 6 -3.944203 4.090119
##可视化
ldaPreds <- predict(learner_lda$model, task_classif$data())$x
wineTib %>%
  mutate(LD1 = ldaPreds[, 1], 
         LD2 = ldaPreds[, 2]) %>%
  ggplot(aes(LD1, LD2, col = Class)) +
  geom_point() +
  stat_ellipse() +
  theme_bw()
image-20220404165400730
  • 交叉验证
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
resampling = rsmp("cv")
rr = resample(task_classif, learner_lda, resampling)
rr$prediction()
rr$score(msr("classif.acc"))[,c(-1,-3,-5,-8)]
#    task_id  learner_id resampling_id iteration classif.acc
#  1: wineTib classif.lda            cv         1   0.9473684
#  2: wineTib classif.lda            cv         2   0.9444444
#  3: wineTib classif.lda            cv         3   1.0000000
#  4: wineTib classif.lda            cv         4   1.0000000
#  5: wineTib classif.lda            cv         5   0.9444444
#  6: wineTib classif.lda            cv         6   1.0000000
#  7: wineTib classif.lda            cv         7   1.0000000
#  8: wineTib classif.lda            cv         8   1.0000000
#  9: wineTib classif.lda            cv         9   1.0000000
# 10: wineTib classif.lda            cv        10   1.0000000
rr$aggregate(msr("classif.acc"))
#classif.acc 
#  0.9836257 
(2)QDA
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
## 如下使用60%数据训练、40%数据验证
split = partition(task_classif, ratio = 0.6, stratify = T)
learner_qda$train(task_classif, row_ids = split$train)

prediction = learner_qda$predict(task_classif, row_ids = split$test)
prediction$confusion
#         truth
# response  1  2  3
#        1 24  0  0
#        2  0 28  0
#        3  0  0 19
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#交叉验证
resampling = rsmp("cv")
rr = resample(task_classif, learner_qda, resampling)
rr$prediction()
rr$score(msr("classif.acc"))[,c(-1,-3,-5,-8)]
#     task_id  learner_id resampling_id iteration classif.acc
#  1: wineTib classif.qda            cv         1   1.0000000
#  2: wineTib classif.qda            cv         2   1.0000000
#  3: wineTib classif.qda            cv         3   1.0000000
#  4: wineTib classif.qda            cv         4   1.0000000
#  5: wineTib classif.qda            cv         5   1.0000000
#  6: wineTib classif.qda            cv         6   0.9444444
#  7: wineTib classif.qda            cv         7   0.9444444
#  8: wineTib classif.qda            cv         8   1.0000000
#  9: wineTib classif.qda            cv         9   1.0000000
# 10: wineTib classif.qda            cv        10   1.0000000
rr$aggregate(msr("classif.acc"))
#classif.acc 
#  0.9888889

注意到LDA与QDA的预测结果并不一致。下面通过交叉验证哪一种模型的性能更好一些。