特征离散化

为什么需要离散化

对于很多实际问题(如广告点击率预测),往往特征非常多,这时候时间约束通常不允许我们使用很复杂的非线性分类器。这也是为什么算法发展这么多年,广告点击率预测最常用的方法还是LR模型。

在实际应用中,很少直接将连续值作为逻辑回归模型的特征输入,而是将连续特征离散化为一系列0、1特征交给逻辑回归模型,除了一些加快计算等好处,还可以引入非线性特性,也可以很方便的做交叉特征。离散特征的增加和减少都很容易,易于模型的快速迭代。此外,噪声很大的环境中,离散化可以降低特征中包含的噪声,提升特征的表达能力。

CTR比赛中,深度学习提取特征然后进行LR,和人工提取特征相比,人工提取更能注重业务逻辑,也可以更好的进行交叉特征的构造等。

离散化特征的优点

1、离散特征的增加和减少都很容易,易于模型的快速迭代;

2、稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展;

3、离散化后的特征对异常数据有很强的鲁棒性:比如一个特征是年龄>30是1,否则0。如果特征没有离散化,一个异常数据“年龄300岁”会给模型造成很大的干扰;

4、对于线性模型,例如逻辑斯蒂回归,表达能力受限,单变量离散化为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合;

5、离散化后可以进行特征交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力;

6、特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。当然处于区间相邻处的样本会刚好相反,所以怎么划分区间是门学问;

7、特征离散化以后,起到了简化了逻辑回归模型的作用,降低了模型过拟合的风险。

8、离散化,维度就会大大降低,比如:低速(60-75),中速(70-75),高速(80-90),这样维度就缩减了很多。对于连续数据来说,每个速度都是一个维度的特征。

采用离散化特征还是连续特征

对于海量离散特征可以采用较为简单的模型,例如LR,能够较快的得到结果,节约时间成本,而如果采用连续的特征,采用复杂的模型,例如集成模型XGBoost等,会消耗很多时间,在实际应用中,时间成本往往非常重要。

既可以离散化用线性模型,也可以用连续特征加深度学习。通常来说,离散化特征配合简单模型较为容易,而且可以多人一起并行做,有成功经验;后者目前在竞赛中取得的成绩较为理想,而且对时间成本不做要求,能走多远还须拭目以待。

将类别数据离散化为数值型数据

以性别为例,性别特征具有两个选项:男或女,模型搞不懂何为“男 、女”,但清楚 “1、0”。直观的做法,将“男、女”对“1、0”进行映射,但实际中sex只是一个标称属性,不应具有“数学”意义,故比较合理的做法是将sex特征拆成两个特征,也就是说将男表示为(1, 0),女表示为(0,1)。这也就是我们常用的onehot编码的主要思想。核心就是将m个取值的类别属性转化为m个特征,如果具有某个属性,则代表该属性的特征表示为1,其他为0。

用python具体实现的话,可以借助sklearn包中的LabelEncoder将类别数据标签化,如”女”->0,“男”->1, 用OneHotEncoder负责将标签属性离散化,如将一个属性拆成俩特征,0->(0,1), 1->(1,0)

 

LR需要离散化特征

LR需要这么做是因为,模型本身是线性参数模型,参数模型对特征都有个分布的假设,而特征有些分布是奇形怪状,这也是有时候为什么你要在特征上加个log/sqrt。线性换转线性是一方面,更多原因是因为参数模型,想想为什么树模型可以不用离散化是因为这个模型是非参的。此外,LR用离散特征的好处就是LR的特征是并行的,每个特征是并行同权的,如果有异常值的情况下,如果这个异常值没见过,那在LR里因为没有这个值的权重,最后对score的贡献为0,最多效果不够好,但是不会错得太离谱。另外如果你debug,很容易查出来是在哪个段上的权重有问题,比较好定位和解决。

如何进行特征的离散化

1. 离散化技术分类

连续属性的离散化方法也可以被称为分箱法,即将一组连续的值根据一定的规则分别放到其术语的集合中。离散化技术可以根据如何对数据进行离散化加以分类,可以根据是否使用类信息或根据进行方向(即自顶向下或自底向上)分类。如果离散化过程使用类信息,则称它为监督离散化(superviseddiscretization);否则是非监督的(unsupervised)。

