量化机器学习系列分享(二)模型评估与特征选择
由dontbelazy创建,最终由dontbelazy 被浏览 49 用户
1. 模型评估
1.1 偏差与方差
上次分享我们提到过,模型的好坏评价标准,是模型在测试集上的预测是否准确,好比一个学生在期末考试当中拿高分才是学的好
模型在测试集上的预测误差(Error),可以分为三种来源
-
偏差(Bias):高偏差的模型表现为:
对于一个预测样本,不仅预测不准,而且如果模型再训练一遍,还是同样地预测不准
好比我们期待一个同学期末考90分,但是他只考了50分,如果再给他一次机会,重学一遍再参加考试,他还是考了50分,距离90分一直很远
-
方差(Variance):高方差的模型表现为:
对于一个预测样本,如果一个模型再训练一遍,会取得不一样的预测结果
好比一个同学参加期末考试考了80分,再学一遍再考一次考了40分,再学一遍再考一次考了100分,每次都不一样
-
不可减少误差(Irreducible Error):
就算模型没有任何偏差和方差,也不可能做到百分之百的准确预测,因为样本数据本身是存在不确定性的,总会有数据是你模型没见过的
比方说我们为了期末考试已经做了充分的准备了,但是如果出题老师出了一道超纲题目,我们还是做不对
这部分误差不是模型所能解决的,所以不是机器学习钻研的领域
对于预测误差这两种来源的解读,其实还是停留在理论上的,因为模型使用新的训练数据再训练一遍并不是总可行的
1.2 欠拟合与过拟合
我们评价模型的一个常用指标就是模型的复杂度,可以简单地理解为数据从进入模型,到输出结果,当中进行的运算是多还是少
欠拟合是一个过于简单的模型常常表现出来的问题,指的是模型在训练集上压根就没学到东西
- 欠拟合的模型通常在训练集上表现差,在测试集上表现也差
- 欠拟合的模型通常有高偏差,低方差
- 就好比一个不好好学习的学生,平时学习就差,到了考试的时候考的也差,考的差就是高偏差的表现,而且不论他考多少次,成绩都是稳定地低,只要能稳定,就是低方差的表现
过拟合是一个过于复杂的模型常常表现出来的问题,指的是模型在训练集上学到的东西太死板了
- 过拟合的模型通常在训练集上表现好,但是在测试集上表现差
- 过拟合的模型通常有低偏差,高方差
- 就好比一个学生在平时学习的时候学的死记硬背,到了考试的时候如果遇到考原话的知识点就考高分,如果题目出的灵活一点就考低分,忽高忽低就是高方差的表现,但是总的来说水平在平均水平,在平均水平就是低偏差的表现
下图简单展示了模型复杂度与欠拟合和过拟合的关系
从图中我们可以看到,模型越简单,就越可能欠拟合,模型越复杂,就越可能过拟合
- 模型总的误差与模型复杂度之间存在一个抛物线的关系
- 所以,存在一个最优的模型复杂度,在此复杂度下,模型的总误差是最小的
- 因此,我们调整模型的任务就是找到这个最优的模型复杂度
\
2. 特征选择
特征选择是监督学习的一个重要任务,当我们的数据集中有很多的特征时,我们通常并不想把所有的特征都拿来预测标签,我们只选择一部分特征来预测标签
这么做的原因包括:
- 有些特征和标签是无关的,用它们来预测标签是没有效果的
- 有些多个特征中包含的信息是重复的,表现为多个特征之间高度相关,那么这多个特征中其实只要保留一个特征就够了
- 太多的特征容易导致模型复杂性增加,从而导致过拟合
这一节我们主要来介绍一些特征选择的思路
2.1 特征子集选择
特征子集选择,其实就是不同的特征组合,一个一个地试
例如我们想在特征A,B,C三个特征中,选出最合适的组合,我们可以在以下选项中,一个一个地试
- 只有A
- 只有B
- 只有C
- A,B
- A,C
- B,C
- A,B,C
2.1.1 特征组合的评价方式
要想在所有组合中选出最好的,我们需要对每种组合进行评分,有以下两种思路:
- 使用该组合的特征,与标签进行建模,先使用训练集的数据训练模型,再使用测试集的数据测试效果,如果测试集上的预测准确度越高,说明该组合越好
- 模型评估指标,不同的模型有不同的评价指标,这些指标通常只需要训练集的数据就可以计算出来,不需要测试集,比方说线性回归的评估指标有:
- AIC (Akaike Information Criterion):综合评估模型在训练集上的表现与模型的复杂程度,越低模型越好
- BIC (Bayesian Information Criterion):综合评估模型在训练集上的表现与模型的复杂程度,越低模型越好
2.1.2 特征的子集选择的方式
特征子集选择这种方式的缺点是很明显的,就是它的计算复杂度是成指数上升的,如果我们有10个特征,我们就要尝试2^10-1=1023种组合
因此我们需要一种节约成本的方式,这种方式叫做贪婪搜索(Greedy Searching)
- 贪婪搜索的优点就是节约成本
- 贪婪搜索的缺点就是有可能找不到全局最优的
贪婪搜索的方式也可以分为三种
- 前向选择
- 从空模型出发,一个特征一个特征地加入模型,直到模型表现没有提高为止
- 例如我们有A,B,C,D四个特征
- 首先评估单个特征,我们在四个选项中:只有A,只有B,只有C,只有D,比方说我们发现只有A是最好的,那我们就选A
- 选A之后,我们再在三个选项中:AB,AC,AD,选最好的,比方说我们发现AC是三个中最好的,且AC比只有A要好,那么我们就选AC
- 选AC之后,我们再在两个选项中:ACB,ACD中,选最好的,比方说我们发现ACB是两个中最好的,但是ACB并没有比AC好,那我们就还是得选AC
- 这样一来选择就停止了,最终选择的特征组合是A
- 后向选择
- 从全模型出发,一个特征一个特征地从模型中删去,直到模型表现没有提高为止
- 例如我们有A,B,C,D四个特征
- 首先我们把ABCD四个特征全放入模型,接着我们考虑在此基础上,考虑去掉一个特征的选项:去掉A(留下BCD),去掉B(留下ACD),去掉C(留下ABD),去掉D(留下ABC),比方说我们发现去掉A(留下BCD)之后表现最好,并且比起初的ABCD要好,那么我们的模型就变成了BCD
- 接着从BCD出发,我们接着考虑去掉一个特征的选项:去掉B(留下CD),去掉C(留下BD),去掉D(留下BC),比方说我们发现去掉D(留下BC)之后表现最好,并且比起初的BCD要好,那么我们的模型就变成了BC
- 接着从BC出发,我们接着考虑去掉一个特征的选项:去掉B(留下C),去掉C(留下B),比方说我们发现去掉C(留下B)之后表现最好,但是却不如BC好,那么我们还是选择BC
- 这样一来选择就停止了,最终选择的特征组合是BC
\
- 双向选择
- 从任意模型出发,同时考虑加一个特征和删一个特征,直到模型表现没有提高为止
- 例如我们有A,B,C,D四个特征
- 我们从AB出发,同时考虑加一个和删一个,那就是在以下选项中选择:ABC,ABD,A,B,比方说,这四个选项中ABD表现最好,且相对于初始的AB有提高,那我们就选择ABD
- 接着从ABD出发,同时考虑加一个和删一个,那就是在以下选项中选择:ABCD,AB,AD,BD,比方说这四个选项中AD表现最好,但是却没有初始的ABD好,那我们就还是选择ABD
- 这样一来选择就停止了,最终选择的特征组合是ABD
以下我们来看一下特征子集选择的代码实现
https://bigquant.com/codeshare/27082721-ab6e-47a7-8374-e538e2e21da9
2.2 特征相关性检验
如果多个特征间有高度相关的关系,那么我们只保留一个或几个做代表就可以了
描述两个特征之间的线性相关强度的统计量叫做相关系数
- 特征A与特征B之间的相关系数,越接近1,则表示特征A与特征B之间有越强的正线性相关性
- 特征A与特征B之间的相关系数,越接近-1,则表示特征A与特征B之间有越强的负线性相关性
- 特征A与特征B之间的相关系数,越接近0,则表示特征A与特征B之间的相关性越弱
这样的话如果我有N个特征,两两之间求一个相关系数,这样我就有了N*N个相关系数
- 当然这N*N个相关系数中有一半都是重复的
- 因为特征A与特征B的相关系数,与特征B与特征A的相关系数,其实是一个
利用可视化的思想,我们可以把这N*N个相关系数列成方矩阵,再填上颜色,这就是相关系数矩阵热力图
- 颜色越红,相关系数越接近1,正线性相关性越强
- 颜色越蓝,相关系数越接近-1,负线性相关性越强
- 颜色越白,相关系数越接近0,线性相关性越弱
以下是一个样例的相关系数热力图
- 我们一共有15个备选的特征
- 这当中我们发现,return_5,return_10,return_20,rank_return_0,rank_return_5,rank_return_10,这六个因子中有着较强的相关性
- 因此,在这六个特征中,我们保留一个或者两个就可以了
https://bigquant.com/codeshare/82ba82ec-10b3-41b3-95ce-e0c85423498c
\
2.3 正则化
许多模型是有自动特征选择的功能的
- 这样的模型在训练的过程中,把不重要的特征之前的参数训练为0,或接近为0
- 特征乘以一个参数0之后,特征就从模型里消失了,也就从模型中被去除了
线性回归本身是不支持这样的功能的,但是我们可以把线性回归模型稍微修改一下,加入一个正则化项,这样线性回归就有这样的功能了
这样的正则化项有三种
- L2正则化:形成的模型叫做岭回归
- L1正则化:形成的模型叫做LASSO
- L2正则化与L1正则化综合考虑:形成的模型叫做弹性网络
3. 岭回归、LASSO、弹性网络
之前我们介绍过,普通的线性回归模型表达式为:
我们想要估计一系列的beta,估计的原则是最小化MSE(Mean Squared Error)
3.1 岭回归
岭回归的模型表达式和线性回归一样,也是:
但是优化目标变了:
在这个优化目标中:
- 前面一部分的优化目标是和普通线性回归一样的,都是要最小化训练集中的训练误差
- 后面一部分的优化目标,是要最小化beta的值
- 所以总的优化目标可以理解为,在最小化训练误差的基础上,beta的值也不能太大
- 所以,在训练的过程中,如果不重要的特征,模型就会把它对应的beta训练为接近于0,这样特征相当于就从模型中被删去了
在优化目标的后面一部分中,有一个lambda,这个东西叫做超参数,它的作用是惩罚参数
- 超参数的值并不是模型训练出来的,而是我们人为自己设定的
- 如果我们设置一个大一些的lambda,模型在训练的时候就会对beta惩罚的狠一些,表现为很多beta被估计为0
- 如果我们设置一个小一些的lambda,模型在训练的时候就会对beta惩罚的轻一些,表现为很少beta被估计为0
那么选择多大的lambda是合适的,这个就可以在一系列lambda的备选值中选择最优的,这就是调参的过程
- 调参的过程中通常会使用到验证集,而不是最终的测试集
- 评估lambda的好坏,使用的指标通常是验证集上的准确率
以下是一个岭回归超参数调优的样板代码
https://bigquant.com/codeshare/b68073dc-400c-44c8-a070-14ef3cae0ca8
3.2 LASSO(索套回归)
LASSO的模型表达式和线性回归一样,也是:
优化目标为:
这个优化和岭回归的很类似,只不过岭回归是L2正则化,LASSO是L1正则化
- L1正则化可以真正地把beta训练为0
- 而L2正则化只能做到让beta接近于0
以下是一个LASSO超参数调优的样板代码
https://bigquant.com/codeshare/b4e2c384-2910-4070-9ae8-4b2268bf2d29
3.3 弹性网络
弹性网络其实就是将岭回归和LASSO的思想结合一下
弹性网络的模型表达式为:
优化目标为:
我们可以看到,在这个优化目标中,既有L1正则项,也有L2正则项
- 但是L1正则项和L2正则项之前的超参数的值是不一样的
- 所以我们需要优化两个参数,运算量就成倍提升了
- 比较方便的是,sklearn这个包中把这两个参数综合为一个参数了,所以真正调参的时候调一个就可以了
https://bigquant.com/codeshare/2f11a747-d046-490f-936a-ea8b3d70a475
注意:我把后面的回测模块封装成Python文件了 ,纯粹是为了减少代码复用,其实回测模块和平台默认的可视化线性策略里的是一样的
\