《Python机器学习基础教程 》笔记-第4章

github地址:点我

分类变量

如果特征不是连续值,而是一些分类特征,来自一系列固定的可能取值,那么直接用于类似Logistic回归分类模型是没有意义的。

One-Hot编码(虚拟变量)

将1个特征的多种取值,改为多个特征的0/1取值,其中有一个特征为1,其他为0.

第1个特征取值有2个(0、1),所以在one-hot里占用2列;第2个特征取值有3个(0、1、2),所以在one-hot里占用3列;第3个特征取值有4个(0、1、2、3),所以one-hot占用4列;

对于输入特征[1,4,2],因为4在fit时没有出现过,所以在one-hot编码中被ignore为3个0.

数字可以编码分类变量

书中提到pandas库做one-hot的时候,可以指定对哪些特征对one-hot,而对其他连续特征可以不做处理。

我以sklearn为例,假设3维特征只有前2个特征是离散分类需要做one-hot,而第3个特征不需要one-hot。

通过categorical_features=[0,1]指定了只有前2个特征需要离散化。

从结果可见,0,1是第1列特征的one-hot,0,0,0是第2列特征的one-hot(因为4在fit时不存在),第3列特征没有变动。

字符串编码为整形

书中没有提到sklearn如何把字符串类型的特征转换为整形,我调研了一下作为补充。

在最新版sklearn 0.2+中,需要用ColumnTransformer来作为统一的特征处理方法。

下面,我对特征的第1列做执行OrdinalEncoder编码字符串为整形,然后再对第1列做Onehot编码:

特征的pipeline处理非常方便。

分箱、离散化、线性模型与树

对于只有1个连续特征的线性模型,它的表现就是y=w*x的线,效果不好。

这时候可以考虑将特征取值划分范围,这就是分箱,每个箱子的数值区间不同。

这样就把1个连续特征变成了离线特征,也就是在哪个区间里,可以继续通过one-hot编码成多个0/1特征。

分箱对线性模型有提升效果,对树模型效果不会很好可能还会下降。

交互特征与多项式特征

意思就是把原始特征之间进行组合和扩充,对线性模型有提升效果,比如:添加特征的平方或立方,或者把两两特征相乘。

添加交互/多项式特征之后的线性模型,与没有交互特征的树模型/复杂模型的性能就比较相近了。

单变量非线性变换

对于简单模型(线性、朴素贝叶斯)来说,如果数据集的数据分布存在大量的小值以及个别非常大的值,会导致线性模型很难处理。

这种情况出现在一些计数性质的特征上,比如点赞次数。

此时对该特征应用log(x+1)或者exp来调节特征值得比例,可以改进线性模、SVM、神经网络的效果。

对线性模型提升最明显,对树模型意义不大,对SVM/KNN/神经网络有可能受益。

自动化特征选择

上面讲的是增加特征,现在是通过分析数据来减少特征,得到一个泛化更好,更简单的模型,也就是特征选择。

一共有3种方法:

  • 单变量统计
  • 基于模型的选择
  • 迭代选择

单变量统计

每次考虑一个特征,观察特征与目标值之间是否存在统计显著性,但是没法综合考虑多个特征。

算法可以指定保留一定数量的重要特征。

可见,删了一半特征,对模型精度没有产生影响。

基于模型的特征选择

线性模型、决策树模型在训练的过程中自然的完成了对特征重要程度的学习。

所以可以基于这些模型进行特征选择,再将选择后的特征作为另外一个模型的输入。

模型综合度量了所有特征的重要性,所以比单变量统计强大的多。

迭代特征选择

RFE利用模型进行多轮特征选择,每轮筛掉1个最不重要的特征。

下面用随机森林做特征选择,选择出来的特征用线性LR做训练,发现线性模型精度很好。

如果不确定选择哪些特征作为算法输入,那么可以尝试自动特征选择。 实际情况中,特征选择不太可能大幅提升精度。

利用专家知识

通常来说,领域专家可以帮助找出有用的特征,其信息量比数据原始表示要大得多。

有一份单维度的数据,特征是时间,目标是租车量,希望可以预估未来某个时间的租车量。

不作任何特征预处理,直接交给随机森林回归:

训练集精度还不错,但是测试集完全无效。

这是因为树回归模型是无法外推的,测试集的时间戳超出了训练集的范围,所以模型只能预测给出训练集中出现过最近的数据点的目标值。

这时候,我们还是需要专家知识的帮助,租车量与2个因素有关:

  • 一天内的第几个小时
  • 一周内的星期几

继续应用随机森林,因为特征取值范围有限,所以现在模型表现很不错。

模型学习到的是周几以及几点与目标之间的关系,用线性模型试试:

精度又很差,为什么呢?

因为线性模型把特征作为连续值去线性理解,它可能认为周几越大出租量越大,实际情况并不是这种线性的。

把这俩特征作为离散值理解更有意义,所以需要one-hot编码。

正常了一些,但模型还是太简单了。

下面添加一些多项式特征,令线性模型更复杂:

线性模型基本已经接近随机森林。

小结

  • one-hot编码分类特征
  • 线性模型通过分箱,添加多项式、交互项来添加新特征,可以大大受益
  • 对于非线性模型(比如随机森林、SVM),无需扩展特征就可以得到不错的效果
  • 实践中,所使用的特征是机器学习表现良好的最重要因素

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~