添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

以 iris 数据集为例,简单,方便介绍模型和算法,定位入门。分类间隔最大化,也是一个优化问题,找一条分界线,一个分割面,一个超平面划分不同的种类。本章篇幅:每个算法 4 页,共计 40 页。10 个算法的介绍按照分类思路,模型,代码和参数说明,分类性能评估。应用案例是手写数字识别。要点不是数据如何复杂,而是怎样把理论写得通俗、准确,看了之后能够应用到复杂的真实数据分析场景中去。理论解释、绘图说明、经验总结。

  • 线性分类器
  • 多项回归模型
  • 线性判别分析
  • 非线性分类器
  • 二次判别分析
  • 朴素贝叶斯
  • 支持向量机
  • K 最近邻
  • iris 数据集也来自 Base R 自带的 datasets 包,由 Anderson Edgar 收集,最早见于 1935 年的文章,后被 Ronald Fisher 在研究分类问题时引用 ( Fisher 1936 )。到如今,在机器学习的社区里,提及 iris 数据集,一般只知 Fisher 不知 Anderson。

    Call:
    multinom(formula = Species ~ ., data = iris, trace = FALSE)
    Coefficients:
               (Intercept) Sepal.Length Sepal.Width Petal.Length Petal.Width
    versicolor    18.69037    -5.458424   -8.707401     14.24477   -3.097684
    virginica    -23.83628    -7.923634  -15.370769     23.65978   15.135301
    Std. Errors:
               (Intercept) Sepal.Length Sepal.Width Petal.Length Petal.Width
    versicolor    34.97116     89.89215    157.0415     60.19170    45.48852
    virginica     35.76649     89.91153    157.1196     60.46753    45.93406
    Residual Deviance: 11.89973 
    AIC: 31.89973 
    setosa versicolor virginica setosa 50 0 0 versicolor 0 49 1 virginica 0 1 49

    在有的数据中,观测变量之间存在共线性,采用变量选择方法,比如 Lasso 方法压缩掉一部分变量。

    iris_lda_pred setosa versicolor virginica setosa 50 0 0 versicolor 0 48 1 virginica 0 2 49 1.3 二次判别分析
    Call:
    qda(Species ~ ., data = iris)
    Prior probabilities of groups:
        setosa versicolor  virginica 
     0.3333333  0.3333333  0.3333333 
    Group means:
               Sepal.Length Sepal.Width Petal.Length Petal.Width
    setosa            5.006       3.428        1.462       0.246
    versicolor        5.936       2.770        4.260       1.326
    virginica         6.588       2.974        5.552       2.026
    iris_qda_pred <- predict (iris_qda, iris[, - 5 ]) $ class iris_qda_pred setosa versicolor virginica setosa 50 0 0 versicolor 0 48 1 virginica 0 2 49
    代码 1.4 朴素贝叶斯 Naive Bayes Classifier for Discrete Predictors Call: naiveBayes.default(x = X, y = Y, laplace = laplace) A-priori probabilities: setosa versicolor virginica 0.3333333 0.3333333 0.3333333 Conditional probabilities: Sepal.Length Y [,1] [,2] setosa 5.006 0.3524897 versicolor 5.936 0.5161711 virginica 6.588 0.6358796 Sepal.Width Y [,1] [,2] setosa 3.428 0.3790644 versicolor 2.770 0.3137983 virginica 2.974 0.3224966 Petal.Length Y [,1] [,2] setosa 1.462 0.1736640 versicolor 4.260 0.4699110 virginica 5.552 0.5518947 Petal.Width Y [,1] [,2] setosa 0.246 0.1053856 versicolor 1.326 0.1977527 virginica 2.026 0.2746501 iris_nb_pred <- predict (iris_nb, newdata = iris, type = "class" ) # 预测结果 table (iris_nb_pred, iris[, 5 ]) iris_nb_pred setosa versicolor virginica setosa 50 0 0 versicolor 0 47 3 virginica 0 3 47 1.5 支持向量机

    e1071 包也提供支持向量机

    # e1071
    iris_svm <- svm(Species ~ ., data = iris)
    iris_svm
    Call: svm(formula = Species ~ ., data = iris) Parameters: SVM-Type: C-classification SVM-Kernel: radial cost: 1 Number of Support Vectors: 51 iris_svm_pred <- predict (iris_svm, newdata = iris, probability = FALSE ) # 预测结果 table (iris_svm_pred, iris[, 5 ]) iris_svm_pred setosa versicolor virginica setosa 50 0 0 versicolor 0 48 2 virginica 0 2 48

    kernlab 包提供核支持向量机。

    Support Vector Machine object of class "ksvm" 
    SV type: C-svc  (classification) 
     parameter : cost C = 1 
    Gaussian Radial Basis kernel function. 
     Hyperparameter : sigma =  1.08127435821472 
    Number of Support Vectors : 64 
    Objective Function Value : -5.3341 -6.0361 -19.6926 
    Training error : 0.02 

    kernlab ( Karatzoglou 等 2004 ) 的绘图函数 plot() 仅支持二分类模型。

    iris_pred_svm setosa versicolor virginica setosa 50 0 0 versicolor 0 48 1 virginica 0 2 49 1.6 K 最近邻
                iris_species
    iris_knn     setosa versicolor virginica
      setosa         25          0         0
      versicolor      0         23         3
      virginica       0          2        22
    1.7 神经网络
    a 4-4-3 network with 35 weights
    options were - softmax modelling 
     b->h1 i1->h1 i2->h1 i3->h1 i4->h1 
      2.91  -3.46   7.46  -2.90   3.25 
     b->h2 i1->h2 i2->h2 i3->h2 i4->h2 
     -2.65   1.26   3.26   5.85 -24.78 
     b->h3 i1->h3 i2->h3 i3->h3 i4->h3 
     -9.10  -0.07  -1.32   3.50  -2.13 
     b->h4 i1->h4 i2->h4 i3->h4 i4->h4 
     -0.53  -1.63  -1.20  -0.61  -0.12 
     b->o1 h1->o1 h2->o1 h3->o1 h4->o1 
     -2.73  31.51  -2.15 -16.18  -0.49 
     b->o2 h1->o2 h2->o2 h3->o2 h4->o2 
      4.06  -4.35  10.82  -7.18   0.28 
     b->o3 h1->o3 h2->o3 h3->o3 h4->o3 
     -1.04 -26.77  -8.92  23.81   0.30 

    size 隐藏层中的神经元数量

    iris_pred_nnet setosa versicolor virginica setosa 50 0 0 versicolor 0 49 0 virginica 0 1 50 1.8 决策树
    n= 150 
    node), split, n, loss, yval, (yprob)
          * denotes terminal node
    1) root 150 100 setosa (0.33333333 0.33333333 0.33333333)  
      2) Petal.Length< 2.45 50   0 setosa (1.00000000 0.00000000 0.00000000) *
      3) Petal.Length>=2.45 100  50 versicolor (0.00000000 0.50000000 0.50000000)  
        6) Petal.Width< 1.75 54   5 versicolor (0.00000000 0.90740741 0.09259259) *
        7) Petal.Width>=1.75 46   1 virginica (0.00000000 0.02173913 0.97826087) *
    iris_pred_rpart <- predict (iris_rpart, iris[, - 5 ], type = "class" ) # 预测结果 table (iris_pred_rpart, iris[, 5 ]) iris_pred_rpart setosa versicolor virginica setosa 50 0 0 versicolor 0 49 5 virginica 0 1 45

    party 包和 partykit 包也提供类似的功能,前者是基于 C 语言实现,后者基于 R 语言实现。

    代码 1.9 随机森林 Call: randomForest(formula = Species ~ ., data = iris, importance = TRUE, proximity = TRUE) Type of random forest: classification Number of trees: 500 No. of variables tried at each split: 2 OOB estimate of error rate: 4% Confusion matrix: setosa versicolor virginica class.error setosa 50 0 0 0.00 versicolor 0 47 3 0.06 virginica 0 3 47 0.06
    代码 iris_pred_rf setosa versicolor virginica setosa 50 0 0 versicolor 0 50 0 virginica 0 0 50 1.10 集成学习

    在训练模型之前,需要先对数据集做预处理,包括分组采样、类别编码、数据拆分、类型转换等。

    制作一个函数对数据集添加新列 mark 作为训练集 train 和测试集 test 的采样标记,返回数据。

    # 输入数据 x 和采样比例 prop
    add_mark <- function(x = iris, prop = 0.7) {
      idx <- sample(x = nrow(x), size = floor(nrow(x) * prop))
      rbind(
        cbind(x[idx, ], mark = "train"),
        cbind(x[-idx, ], mark = "test")
    

    为了使采样结果可重复,设置随机数种子,然后对 iris 数据集按列 Species 分组添加采样标记,分组随机抽取 70% 的样本作为训练数据,余下的作为测试数据。就 iris 数据集来说,训练集有 35*3 = 105 条记录,测试集有 15*3 = 45 条记录。

    为了使用函数 fcase() 对分类变量 Species 做重编码操作,加载 data.table 包,将数据集 iris_df 转为 data.table 类型。值得注意,xgboost 包要求分类变量的类别序号必须从 0 开始。

    # 数据准备
    library(data.table)
    iris_dt <- as.data.table(iris_df)
    iris_dt <- iris_dt[, Species := fcase(
      Species == "setosa", 0,
      Species == "versicolor", 1,
      Species == "virginica", 2
    

    将数据 iris_dt 拆分成训练集和测试集,并以列表结构存储数据,样本数据及标签以矩阵类型存储。

    # 训练数据
    iris_train <- list(
      data = as.matrix(iris_dt[iris_dt$mark == "train", -c("mark", "Species")]),
      label = as.matrix(iris_dt[iris_dt$mark == "train", "Species"])
    # 测试数据
    iris_test <- list(
      data = as.matrix(iris_dt[iris_dt$mark == "test", -c("mark", "Species")]),
      label = as.matrix(iris_dt[iris_dt$mark == "test", "Species"])
    

    数据准备好后,加载 xgboost 包,设置训练参数,开始训练分类模型。此分类任务中类别超过 2,是多分类任务,学习任务是分类,目标函数可以是 objective = "multi:softprob" 或者 objective = "multi:softmax",相应的评估指标可以是 eval_metric = "mlogloss" 或者 eval_metric = "merror"iris 数据集的分类变量 Species 共有 3 类,所以 num_class = 3