• 45.2.1 evalCpp() 转换单一计算表达式
  • 45.2.2 cppFunction() 转换简单的C++函数—Fibnacci例子
  • 45.2.3 sourceCpp() 转换C++程序—正负交替迭代例子
  • 45.2.4 sourceCpp() 转换C++源文件中的程序—正负交替迭代例子
  • 45.2.5 sourceCpp() 转换C++源程序文件—卷积例子
  • 45.2.6 随机数例子
  • 45.2.7 bootstrap例子
  • 45.2.8 在Rmd文件中使用C++源程序文件
  • 46 R与C++的类型转换
  • 46.1 wrap() 把C++变量返回到R中
  • 46.2 as() 函数把R变量转换为C++类型
  • 46.3 as() wrap() 的隐含调用
  • 47 Rcpp 属性
  • 47.1 Rcpp属性介绍
  • 47.2 在C++源程序中指定要导出的C++函数
  • 47.2.1 特殊注释 //[[Rcpp::export]]
  • 47.2.2 修改导出的函数名
  • 47.2.3 可导出的函数
  • 47.3 在R中编译链接C++代码
  • 47.3.1 sourceCpp() 函数中直接包含C++源程序字符串
  • 47.3.2 cppFunction() 函数中直接包含C++函数源程序字符串
  • 47.3.3 evalCpp() 函数中直接包含C++源程序表达式字符串
  • 47.3.4 depends 指定要链接的库
  • 47.4 Rcpp属性的其它功能
  • 47.4.1 自变量有缺省值的函数
  • 47.4.2 异常传递
  • 47.4.3 允许用户中断
  • 47.4.4 把R代码写在C++源文件中
  • 47.4.5 invisible 要求函数结果不自动显示
  • 47.4.6 在C++中调用R的随机数发生器
  • 48 Rcpp提供的C++数据类型
  • 48.1 RObject类
  • 48.2 IntegerVector类
  • 48.2.1 IntegerVector示例1:返回完全数
  • 48.2.2 IntegerVector示例2:输入整数向量
  • 48.3 NumericVector类
  • 48.3.1 示例1:计算元素 \(p\) 次方的和
  • 48.3.2 示例2: clone 函数
  • 48.3.3 示例3:向量子集
  • 48.4 NumericMatrix类
  • 48.4.1 示例1:计算矩阵各列模的最大值
  • 48.4.2 示例2:把输入矩阵制作副本计算元素平方根
  • 48.4.3 示例3:访问列子集
  • 48.5 Rcpp的其它向量类
  • 48.5.1 Rcpp的LogicalVector类
  • 48.5.2 Rcpp的CharacterVector类型
  • 48.6 Rcpp提供的其它数据类型
  • 48.6.1 Named类型
  • 48.6.2 List类型
  • 48.6.3 Rcpp的DataFrame类
  • 48.6.4 Rcpp的Function类
  • 48.6.5 Rcpp的Environment类
  • 49 Rcpp糖
  • 49.1 简单示例
  • 49.2 向量化的运算符
  • 49.2.1 向量化的四则运算
  • 49.2.2 向量化的赋值运算
  • 49.2.3 向量化的二元逻辑运算
  • 49.2.4 向量化的一元运算符
  • 49.3 用Rcpp访问数学函数
  • 49.4 用Rcpp访问统计分布类函数
  • 49.5 在Rcpp中产生随机数
  • 49.6 返回单一逻辑值的函数
  • 49.7 返回糖表达式的函数
  • 49.7.1 is_na
  • 49.7.2 seq_along
  • 49.7.3 seq_len
  • 49.7.4 pmin pmax
  • 49.7.5 ifelse
  • 49.7.6 sapply lapply
  • 49.7.7 sign
  • 49.7.8 diff
  • 49.8 R与Rcpp不同语法示例
  • 49.9 用RcppArmadillo执行矩阵运算
  • 49.9.1 生成多元正态分布随机数
  • 49.9.2 快速计算线性回归
  • 50 用Rcpp帮助制作R扩展包
  • 50.1 不用扩展包共享C++代码的方法
  • 50.2 生成扩展包
  • 50.2.1 利用已有基于Rcpp属性的源程序制作扩展包
  • 50.2.2 DESCRIPTION文件
  • 50.2.3 NAMESPACE文件
  • 50.3 重新编译
  • 50.4 建立C++用的接口界面
  • 51 R编程例子
  • 51.1 R语言
  • 51.1.1 用向量作逆变换
  • 51.1.2 斐波那契数列计算
  • 51.1.3 穷举所有排列
  • 51.1.4 可重复分组方式穷举
  • 51.1.5 升降连计数
  • 51.1.6 高斯八皇后问题
  • 51.1.7 最小能量路径
  • 51.2 概率
  • 51.2.1 智者千虑必有一失
  • 51.2.2 圆桌夫妇座位问题
  • 51.3 科学计算
  • 51.3.1 城市间最短路径
  • 51.3.2 Daubechies小波函数计算
  • 51.3.3 房间加热温度变化
  • 51.4 统计计算
  • 51.4.1 线性回归实例
  • 51.4.2 核回归与核密度估计
  • 51.4.3 二维随机模拟积分
  • 51.4.4 潜周期估计
  • 51.4.5 ARMA(1,1)模型估计
  • 51.4.6 VAR模型平稳性
  • 51.4.7 贮存可靠性评估
  • 51.5 数据处理
  • 51.5.1 小题分题型分数汇总
  • 51.5.2 类别编号重排
  • 51.6 文本处理
  • 51.6.1 用R语言下载处理《红楼梦》htm文件
  • 52 使用经验
  • 52.1 文件管理
  • 52.1.1 文件备份
  • 52.1.2 工作空间
  • 52.2 程序格式
  • A R Markdown文件格式
  • A.1 R Markdown文件
  • A.2 R Markdown文件的编译
  • A.2.1 编译的实际过程
  • A.3 在R Markdown文件中插入R代码
  • A.4 输出表格
  • A.5 利用R程序插图
  • A.6 冗余输出控制
  • A.7 代码段选项
  • A.7.1 代码和文本输出结果格式
  • A.7.2 图形选项
  • A.7.3 缓存(cache)选项
  • A.8 章节目录链接问题
  • A.9 其它编程语言引擎
  • A.10 交互内容
  • A.11 属性设置
  • A.11.1 YAML元数据
  • A.11.2 输出格式
  • A.11.3 输出格式设置
  • A.11.4 目录设置
  • A.11.5 章节自动编号
  • A.11.6 Word输出章节自动编号及模板功能
  • A.11.7 HTML特有输出格式设置
  • A.11.8 关于数学公式支持的设置
  • A.11.9 输出设置文件
  • A.12 LaTeX和PDF输出
  • A.12.1 TinyTex的安装使用
  • A.12.2 Rmd中Latex设置
  • A.13 生成期刊文章
  • A.14 附录:经验与问题
  • A.14.1 Word模板制作
  • A.14.2 数学公式设置补充
  • B 用bookdown制作图书
  • B.1 介绍
  • B.2 一本书的设置
  • B.3 章节结构
  • B.4 书的编译
  • B.5 交叉引用
  • B.6 数学公式和公式编号
  • B.7 定理类编号
  • B.8 文献引用
  • B.9 插图
  • B.10 表格
  • B.10.1 Markdown表格
  • B.10.2 kable() 函数制作表格
  • B.10.3 R中其它制作表格的包
  • B.11 数学公式的设置
  • B.12 使用经验
  • B.12.1 学位论文
  • B.12.2 LaTeX
  • B.12.3 算法
  • B.12.4 中文乱码
  • B.12.5 图片格式
  • B.12.6 其它经验
  • B.13 bookdown的一些使用问题
  • C 用R Markdown制作简易网站
  • C.1 介绍
  • C.2 简易网站制作
  • C.2.1 网站结构
  • C.2.2 编译
  • C.2.3 内容文件
  • C.2.4 网站设置
  • C.3 用blogdown制作网站
  • C.3.1 生成新网站的框架
  • C.3.2 网页内容文件及其设置
  • C.3.3 初学者的工作流程
  • C.3.4 网站设置文件
  • C.3.5 静态文件
  • D 制作幻灯片
  • D.1 介绍
  • D.2 Slidy幻灯片
  • D.2.1 文件格式
  • D.2.2 幻灯片编译
  • D.2.3 播放控制
  • D.2.4 生成单页HTML
  • D.2.5 数学公式处理与输出设置文件
  • D.2.6 其它选项
  • D.2.7 slidy幻灯片激光笔失效问题的修改
  • D.3 MS PowerPoint幻灯片
  • D.4 Bearmer幻灯片格式
  • D.5 R Presentation格式
  • References
  • 编著:李东风
  • 统计学习介绍的主要参考书: ( James et al. 2013 ) : Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani(2013) An Introduction to Statistical Learning: with Applications in R, Springer.

    调入需要的扩展包:

    38.1.1 统计学习的基本概念和方法

    统计学习(statistical learning), 也有数据挖掘(data mining),机器学习(machine learning)等称呼。 主要目的是用一些计算机算法从大量数据中发现知识。 方兴未艾的数据科学就以统计学习为重要支柱。 方法分为有监督(supervised)学习与无监督(unsupervised)学习。

    无监督学习方法如聚类问题、购物篮问题、主成分分析等。

    有监督学习 即统计中回归分析和判别分析解决的问题, 现在又有树回归、树判别、随机森林、lasso、支持向量机、 神经网络、贝叶斯网络、排序算法等许多方法。

    无监督学习 在给了数据之后, 直接从数据中发现规律, 比如聚类分析是发现数据中的聚集和分组现象, 购物篮分析是从数据中找到更多的共同出现的条目 (比如购买啤酒的用户也有较大可能购买火腿肠)。

    有监督学习方法众多。 通常,需要把数据分为训练样本和检验样本, 训练样本的因变量(数值型或分类型)是已知的, 根据训练样本中自变量和因变量的关系训练出一个回归函数, 此函数以自变量为输入, 可以输出因变量的预测值。

    训练出的函数有可能是有简单表达式的(例如,logistic回归)、 有参数众多的表达式的(如神经网络), 也有可能是依赖于所有训练样本而无法写出表达式的(例如k近邻分类)。

    38.1.2 偏差与方差折衷

    对回归问题,经常使用均方误差 \(E|Ey - \hat y|^2\) 来衡量精度。 对分类问题,经常使用分类准确率等来衡量精度。 易见 \(E|Ey - \hat y|^2 = \text{Var}(\hat y) + (E\hat y - E y)^2\) ,所以均方误差可以分解为 \text{均方误差} = \text{方差} + \text{偏差}^2,

    训练的回归函数如果仅考虑对训练样本解释尽可能好, 就会使得估计结果方差很大,在对检验样本进行计算时因方差大而导致很大的误差, 所以选取的回归函数应该尽可能简单。

    如果选取的回归函数过于简单而实际上自变量与因变量关系比较复杂, 就会使得估计的回归函数偏差比较大, 这样在对检验样本进行计算时也会有比较大的误差。

    所以,在有监督学习时, 回归函数的复杂程度是一个很关键的量, 太复杂和太简单都可能导致差的结果, 需要找到一个折衷的值。

    复杂程度在线性回归中就是自变量个数, 在一元曲线拟合中就是曲线的不光滑程度。 在其它指标类似的情况下,简单的模型更稳定、可解释更好, 所以统计学特别重视模型的简化。

    38.1.3 交叉验证

    即使是在从训练样本中修炼(估计)回归函数时, 也需要适当地选择模型的复杂度。 仅考虑对训练数据的拟合程度是不够的, 这会造成过度拟合问题。

    为了相对客观地度量模型的预报误差, 假设训练样本有 \(n\) 个观测, 可以留出第一个观测不用, 用剩余的 \(n-1\) 个观测建模,然后预测第一个观测的因变量值, 得到一个误差;对每个观测都这样做, 就可以得到 \(n\) 个误差。 这样的方法叫做留一法。

    更常用的是五折或十折交叉验证。 假设训练集有 \(n\) 个观测, 将其均分成 \(10\) 分, 保留第一份不用, 将其余九份合并在一起用来建模,然后预报第一份; 对每一份都这样做, 也可以得到 \(n\) 个误差, 这叫做十折(ten-fold)交叉验证方法。

    因为要预报的数据没有用来建模, 交叉验证得到的误差估计更准确。

    38.1.4 一般步骤

    一个有监督的统计学习项目, 大致上按如下步骤进行:

  • 将数据拆分为训练集和测试集;
  • 在训练集上比较不同的模型, 可以用交叉验证方法比较;
  • 使用训练集上找到的最优模型, 对测试集进行测试;
  • 在整个数据集上使用找到的最优模型, 但预测效果的指标使用测试集上得到的预测效果指标。
  • 变量包括:

    38.2.1.1 最优子集选择

    用leaps包的 regsubsets() 函数计算最优子集回归, 办法是对某个试验性的子集自变量个数 \(\hat p\) 值, 都找到 \(\hat p\) 固定情况下残差平方和最小的变量子集, 这样只要在这些不同 \(\hat p\) 的最优子集中挑选就可以了。 挑选可以用AIC、BIC等方法。

    可以先进行一个包含所有自变量的全集回归:

    在用做了全集回归后, 把全集回归结果输入到函数中可以执行逐步回归。

    在整个数据集中随机选取一部分作为训练集,其余作为测试集。 下面的程序把原始数据一分为二:

    下列程序对数据中每一行分配一个折号:

    当自变量个数太多时,模型复杂度高, 可能有过度拟合, 模型不稳定。

    一种方法是对较大的模型系数施加二次惩罚, 把最小二乘问题变成带有二次惩罚项的惩罚最小二乘问题: \[\begin{aligned} \min\; \sum_{i=1}^n \left( y_i - \beta_0 - \beta_1 x_{i1} - \dots - \beta_p x_{ip} \right)^2 + \lambda \sum_{j=1}^p \beta_j^2 . \end{aligned}\] 这比通常最小二乘得到的回归系数绝对值变小, 但是求解的稳定性增加了,避免了共线问题。

    与线性模型\(\boldsymbol Y = \boldsymbol X \boldsymbol\beta + \boldsymbol\varepsilon\) 的普通最小二乘解 \(\hat{\boldsymbol\beta} = (\boldsymbol X^T \boldsymbol X)^{-1} \boldsymbol X^T \boldsymbol Y\) 岭回归问题的解为 \tilde{\boldsymbol\beta} = (\boldsymbol X^T \boldsymbol X + s \boldsymbol I)^{-1} \boldsymbol X^T \boldsymbol Y 其中\(\boldsymbol I\)为单位阵,\(s>0\)\(\lambda\)有关。

    \(\lambda\)称为调节参数,\(\lambda\)越大,相当于模型复杂度越低。 适当选择\(\lambda\)可以在方差与偏差之间找到适当的折衷, 从而减小预测误差。

    由于量纲问题,在不同自变量不可比时,数据集应该进行标准化。

    用R的glmnet包计算岭回归。 用glmnet()函数, 指定参数alpha=0时执行的是岭回归。 用参数lambda=指定一个调节参数网格, 岭回归将在这些调节参数上计算。 用coef()从回归结果中取得不同调节参数对应的回归系数估计, 结果是一个矩阵,每列对应于一个调节参数。

    仍采用上面去掉了缺失值的Hitters数据集结果d。

    如下程序把回归的设计阵与因变量提取出来:

    如下程序把数据分为一半训练、一半测试:

    仍使用训练集, 但训练集再进行交叉验证。 cv.glmnet()函数可以执行交叉验证。

    另一种对回归系数的惩罚是\(L_1\)惩罚: \[\begin{align} \min\; \sum_{i=1}^n \left( y_i - \beta_0 - \beta_1 x_{i1} - \dots - \beta_p x_{ip} \right)^2 + \lambda \sum_{j=1}^p |\beta_j| . \tag{38.1} \end{align}\] 奇妙地是,适当选择调节参数\(\lambda\),可以使得部分回归系数变成零, 达到了即减小回归系数的绝对值又挑选重要变量子集的效果。

    事实上,(38.1)等价于约束最小值问题 \[\begin{aligned} & \min\; \sum_{i=1}^n \left( y_i - \beta_0 - \beta_1 x_{i1} - \dots - \beta_p x_{ip} \right)^2 \quad \text{s.t.} \\ & \sum_{j=1}^p |\beta_j| \leq s \end{aligned}\] 其中\(s\)\(\lambda\)一一对应。 这样的约束区域是带有顶点的凸集, 而目标函数是二次函数, 最小值点经常在约束区域顶点达到, 这些顶点是某些坐标等于零的点。 见图38.4

    (38.1)的相应解, 记为\(\hat{\boldsymbol\beta}(\lambda)\)。 幸运的是, 不需要对每个\(\lambda\)去解最小值问题(38.1), 存在巧妙的算法使得问题的计算量与求解一次最小二乘相仿。

    通常选取\(\lambda\)的格子点,计算相应的惩罚回归系数。 用交叉验证方法估计预测的均方误差。 选取使得交叉验证均方误差最小的调节参数(一般R函数中已经作为选项)。

    用R的glmnet包计算lasso。 用glmnet()函数, 指定参数alpha=1时执行的是lasso。 用参数lambda=指定一个调节参数网格, lasso将输出这些调节参数对应的结果。 对回归结果使用plot()函数可以画出调节参数变化时系数估计的变化情况。

    仍使用gmlnet包的glmnet()函数计算Lasso回归, 指定一个调节参数网格(沿用前面的网格):

    按照前面划分的训练集与测试集, 仅使用训练集数据做交叉验证估计最优调节参数:

    决策树方法按不同自变量的不同值, 分层地把训练集分组。 每层使用一个变量, 所以这样的分组构成一个二叉树表示。 为了预测一个观测的类归属, 找到它所属的组, 用组的类归属或大多数观测的类归属进行预测。 这样的方法称为决策树(decision tree)。 决策树方法既可以用于判别问题, 也可以用于回归问题,称为回归树。

    决策树的好处是容易解释, 在自变量为分类变量时没有额外困难。 但预测准确率可能比其它有监督学习方法差。

    改进方法包括装袋法(bagging)、随机森林(random forests)、 提升法(boosting)。 这些改进方法都是把许多棵树合并在一起, 通常能改善准确率但是可解释性变差。

    对Hitters数据,用Years和Hits作因变量预测log(Salaray)。

    仅取Hitters数据集的Salary, Years, Hits三个变量, 并仅保留完全观测:

    把数据随机地分成一半训练集,一半测试集:

    判别树在不同的训练集、测试集划分上可以产生很大变化, 说明其预测值方差较大。 利用bootstrap的思想, 可以随机选取许多个训练集, 把许多个训练集的模型结果平均, 就可以降低预测值的方差。

    办法是从一个训练集中用有放回抽样的方法抽取 \(B\) 个训练集, 设第 \(b\) 个抽取的训练集得到的回归函数为 \(\hat f^{*b}(\cdot)\) , 则最后的回归函数是这些回归函数的平均值: \[\begin{aligned} \hat f_{\text{bagging}}(x) = \frac{1}{B} \sum_{b=1}^b \hat f^{*b}(x) \end{aligned}\] 这称为装袋法(bagging)。 装袋法对改善判别与回归树的精度十分有效。

    装袋法的步骤如下:

  • 从训练集中取 \(B\) 个有放回随机抽样的bootstrap训练集, \(B\) 取为几百到几千之间。
  • 对每个bootstrap训练集,估计未剪枝的树。
  • 如果因变量是连续变量,对测试样品,用所有的树的预测值的平均值作预测。
  • 如果因变量是分类变量,对测试样品,可以用所有树预测类的多数投票决定预测值。
  • 装袋法也可以用来改进其他的回归和判别方法。

    装袋后不能再用图形表示,模型可解释性较差。 但是,可以度量自变量在预测中的重要程度。 在回归问题中, 可以计算每个自变量在所有 \(B\) 个树种平均减少的残差平方和的量, 以此度量其重要度。 在判别问题中, 可以计算每个自变量在所有 \(B\) 个树种平均减少的基尼系数的量, 以此度量其重要度。

    除了可以用测试集、交叉验证方法以外, 还可以使用袋外观测预测误差。 用bootstrap再抽样获得多个训练集时每个bootstrap训练集总会遗漏一些观测, 平均每个bootstrap训练集会遗漏三分之一的观测。 对每个观测,大约有 \(B/3\) 棵树没有用到此观测, 可以用这些树的预测值平均来预测此观测,得到一个误差估计, 这样得到的均方误差估计或错判率称为 袋外观测估计 (OOB估计)。 好处是不用很多额外的工作。

    对训练集用装袋法:

    随机森林的思想与装袋法类似, 但是试图使得参加平均的各个树之间变得比较独立。 仍采用有放回抽样得到的多个bootstrap训练集, 但是对每个bootstrap训练集构造判别树时, 每次分叉时不考虑所有自变量, 而是仅考虑随机选取的一个自变量子集。

    对判别树,每次分叉时选取的自变量个数通常取 \(m \approx \sqrt{p}\) 个。 比如,对Heart数据的13个自变量, 每次分叉时仅随机选取4个纳入考察范围。

    随机森林的想法是基于正相关的样本在平均时并不能很好地降低方差, 独立样本能比较好地降低方差。 如果存在一个最重要的变量, 如果不加限制这个最重要的变量总会是第一个分叉, 使得 \(B\) 棵树相似程度很高。 随机森林解决这个问题的办法是限制分叉时可选的变量子集。

    随机森林也可以用来改进其他的回归和判别方法。

    装袋法和随机森林都可以用R扩展包randomForest的 randomForest() 函数实现。 当此函数的 mtry 参数取为自变量个数时,执行的就是装袋法; mtry 取缺省值时,执行随机森林算法。 执行随机森林算法时, randomForest() 函数在回归问题时分叉时考虑的自变量个数取 \(m \approx p/3\) , 在判别问题时取 \(m \approx \sqrt{p}\)

    对训练集用随机森林法:

    Heart数据是心脏病诊断的数据, 因变量AHD为是否有心脏病, 试图用各个自变量预测(判别)。

    读入Heart数据集,并去掉有缺失值的观测:

    Heart.csv

    38.3.1 树回归

    38.3.1.1 划分训练集与测试集

    简单地把观测分为一半训练集、一半测试集:

    用交叉验证方法确定剪枝保留的叶子个数,剪枝时按照错判率执行:

    对训练集用装袋法:

    对训练集用随机森林法:

    Carseats是ISLR包的一个数据集,基本情况如下: {rstatl-car-summ01, cache=TRUE} str(Carseats) summary(Carseats)

    把Salses变量按照大于8与否分成两组, 结果存入变量High,以High为因变量作判别分析。

    38.4.1.1 全体数据的判别树

    对全体数据建立未剪枝的判别树:

    把输入数据集随机地分一半当作训练集,另一半当作测试集:

    对训练集用随机森林法:

    MASS包的Boston数据包含了波士顿地区郊区房价的若干数据。 以中位房价medv为因变量建立回归模型。 首先把缺失值去掉后存入数据集d:

    38.5.1.1 划分训练集和测试集

    用randomForest包计算。 当参数mtry取为自变量个数时按照装袋法计算。 对训练集计算。

    用randomForest包计算。 当参数mtry取为缺省值时按照随机森林方法计算。 对训练集计算。

    支持向量机是1990年代有计算机科学家发明的一种有监督学习方法, 使用范围较广,预测精度较高。

    支持向量机利用了Hilbert空间的方法将线性问题扩展为非线性问题。 线性的支持向量判别法, 可以通过\(\mathbb R^p\)的内积将线性的判别函数转化为如下的表示:

    \[\begin{aligned} f(\boldsymbol x) = \beta_0 + \sum_{i=1}^n \alpha_i \langle \boldsymbol x, \boldsymbol x_i \rangle \end{aligned}\] 其中\(\beta_0, \alpha_1, \dots, \alpha_n\)是待定参数。 为了估计参数, 不需要用到各\(\boldsymbol x_i\)的具体值, 而只需要其两两的内积值, 而且在判别函数中只有支持向量对应的\(\alpha_i\)才非零, 记\(\mathcal S\)为支持向量点集, 则线性判别函数为 \[\begin{aligned} f(\boldsymbol x) = \beta_0 + \sum_{i \in \mathcal S} \alpha_i \langle \boldsymbol x, \boldsymbol x_i \rangle \end{aligned}\]

    支持向量机方法将\(\mathbb R^p\)中的内积推广为如下的核函数值: \[\begin{aligned} K(\boldsymbol x, \boldsymbol x') \end{aligned}\] 核函数\(K(\boldsymbol x, \boldsymbol x')\), \(\boldsymbol x, \boldsymbol x' \in \mathbb R^p\) 是度量两个观测点\(\boldsymbol x, \boldsymbol x'\)的相似程度的函数。 \[\begin{aligned} K(\boldsymbol x, \boldsymbol x') = \sum_{j=1}^p x_j x_j' \end{aligned}\] 就又回到了线性的支持向量判别法。

    核有多种取法。 \[\begin{aligned} K(\boldsymbol x, \boldsymbol x') = \left\{ 1 + \sum_{j=1}^p x_j x_j' \right\}^d \end{aligned}\] 其中\(d>1\)为正整数, 称为多项式核, 则结果是多项式边界的判别法, 本质上是对线性的支持向量方法添加了高次项和交叉项。

    利用核代替内积后, 判别法的判别函数变成 \[\begin{aligned} f(\boldsymbol x) = \beta_0 + \sum_{i \in \mathcal S} K(\boldsymbol x, \boldsymbol x_i) \end{aligned}\]

    另一种常用的核是径向核(radial kernel), \[\begin{aligned} K(\boldsymbol x, \boldsymbol x') = \exp\left\{ - \gamma \sum_{j=1}^p (x_j - x_j')^2 \right\} \end{aligned}\] \(\gamma\)为正常数。 当\(\boldsymbol x\)\(\boldsymbol x'\)分别落在以原点为中心的两个超球面上时, 其核函数值不变。

    使用径向核时, 判别函数为 \[\begin{aligned} f(\boldsymbol x) = \beta_0 + \sum_{i \in \mathcal S} \exp\left\{ - \gamma \sum_{j=1}^p (x_{j} - x_{ij})^2 \right\} \end{aligned}\] 对一个待判别的观测\(\boldsymbol x^*\), 如果\(\boldsymbol x^*\)距离训练观测点\(\boldsymbol x_i\)较远, 则\(K(\boldsymbol x^*, \boldsymbol x_i)\)的值很小, \(\boldsymbol x_i\)\(\boldsymbol x^*\)的判别基本不起作用。 这样的性质使得径向核方法具有很强的局部性, 只有离\(\boldsymbol x^*\)很近的点才对其判别起作用。

    为什么采用核函数计算观测两两的\(\binom{n}{2}\)个核函数值, 而不是直接增加非线性项? 原因是计算这些核函数值计算量是确定的, 而增加许多非线性项, 则可能有很大的计算量, 而且某些核如径向核对应的自变量空间维数是无穷维的, 不能通过添加维度的办法解决。

    支持向量机的理论基于再生核希尔伯特空间(RKHS), 可参见(Trevor Hastie 2009)节5.8和节12.3.3。

    38.6.1 支持向量机用于Heart数据

    考虑心脏病数据Heart的判别。 共297个观测, 随机选取其中207个作为训练集, 90个作为测试集。

    支持向量判别法就是SVM取多项式核, 阶数\(d=1\)的情形。 需要一个调节参数costcost越大, 分隔边界越窄, 过度拟合危险越大。

    先随便取调节参数cost=1试验支持向量判别法:

    径向核需要的参数为 \(\gamma\) 值。 取参数 gamma=0.1