12  机器学习概念

对于是否用到标记还可以将学习任务划分为:

每个具体的输入是一个实例,通常以特征向量来表示(feature vector),所有特征向量的空间就是特征空间。特征向量写作

\[ x=(x_1,x_2,\cdots x_n) \]

机器学习三要素:方法=模型+策略+算法。

模型:也就是输入到机器中训练的数据集(包括训练集和验证集)然后通过训练得到模型(学习器)最后测试集测试。模型的假设空间包含所有的条件概率分布或决策函数。

参数空间:对于\(X\)\(Y\)是定义在\(\mathcal{X}\)\(\mathcal{Y}\)的变量,这时\(\mathcal{F}\)被认为是一个由参数向量决定的函数族: \[ \mathcal{F}=\{f|Y=f_\theta(X),\theta\in R^n\} \] 这里的参数取决于\(n\)维欧式空间\(R^n\)

优化算法:需要对一些难以解决的问题进行优化求解,对于机器学习来说就是需要考虑时候发什么样的模型进行求解模型。

训练误差(training error)就是平均损失: \[R_{emp}=\frac{1}{N}\sum_{i=1}^NL(y_i,\hat{f}(x_i))\] 其中N表示的是训练容量。测试误差(test error)是模型\(Y=\hat{f}(X)\)一个测试验证集的平均损失: \[e_{test}=\frac{1}{N'}\sum_{i=1}^{N'}L(y_i,\hat{f}(x_i))\] 其中\(N'\)表示测试样本容量。

测试误差反映了学习方法对未知测试集的预测能力。一般将这个能力称为泛化能力(generalization ability)

通过正则化进行模型选择是一个经典方法,正则化是结构风险最小化的策略。在经验风险上加入一个惩罚项(penalty term)。模型越复杂,惩罚项越大。 一般形式:

\[ \min_{f\in \mathcal{F}}\frac{1}{N}\sum_{i=1}^NL(y_i,f(x_i))+\lambda J(f) \]

奥卡姆剃刀定律:若有多个假设与观测值一致,选择最简单的一个。

12.1 机器学习R包

在机器学习应用领域,python中的sklearn是最常被使用的一个包,而在R中,mlr3包,也是一个较为完善的机器学习集成包。

安装:

install.packages("mlr3")
# 或者
remotes::install_github("mlr-org/mlr3")

mlr3的基本工作流为通过构建模块和操作实现,包括创建有监督的机器学习任务、如分类、回归等。对新数据进行预测、使用交叉验证和标杆管理(benchmarking)评价和比较不同模型。

12.1.1 mlr3基本工作流程

library(mlr3)
task = TaskClassif$new(id="iris", backend=iris, target="Species") 
# task = tsk("iris")    
task
<TaskClassif:iris> (150 x 5)
* Target: Species
* Properties: multiclass
* Features (4):
  - dbl (4): Petal.Length, Petal.Width, Sepal.Length, Sepal.Width
learner = lrn("classif.rpart",cp=0.1,minsplit=10)
learner
<LearnerClassifRpart:classif.rpart>: Classification Tree
* Model: -
* Parameters: xval=0, cp=0.1, minsplit=10
* Packages: mlr3, rpart
* Predict Types:  [response], prob
* Feature Types: logical, integer, numeric, factor, ordered
* Properties: importance, missings, multiclass, selected_features,
  twoclass, weights

划分训练集/抽样集

set.seed(123)
train = sample(task$nrow, 0.8 * task$nrow) 
test = setdiff(seq_len(task$nrow), train)

训练模型

learner$train(task, row_ids=train) 
learner$model  # 查看训练好的模型
n= 120 

node), split, n, loss, yval, (yprob)
      * denotes terminal node

1) root 120 75 virginica (0.33333333 0.29166667 0.37500000)  
  2) Petal.Length< 2.45 40  0 setosa (1.00000000 0.00000000 0.00000000) *
  3) Petal.Length>=2.45 80 35 virginica (0.00000000 0.43750000 0.56250000)  
    6) Petal.Length< 4.75 32  1 versicolor (0.00000000 0.96875000 0.03125000) *
    7) Petal.Length>=4.75 48  4 virginica (0.00000000 0.08333333 0.91666667) *

模型预测

predictions = learner$predict(task, row_ids=test)
predictions
<PredictionClassif> for 30 observations:
    row_ids     truth  response
          1    setosa    setosa
          2    setosa    setosa
          3    setosa    setosa
---                            
        125 virginica virginica
        131 virginica virginica
        141 virginica virginica

模型评估

predictions$confusion
            truth
response     setosa versicolor virginica
  setosa         10          0         0
  versicolor      0         13         0
  virginica       0          2         5

这里采用ACC准则来对模型进行评估:

measure = msr("classif.acc")
predictions$score(measure)     # 预测精度
classif.acc 
  0.9333333 

精度为93.33%。

重抽样,调用函数rsmp,选用参数为cv交叉验证方法,折数为3折。

resampling = rsmp("cv", folds = 3L)
rr = resample(task, learner, resampling)
INFO  [00:35:16.905] [mlr3] Applying learner 'classif.rpart' on task 'iris' (iter 1/3)
INFO  [00:35:16.951] [mlr3] Applying learner 'classif.rpart' on task 'iris' (iter 2/3)
INFO  [00:35:16.972] [mlr3] Applying learner 'classif.rpart' on task 'iris' (iter 3/3)
rr$score(measure)
                task task_id                   learner    learner_id
1: <TaskClassif[50]>    iris <LearnerClassifRpart[38]> classif.rpart
2: <TaskClassif[50]>    iris <LearnerClassifRpart[38]> classif.rpart
3: <TaskClassif[50]>    iris <LearnerClassifRpart[38]> classif.rpart
           resampling resampling_id iteration              prediction
1: <ResamplingCV[20]>            cv         1 <PredictionClassif[20]>
2: <ResamplingCV[20]>            cv         2 <PredictionClassif[20]>
3: <ResamplingCV[20]>            cv         3 <PredictionClassif[20]>
   classif.acc
1:        0.92
2:        0.96
3:        0.98
rr$aggregate(measure)  
classif.acc 
  0.9533333 

此时的精度得到提升。

12.1.2 建立任务

mlr3包括了一些预先定义的机器学习任务在R6目录中mlr3::mlr_tasks

mlr_tasks
<DictionaryTask> with 11 stored values
Keys: boston_housing, breast_cancer, german_credit, iris, mtcars,
  penguins, pima, sonar, spam, wine, zoo

为从字典中获得一个任务,可以使用mlr::tsk()函数和返回一个新特征。比如在这里使用mlr_tasks_mtcars来获取数据集

task_mtcars = tsk("mtcars")
task_mtcars
<TaskRegr:mtcars> (32 x 11): Motor Trends
* Target: mpg
* Properties: -
* Features (10):
  - dbl (10): am, carb, cyl, disp, drat, gear, hp, qsec, vs, wt
data("mtcars", package = "datasets")
str(mtcars)
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

12.1.2.1 可视化

mtcars_subset = subset(mtcars, select = c("mpg", "cyl", "disp"))
task_mtcars = as_task_regr(mtcars_subset, target = "mpg", id = "cars")
task_mtcars
<TaskRegr:cars> (32 x 3)
* Target: mpg
* Properties: -
* Features (2):
  - dbl (2): cyl, disp
library("mlr3viz")
autoplot(task_mtcars, type = "pairs")
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2