如果首先找出一点或几个点(称作分裂点或割点)来划分整个属性区间,然后在结果区间上递归地重复这一过程,则称它为自顶向下离散化或分裂。自底向上离散化或合并正好相反,首先将所有的连续值看作可能的分裂点,通过合并相邻域的值形成区间,然后递归地应用这一过程于结果区间。

3. 齐次性的卡方检验

4. 自上而下的卡方分裂算法

该分裂算法是把整个属性的取值区间当做一个离散的属性值,然后对该区间进行划分,一般是一分为二,即把一个区间分为两个相邻的区间,每个区间对应一个离散的属性值,该划分可以一直进行下去,直到满足某种停止条件,其关键是划分点的选取。分裂步骤:依次计算每个插入点的卡方值,当卡方值达到最大时,将该点作为分裂点,属性值域被分为两块。然后再计算卡方值,找到最大值将属性值域分成三块

单个原始特征(或称为变量)通常属于以下几类之一:

对于连续特征,除了归一化(去中心,方差归一),不用做太多特殊处理,可以直接把连续特征扔到模型里使用

对于无序特征,可以使用One-hot(也叫One-of-k)的方法把每个无序特征转化为一个数值向量。这种方法在NLP里用的很多,就是所谓的词向量模型。变换后的向量长度对于词典长度,每个词对应于向量中的一个元素。

对于有序特征,有些特征虽然也像无序特征那样只取限定的几个值,但是这些值之间有顺序的含义。例如一个人的状态status有三种取值:bad, normal, good,显然bad < normal < good。

当然,对有序特征最简单的处理方式是忽略其中的顺序关系,把它看成无序的,这样我们就可以使用处理无序特征的方式来处理它。在实际问题中,这种处理方式其实用的很多。

当然有些问题里有序可能会很重要,这时候就不应该把其中的顺序关系丢掉。最常用的转化方式是对特征做离散化,也就是把原来的值分段,转化成一个取值为0或1的向量。原始值落在某个段里,向量中此段对应的元素就为1,否则为0。离散化的目标是特征与转化后向量里的每个元素都保持比较好的线性关系。

离散化方法的关键是怎么确定分段中的离散点,下面是常用的选取离散点的方法:

等距离离散:顾名思义,就是离散点选取等距点。

等样本点离散:选取的离散点保证落在每段里的样本点数量大致相同

画图观察趋势:

函数变换

函数变换直接把原来的特征通过非线性函数做变换,然后把原来的特征,以及变换后的特征一起加入模型进行训练。

笛卡尔乘积

我们可以使用笛卡尔乘积的方式来组合2个或更多个特征。比如有两个类别特征color和light,它们分别可以取值为red,green,blue和on, off。这两个特征各自可以离散化为3维和2维的向量。对它们做笛卡尔乘积转化,就可以组合出长度为6的特征,它们分别对应着原始值对(red, on),(red, off),(green, on),(green, off),(blue, on),(blue, off)

决策树模型

它天生就可以对连续特征分段,所以把它用于离散化连续特征合情合理。我称这种方法为决策树离散化方法。例如Gmail在对信件做重要性排序时就使用了决策树离散化方法。

决策树离散化方法通常也是每次离散化一个连续特征,做法如下:

单独用此特征和目标值训练一个决策树模型,然后把训练获得的模型内的特征分割点作为离散化的离散点。这种方法当然也可以同时离散化多个连续特征,但是操作起来就更复杂了,实际用的不多。

1、首先对这个连续变量排序。比如说年龄,把所有样本中年龄的数值从小到大排序。在数据没有重复的假设下,如果有n个样本,那么排序后的数据之间应该有n-1个间隔。

2、决策树会对这n-1个间隔进行逐一尝试(分叉),每个不同的分叉,会带来不同的基尼指数,我们最终选基尼指数最小的那个分叉作为最优分叉。理论上是这样进行的,但是实际情况是为了一些计算优化,可能会进行一些随机搜索,而不一定是遍历。

3、以此反复,这样一个连续变量就不停地被离散化,直到模型达到停止的条件。

核方法

核方法经常作为线性模型的一种推广出现。

如果我们把上面模型里的{K(x,xi)}ni=1{K(x,xi)}i=1n看成特征,而θθ看成模型参数的话,上面的模型仍旧是个线性模型。所以可以认为核方法只是特征函数变换的一种方式。

猜你喜欢

转载自blog.csdn.net/FigthingForADream/article/details/81432887