第2章 特征工程

在机器学习应用中,特征工程扮演着重要的角色,可以说特征工程是机器学习应用的基础。在机器学习界流传着这样一句话:“数据和特征决定了机器学习算法的上限,而模型和算法只是不断逼近这个上限而已。”在机器学习应用中,特征工程介于“数据”和“模型”之间,特征工程是使用数据的专业领域知识创建能够使机器学习算法工作的特征的过程。美国计算机科学家Peter Norvig有两句经典名言:“基于大量数据的简单模型胜于基于少量数据的复杂模型。”以及“更多的数据胜于聪明的算法,而好的数据胜于多的数据。”因此,特征工程的前提便是收集足够多的数据,其次则是从大量数据中提取关键信息并表示为模型所需要的形式。合适的特征可以让模型预测更加容易,机器学习应用更有可能成功。

纵观Kaggle、KDD等国内外大大小小的比赛以及工业界的应用,它们其实并没有用到很复杂的模型和算法,大多数成功都是在特征工程这个环节做了出色的工作。吴恩达曾说过:“特征工程不仅操作困难、耗时,而且需要专业领域知识。应用机器学习基本上就是特征工程。”相信大多数人都会同意。在机器学习应用中,我们大多数时间都在进行特征工程和数据清洗,而算法和模型的优化仅仅占了一小部分。遗憾的是,目前大多数书籍中并没有提到特征工程,对于特征工程的介绍更多则是特征选择的方法。这是因为,好的特征工程不仅需要我们对模型和算法有深入的理解,更需要较强的专业领域知识。特征工程不仅跟模型相关,而且跟实际问题是强相关的。针对不同问题,特征工程所用的方法可能相差很大,很难总结出一套比较通用的方法。尽管如此,但仍然有很多特征工程的技巧在不同问题中都适用。在本章,我们将介绍特征工程中通用的方法和技巧,以及常用特征选择方法。

2.1 特征提取

从数学的角度讲,特征工程就是将原始数据空间变换到新的特征空间,或者说是换一种数据的表达方式,在新的特征空间中,模型能够更好地学习数据中的规律。因此,特征抽取就是对原始数据进行变换的过程。大多数模型和算法都要求输入是维度相同的实向量,因此特征工程首先需要将原始数据转化为实向量。原始数据有很多类型,比如数值类型、离散类型,还有文本、图像以及视频等。将原始数据转化为实向量后,对应的特征空间并不一定是最佳的特征空间。为了让模型更好地学习到数据中隐藏的规律,我们可能还需要对特征做进一步的变换。将原始数据空间变换为模型输入向量空间的过程便是特征工程所要做的事情。事实上,如果特征工程足够复杂,即使是最简单的模型,也能表现出非常好的效果。然而,复杂的模型在一定程度上减少了特征工程需要做的工作。因此,特征工程和模型二者此消彼长。例如,对于线性模型,我们需要将类别变量进行独热编码等处理,但对于复杂一些的模型如树模型,可以直接处理类别变量。对于更高级的深度神经网络,模型可以自动进行特征表示。

那么特征工程具体怎么操作呢?首先,我们需要知道手上有哪些可以使用的数据,可以获取哪些数据以及这些数据的获取成本。我们拥有的数据越多、越有价值,机器学习应用成功的可能性往往就越高。但有些数据的获取成本非常昂贵,而且从数据量和覆盖面两方面来讲,数据都很有限,所以我们面临的挑战更多在于从现有数据中挖掘出对机器学习模型有用的特征。特征的挖掘一般跟专业领域知识强相关,特征工程可以说是业务逻辑的一种数据层面的表示。所以特征工程的第一步是理解业务数据和业务逻辑。特征提取也可以看作用特征描述业务逻辑的过程,特征提取的目标是对业务进行精确、全面的描述。同时,生产的特征最终用于模型预测,因此我们需要理解模型和算法,清楚模型需要什么样的输入才能有较精确的预测结果。此外,为了进一步提升模型效果,我们还需要对特征进行特殊的数学变换。

根据机器学习算法所要学习的目标和业务逻辑,我们需要考虑数据中有哪些可能相关的要素。例如在美团酒店搜索排序中,酒店的销量、价格、用户的消费水平等是强相关的因素,用户的年龄、位置可能是弱相关的因素,用户的ID是完全无关的因素。在确定了哪些因素可能与预测目标相关后,我们需要将此信息表示为数值类型,即为特征抽取的过程。例如在美团酒店搜索排序中,描述酒店的特征有酒店的位置、上线时间、星级等,描述用户的特征有用户的注册时间、VIP等级、地理位置等,这些特征都是静态的,可以从数据库中抽取。除此之外,用户在App上的浏览、交易等行为记录中包含了大量的信息,特征抽取则主要是从这些信息抽取出相关因素,用数值变量进行表示。常用的统计特征有计数特征,如浏览次数、下单次数等;比率特征,如点击率、转化率等;统计量特征,如价格均值、标准差、分位数、偏度、峰度等。

2.1.1 探索性数据分析

当你手上有一份数据,但对这份数据完全陌生且没有足够的专业背景知识时,你可能感觉无从下手。如果不做任何数据分析和预处理,直接将数据喂给模型,得到的效果一般都不会太好。这是因为喂给模型的数据不具有好的特征。如何发现好的特征呢?当然专业领域知识很重要,但是在没有足够专业领域知识的情况下,通过探索性数据分析往往能够发现效果不错的特征。

在统计学里,探索性数据分析(Exploratory Data Analysis,EDA)是采用各种技术(大部分为可视化技术)在尽量少的先验假设条件下,探索数据内部结构和规律的一种数据分析方法或理念。特别是当我们对数据中的信息没有足够的先验知识,不知道该用什么方法进行分析时,先对数据进行探索性分析,发现数据的模式和特点,就能够灵活地选择和调整合适的模型。EDA由美国著名统计学家约翰•图基(John W. Tukey)在20世纪60年代提出。EDA的目的是尽可能地洞察数据集、发现数据的内部结构、提取重要的特征、检测异常值、检验基本假设、建立初步的模型。EDA的特点是从数据本身出发,不拘泥于传统的统计方法,强调数据可视化。EDA工具有很多,但EDA更多是方法论而不是特定的技术。EDA技术通常可分为两类。一类是可视化技术,如箱形图、直方图、多变量图、链图、帕累托图、散点图、茎叶图、平行坐标、让步比、多维尺度分析、目标投影追踪、主成分分析、多线性主成分分析、降维、非线性降维等;另一类是定量技术,如样本均值、方差、分位数、峰度、偏度等。

2.1.2 数值特征

数值类型的数据具有实际测量意义,例如人的身高、体重、血压等,或者是计数,例如一个网站被浏览多少次、一种产品被购买多少次等(统计学家也称数值类型的数据为定量数据)。数值类型的数据可以分为离散型和连续型。离散型数据表示的量是可数的,其可以是有限个值,也可以是无限个值。例如,100次硬币投掷中正面朝上的个数取值为0到100,但是获得100次正面朝上所需要的投掷次数取值为0到正无穷。连续型数据表示测量得到的量,其取值是不可数的,可以用实数轴上的区间表示,为了便于记录,通常指只保留部分有效数字,例如人的体重的取值可以是70.41千克,或者是70.414 863千克。

机器学习模型可以直接将数值类型的数据格式作为输入,但这并不意味着没有必要进行特征工程。好的特征不仅能表示出数据中隐藏的关键信息,而且还与模型的假设一致。通常情况下,对数值类型的数据进行适当的数值变换能带来不错的效果提升。对于数值特征,我们主要考虑的因素是它的大小和分布。对于那些目标变量为输入特征的光滑函数的模型,如线性回归、逻辑回归等,其对输入特征的大小很敏感。因此,当使用光滑函数建模时,有必要对输入进行归一化。而对于那些基于树的模型,例如随机森林、梯度提升树等,其对输入特征的大小不敏感,输入不需要进行归一化。但是,对于树模型,如果特征取值无限大也会有问题。如果模型对输入特征和目标变量有一些隐式或者显式的假设,则数据的分布对模型很重要。例如,线性回归训练通常使用平方损失函数,其等价于假设预测误差服从高斯分布。因此,如果输出变量分布在不同尺度时,这个假设不再成立。在这种情况下,我们有必要对目标变量进行变换使其满足假设。严格地说,这种方法应该称为“目标”工程,而不是特征工程。除了对特征进行变换以满足模型的假设,我们也可以对特征进行交叉组合。特征交叉提升了模型的表达能力,让线性模型具有非线性模型的性质,而树模型天然有这种性质。下面我们详细介绍8种常见的数值特征的处理方法。

 截断。对于连续型数值特征,有时候太多的精度可能只是噪声。因此,可以在保留重要信息的前提下对特征进行截断,截断后的特征也可以看作是类别特征。另外,至于长尾的数据,可以先进行对数转换,然后进行截断。

 二值化。数值特征的一种常用类型是计数特征,如网站每天的访问量、餐厅的评论数、用户对一首歌的播放次数等。在大数据时代,计数可以非常快地累加。处理计数特征时,首先要考虑的是,保留为原始计数还是转换为二值变量来标识是否存在或者进行分桶操作。

 分桶。在购物网站上,每件商品都会显示用户的评论次数。假设我们的任务是利用逻辑回归模型来预测用户对某件商品的购买概率。商品的评论次数可能是一个有用的特征,因为评论次数跟商品的热度有很强的相关性,那么我们应该直接使用原始的评论次数作为特征还是需要进行预处理?如果商品的评论次数跨越不同的数量级,则它不是一个好的特征,例如对于逻辑回归模型,一个特征对应一个系数,从而模型往往只对比较大的特征值敏感。对于这种情况,通常的解决方法是进行分桶。分桶是将数值变量分到一个桶里并分配一个桶编号,常见的分桶方法有固定宽度的分桶。对于固定宽度的分桶,每个桶的值域是固定,如果每个桶的大小一样,它也称为均匀分桶,例如将人的年龄分为0~9岁、10~19岁等。除此之外,桶的宽度也可以自定义。如果数值跨越不同数量级,可以根据10(或者其他任何适当的常数)的幂来分桶,如0~9、10~99、100~999、1000~9999等,这种方法和对数变换非常相关。另一种分桶方式是分位数分桶,虽然固定宽度的分桶易于实现,但如果数值变量的取值存在很大间隔时,有些桶里没有数据,可以基于数据的分布进行分桶,也即分位数分桶,其对应的桶里面数据一样多。除此之外,也可以使用模型找到最佳分桶,例如利用聚类的方式将特征分为多个类别。分桶操作也可以看作是对数值变量的离散化,因此分桶后也可以将分桶操作当成类别变量进行处理。

 缩放。缩放即将数值变量缩放到一个确定的范围。常见的缩放有:标准化缩放(也称为Z缩放),即将数值变量的均值变为0,方差变为1,对于那些目标变量为输入特征的光滑函数的模型,如线性回归、逻辑回归等,其对输入特征的大小很敏感,对特征进行标准化比较有效;最大最小值缩放及最大绝对值缩放;基于某种范数的归一化,如使用L1范数、L2范数将数值向量的范数变为1;平方根缩放或对数缩放,对数缩放对于处理长尾分且取值为正数的数值变量非常有效,它将大端长尾压缩为短尾,并将小端进行延伸,平方根或者对数变换是幂变换的特例,在统计学中都称为方差稳定的变换,其中Box-Cox变换是简化的幂变换,Box-Cox 转换仅对取值为正数的数值变量起作用;对于有异常点的数据,可以使用更加健壮的缩放,与一般的标准化基于标准差进行缩放不同的是,健壮的缩放使用中位数而不是均值,基于分位数而不是方差。

 缺失值处理。实际问题中经常会遇到特征缺失的情形,但是大多数模型并不能处理特征缺失的情况,缺失特征的处理方式会影响模型效果。对于特征缺失,我们有两类处理方法。第一种是补一个值,例如最简单的方法是补一个均值;对于包含异常值的变量,更加健壮一些的方法则是补一个中位数;除此之外还可以使用模型预测缺失值。另外一种则是直接忽略,即将缺失作为一种信息进行编码喂给模型让其进行学习。现在有一些模型可以直接处理缺失值,例如XGBoost模型可以处理缺失特征。

 特征交叉。特征交叉可以表示数值特征之间的相互作用,例如可以对两个数值变量进行加、减、乘、除等操作,可以通过特征选择方法(如统计检验或者模型的特征重要性)来选择有用的交叉组合。有些特征交叉组合,虽然没有直观的解释,但有可能对于模型效果有很大的提升。除了构造交叉特征外,有些模型可以自动进行特征交叉组合,例如FM和FFM模型等。特征交叉可以在线性模型中引入非线性性质,提升模型的表达能力。

 非线性编码。线性模型往往很难学习到数据中的非线性关系,除了采用特征交叉的方式之外,也可以通过非线性编码来提升线性模型的效果。例如使用多项式核,高斯核等,但选择合适的核函数并不容易。另外一种方法是将随机森林模型的叶节点进行编码喂给线性模型,这样线性模型的特征包含了复杂的非线性信息。还有基因算法以及局部线性嵌入、谱嵌入、t-SNE等。

 行统计量。除了对原始数值变量进行处理之外,直接对行向量进行统计也可以作为一类特征,如统计行向量中空值的个数、0的个数、正值或负值的个数,以及均值、方差、最小值、最大值、偏度、峰度等。

以上内容是常见的数值特征的预处理方法。具体采取哪一种处理方式不仅依赖于业务和数据本身,还依赖于所选取的模型,因此首先要理解数据和业务逻辑以及模型的特点,才能更好地进行特征工程。

2.1.3 类别特征

类别数据表示的量可以是人的性别、婚姻状况、家乡或者他们喜欢的电影类型等。类别数据的取值可以是数值类型(例如“1”代表男性,“0”代表女性),但是数值没有任何数学意义,它们不能进行数学运算。类别数据的另一个名称是定性数据。类别特征不仅可以由原始数据中直接提取,也可以通过将数值特征离散化得到。下面我们介绍几种常见的类别变量的处理方法。

 自然数编码。类别特征,一般首先要转换为数值类型才能喂给模型。最简单的编码方式是自然数编码,即给每一个类别分配一个编号,对类别编号进行洗牌,训练多个模型进行融合可以进一步提升模型效果。

 独热编码。通常,直接将类别特征的自然数编码特征喂给模型,效果可能比较差,尤其是线性模型。这是因为,对于类别特征的自然数编码,取值大小没有物理含义,直接喂给线性模型没有任何意义。我们常用的一种做法是对类别特征进行独热编码,这样每个特征取值对应一维特征,独热编码得到稀疏的特征矩阵。

 分层编码。对于邮政编码或者身份证号等类别特征,可以取不同位数进行分层,然后按层次进行自然数编码,这类编码一般需要专业领域知识。

 散列编码。对于有些取值特别多的类别特征,使用独热编码得到的特征矩阵非常稀疏,因此在进行独热编码之前可以先对类别进行散列编码,这样可以避免特征矩阵过于稀疏。实际应用中我们可以重复多次选取不同的散列函数,利用融合的方式来提升模型效果。散列方法可能会导致特征取值冲突,这种冲突通常会削弱模型的效果。自然数编码和分层编码可以看作散列编码的特例。

 计数编码。计数编码是将类别特征用其对应的计数来代替,这对线性和非线性模型都有效。这种方法对异常值比较敏感,特征取值也可能冲突。

 计数排名编码。它利用计数的排名对类别特征进行编码,其对线性和非线性模型都有效,而且对异常点不敏感,类别特征取值不会冲突。

 目标编码。它基于目标变量对类别特征进行编码。对于基数(类别变量所有可能不同取值的个数)很大的离散特征,例如IP地址、网站域名、城市名、家庭地址、街道、产品编号等,上述预处理方法效果往往不太好。因为对于自然数编码方法,简单模型容易欠拟合,而复杂模型容易过拟合;对于独热编码方法,得到的特征矩阵太稀疏。对于高基数类别变量,一种有效方式则是基于目标变量对类别特征进行编码,即有监督的编码方法,其适用于分类和回归问题。例如对于分类问题,采用交叉验证的方式,即将样本划分为5 份,针对其中每一份数据,计算离散特征每个取值在另外4 份数据中每个类别的比例。为了避免过拟合,也可以采用嵌套的交叉验证划分方法。回归问题同样采用交叉验证的方式计算目标变量均值对类别变量编码。在实际问题中,我们往往利用历史数据来预测未来结果。因此我们一般基于时间信息来划分训练集和验证集,利用相同时间窗口大小的历史数据来对类别特征进行编码。例如,在广告点击率预测问题中,我们计算广告主ID在过去固定一段时间内的点击率,对广告主ID进行目标编码。目标编码方法对于基数较低的离散变量通常很有效,但对于基数特别高的离散变量,可能会有过拟合的风险。因为很多类别特征的取值样本个数太少,不具有统计意义。对于这种情况,我们通常采用贝叶斯方法,即对统计特征进行贝叶斯平滑,如拉普拉斯平滑或者先验概率和后验概率加权平均的方式。

 类别特征之间交叉组合。除了前面提到的数值特征之间的交叉组合外,类别特征之间的交叉组合也是很重要的特征。两个类别特征进行笛卡儿积操作可以产生新的类别特征,这种操作适用于两个类别特征的基数较小的情况。两个类别特征的笛卡儿积取值个数是两个类别特征取值个数的乘积,如果两个类别特征的基数很大时,交叉后的特征基数太大,效果可能并不好。除了两个类别特征的交叉,多个类别特征也可以交叉组合,根据实际需要可以进行二阶及二阶以上的交叉组合,最后通过特征选择方法选取重要的组合方式。除了上面提到的交叉组合外,另一种特征组合方式是基于统计的组合。例如针对城市ID和商品ID两个类别特征,我们可以计算某个城市有多少不同的商品ID以及当前ID出现次数的分布,从而得到新的数值特征,或者计算某个城市出现次数最多的商品ID,从而得到一个新的类别特征。对于多个类别特征也可以进行同样的操作。例如针对年龄、性别、产品ID三个类别特征,可以计算某个年龄段不同性别的人购买过多少产品或者对当前产品ID购买次数的分布等。在实际应用中,类别特征之间的组合方式千变万化,这类特征一般从业务逻辑的角度出发进行构造。相比类别特征之间的笛卡儿积操作,基于分组统计的特征组合方式计算更加复杂,而且一般强依赖专业领域知识,因此需要对业务逻辑有较好的理解。

 类别特征和数值特征之间交叉组合。除了数值特征之间的组合以及类别特征之间的组合之外,类别特征和数值特征之间也可以进行组合。这类特征通常是在类别特征某个类别中计算数值特征的一些统计量。例如针对用户ID,统计过去一段时间内在网站上的浏览次数、购买次数,以及购买价格的统计量,如均值、中位数、标准差、最大值和最小值等;针对产品,统计用户对产品的评分、评价次数、购买次数、浏览次数等。再比如,统计产品在某个区域的销量、产品的价格,或者当前产品的价格跟产品所在区域内的平均价格的差价等。可以看出,这类特征也强依赖专业领域知识。上面的这种组合方式也可以看作是利用数值特征对类别特征进行编码,与前面提到的基于目标变量对类别变量进行编码的方法不同的是,这里不需要划分训练集进行计算。

数值特征和类别特征是机器学习应用中最常见的两类特征。上面我们提到了关于这两类特征的一些常用的特征预处理技巧,基于这些技巧可以构造大量特征。但我们无法构造所有可能的特征表达形式,一方面要考虑模型的使用成本,另一方面也要考虑特征的构造成本。当然,我们可以通过特征选择选取重要的特征,但特征选择成本也很高。因此,在实际应用中我们选择性地构造特征。对于不同类别的特征采取哪一种或者哪几种方法,则依赖于我们对业务和数据本身的理解以及对模型的理解。通过对数据内部结构和规律的探索性分析,可以找到跟目标变量相关的信息,进而根据模型需要的输入形式利用预处理技术对这些信息进行编码,即构造特征。

2.1.4 时间特征

在实际应用中,时间往往是一个非常重要的因素,例如用户在购物网站上的浏览、购买、收藏的时间,产品在购物网站上的上线时间,顾客在银行的存款和借款时间、还款时间等。时间变量通常以日期(如2017/05/07 12:36:49)、时间戳(如1494391009)等形式表示。时间变量可以直接作为类别变量处理,类别特征的处理方式对于时间特征同样适用。但时间变量还包含其他更加丰富的信息。时间变量常用的表达方式有年、月、日、时、分、秒、星期几,以及一年过了多少天、一天过了多少分钟、季度、是否闰年、是否季度初、是否季度末、是否月初、是否月末、是否周末,还有是否营业时间、是否节假日等。除了对单个时间变量的预处理之外,根据具体业务对两个时间变量之间进行组合也能提取重要的特征。例如可以计算产品上线到现在经过了多长时间,顾客上次借款距离现在的时间间隔,两个时间间隔之间是否包含节假日或其他特殊日期等。

除了上面提到的基于时间本身的特征之外,时间变量更重要的是时间序列相关的特征。时间序列不仅包含一维时间变量,还有一维其他变量,如股票价格、天气温度、降雨量、订单量等。时间序列分析的主要目的是基于历史数据来预测未来信息。对于时间序列,我们关心的是长期的变动趋势、周期性的变动(如季节性变动)以及不规则的变动。对于时间序列信息,当前时间点之前的信息通常很重要,例如滞后特征(也称为lag特征)使用非常广泛。滞后特征是时间序列预测问题转化为监督学习问题的一种经典方法。若我们的问题是利用历史数据预测未来,则对于t时刻,可以将t-1、t-2和t-3时刻的值作为特征使用。若我们的问题可以考虑未来信息,则t+1、t+2和t+3时刻的值也可以作为特征使用。另一种有效方式是滑动窗口统计特征,例如计算前n个值的均值(回归问题),或者前n个值中每个类别的分布(分类问题)。时间窗口的选取可以有多种方式,上面提到的滞后特征是滑动窗口统计的一种特例,对应时间窗口宽度是1。另一种常用的窗口设置包含所有历史数据,称为扩展窗口统计。

2.1.5 空间特征

基于空间位置变量也是一类非常重要的信息,例如经纬度。对于经纬度,除了将其作为数值变量使用之外,还有其他更加有效的使用方式。例如可以对经纬度做散列,从而对空间区域进行分块,得到一个类别特征,也可以通过坐标拾取系统获得当前位置的行政区ID、街道ID、城市ID等类别特征,进而利用类别特征的处理方式进行特征预处理。还可以计算两个位置之间的距离,如用户到超市或者电影院、餐厅的距离。距离的计算方式也有很多种,例如可以计算欧氏距离、球面距离以及曼哈顿距离,也可以是真实的街道距离。

上面提到的时间变量和空间变量只是两种比较典型的变量,通过对这两种变量进行预处理进而转换为多个数值变量和类别变量。实际应用中还有很多类似的变量,从单个变量出发就可以构造很多特征,这类特征的构造主要依赖对数据本身的理解。

2.1.6 文本特征

自然语言要处理的对象是文本信息。对于文本特征,类别特征的处理方法同样适用,基于深度学习的自动特征工程效果变得越来越好。但是好的特征仍然具有竞争力。文本特征往往产生特别稀疏的特征矩阵。我们可以从以下几个方面对文本特征进行预处理:将字符转化为小写、分词、去除无用字符、提取词根、拼写纠错、词干提取、标点符号编码、文档特征、实体插入和提取、Word2Vec、文本相似性、去除停止词、去除稀有词、TF-IDF、LDA、LSA等。

 语料构建。构建一个由文档或短语组成的矩阵。矩阵的每一行为文档,可以理解为对产品的描述,每一列为单词。通常,文档的个数与样本个数一致。

 文本清洗。如果数据通过网页抓取,首先剔除文本中的HTML标记;停止词只用于语句的构建,但不包含任何真实的信息,因此需要剔除;为了避免文本中的大小写差异,整个文本通常需要转换为小写形式;统一编码;去除标点符号;去除数字;去除空格;还原为词根。但是在某些情况下,文本不一定需要进行清洗,这取决于具体的应用场景。例如考虑某编辑员对某物品的描述,如果我们关心的对象是物品,则需要去除噪声,保留关键信息,但如果我们关心的对象是编辑员,则噪声信息一定程度上反映了此编辑员的水平。

 分词。

■ 词性标注。词语通常有三类重要的词性:名词、动词和形容词。名词特指人、动物、概念或事物,动词表达动作,形容词描述了名词的属性。词性标注的目标是为文本中的每个词标注一个合适的词性,词性标注可以帮助我们了解语言的内在结构。

■ 词形还原和词干提取。词形还原即把任何形式的语言词汇还原为一般形式(能表达完整语义)。词干提取是抽取词的词干和词根形式(不一定能够表达完整语义)。两者都能够有效归并词形。

■ 文本统计特征。文本统计特征是最简单的文本特征,它不需要考虑词序信息,包括计算文本的长度、单词个数、数字个数、字母个数、大小写单词个数、大小写字母个数、标点符号个数、特殊字符个数等,数字占比、字母占比、特殊字符占比等,以及名词个数、动词个数等。

■ N-Gram模型。在自然语言处理中,N-Gram模型将文本转换为连续序列,序列的每一项包含n个元素(可以是单词或者字母等元素),例如“the dog smelled like a skunk”,得到3-Gram(the dog smelled,dog smelled like,smelled like a,like a skunk)。这种想法是为了将一个或者两个甚至多个单词同时出现的信息喂给模型。为了更好地保留词序信息,构建更有效的语言模型,我们希望在N-Gram模型中选用更大的n。但是当n很大时,数据会很稀疏。3-Gram是常用的选择。统计语言模型一般都是基于N-Gram的统计估计条件概率,基于神经网络的语言模型也是对N-Gram进行建模。

□ Skip-Gram模型。

■ 词集模型。机器学习模型不能直接处理文本,因此我们需要将文本(或者N-Gram序列)转化为实数或者实向量。在词集模型中,向量的每个分量的取值为0和1,代表单词是否在文档中出现。向量空间模型没有考虑词序信息。

■ 词袋模型。在词集模型中,向量的取值不考虑单词出现的次数,这会损失很多信息。词袋模型中,向量的每个分量的取值为单词在文档中的词频,为了避免向量的维度太大,通常会过滤掉在文档集合中词频很小的单词。

■ TF-IDF。TF(Term Frequency,词频)、IDF(Inverse Document Frequency,逆文档频率),用来评估单词对于文件集或语料库中的其中一份文件的重要程度。单词或短语的重要性随着它在文件中出现的次数成正比增加,同时随着它在语料库中出现的频率成反比下降。假设词汇表有N个词,文档d对应的向量表示为图像说明文字,其中图像说明文字图像说明文字为单词t在文档d中的词频(局部参数),图像说明文字为逆文档频率(全局参数),|D|为总文档数,|{d'∈D|t∈d'}|为包含单词t的文档数。TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或短语具有很好的类别区分能力,适合用来分类。TF-IDF模型是经典的向量空间模型(Vector Space Model,VSM),我们可以基于文档的向量表示计算文档之间的相似度,但不能很好地表示特别长的文档,而且这种向量表示也没有考虑词序信息。基于TF-IDF和词袋模型得到的表示文本的向量往往维度非常大,因此实际应用中一般需要降维处理。

□ 余弦相似度。在信息检索中,我们往往需要计算检索词q和文档d之间的相关性。例如将检索词和文档都表示为向量,计算两个向量d和q之间的余弦相似度。

图像说明文字

 Jaccard相似度。另外一种常用的相似度是Jaccard相似度,它为两个文档中相交的单词个数除以两个文档出现单词的总和:

图像说明文字

我们还可以定义Jaccard距离:

图像说明文字

 Levenshtein(编辑距离)。编辑距离是指两个字符串由一个转成另外一个所需要的最少编辑操作(如插入、删除、替换)次数,它也是衡量两个字符串相似度的指标。在自然语言处理中,单词一般作为基本的处理单元。

 隐性语义分析。隐性语义分析是把高维的向量空间模型表示的文档映射到低维的潜在语义空间中。隐性语义分析采用将文档或词矩阵进行奇异值分解(Singular Value Decomposition,SVD)的方法。由于奇异值分解的方法本身是对文档特征进行排序,我们可以通过限制奇异值的个数对数据进行降噪和降维。一般而言,文档和文档或者文档和查询之间的相似性在简化的潜在语义空间的表达更为可靠。

 Word2Vec。Word2Vec是最常用的一种单词嵌入,即将单词所在的空间(高维空间)映射到一个低维的向量空间中,这样每个单词对应一个向量,通过计算向量之间的余弦相似度就可以得到某个单词的同义词。传统的单词表示,如独热编码,仅仅是将词转化为数字表示,不包含任何语义信息。而单词嵌入包含了单词的语义信息,这类表示称为分布式表示。

2.2 特征选择

与特征提取是从原始数据中构造新的特征不同,特征选择是从这些特征集合中选出一个子集。特征选择对于机器学习应用来说非常重要。特征选择也称为属性选择或变量选择,是指为了构建模型而选择相关特征子集的过程。特征选择的目的有如下三个。

 简化模型,使模型更易于研究人员和用户理解。可解释性不仅让我们对模型效果的稳定性有更多的把握,而且也能为业务运营等工作提供指引和决策支持。

 改善性能。特征选择的另一个作用是节省存储和计算开销。

 改善通用性、降低过拟合风险。特征的增多会大大增加模型的搜索空间,大多数模型所需要的训练样本数目随着特征数量的增加而显著增加,特征的增加虽然能更好地拟合训练数据,但也可能增加方差。

好的特征选择不仅能够提升模型的性能,更能帮助我们理解数据的特点和底层结果,这对进一步改善模型和算法都有着重要作用。使用特征选择的前提是:训练数据中包含许多冗余或者无关的特征,移除这些特征并不会导致丢失信息。冗余和无关是两个概念。如果一个特征本身有用,但这个特征与另外一个有用的特征强相关,则这个特征可能就变得冗余。特征选择常用于特征很多但样本相对较少的情况。

特征选择一般包括产生过程、评价函数、停止准则、验证过程。为了进行特征选择,我们首先需要产生特征或特征子集候选集合,其次需要衡量特征或特征子集的重要性或者好坏程度,因此需要量化特征变量和目标变量之间的联系以及特征之间的相互联系。为了避免过拟合,我们一般采用交叉验证的方式来评估特征的好坏;为了减少计算复杂度,我们可能还需要设定一个阈值,当评价函数值达到阈值后搜索停止;最后,我们需要再验证数据集上验证选出来的特征子集的有效性。

2.2.1 过滤方法

使用过滤方法进行特征选择不需要依赖任何机器学习算法,如图2-1所示。过滤方法一般分为单变量和多变量两类。单变量过滤方法不需要考虑特征之间的相互关系,而多变量过滤方法考虑了特征变量之间的相互关系。常用的单变量过滤方法是基于特征变量和目标变量之间的相关性或互信息。单变量过滤方法按照特征变量和目标变量之间的相关性对特征进行排序,过滤掉最不相关的特征变量。这类方法的优点是计算效率高、不易过拟合。由于单变量过滤方法只考虑单特征变量和目标变量的相关性,过滤方法可能选出冗余的特征,所以单变量过滤方法主要用于预处理。常用多变量过滤方法有基于相关性和一致性的特征选择。

图像说明文字

下面详细介绍几种常用的过滤方法。

 覆盖率。它计算每个特征的覆盖率(特征在训练集中出现的比例)。若特征的覆盖率很小,例如我们有10 000个样本,某个特征只出现了5次,则此覆盖率对模型的预测作用不大,覆盖率很小的特征可以剔除。

 皮尔森相关系数。皮尔森相关系数用于度量两个变量X和Y之间的线性相关性,两个变量之间的皮尔森相关系数为两个变量之间的协方差和标准差的商:

图像说明文字

样本上的相关系数为:

图像说明文字

 Fisher得分。对于分类问题,好的特征应该是在同一个类别中的取值比较相似,而在不同类别之间的取值差异比较大。因此,特征i的重要性可以用Fisher得分Si表示:

图像说明文字

其中,μij和ρij分别是特征i在类别j中均值和方差,μi为特征i的均值,nj为类别j中的样本数。Fisher得分越高,特征在不同类别之间的差异性越大、在同一类别中的差异性越小,则特征越重要。

 假设检验。假设特征变量和目标变量之间相互独立,将其作为H0假设,选择适当检验方法计算统计量,然后根据统计量确定P值做出统计推断。例如对于特征变量为类别变量而目标变量为连续数值变量的情况,可以使用方差分析(Analysis of Variance,ANOVA),对于特征变量和目标变量都为连续数值变量的情况,可以使用皮尔森卡方检验。卡方统计量如下:

图像说明文字

其中,Oi为类型为i的观测样本的个数,N为总样本数。卡方统计量取值越大,特征相关性越高。

 互信息。在概率论和信息论中,互信息(或Kullback-Leibler散度、相对熵)用来度量两个变量之间的相关性。互信息越大则表明两个变量相关性越高,互信息为0时,两个变量相互独立。对于两个离散随机变量X和Y,互信息计算公式如下:

图像说明文字

其中,p(x)和p(y)为X和Y的边际概率分布函数,p(x,y)为X和Y的联合概率分布函数。直观上,互信息度量两个随机变量之间共享的信息,也可以表示为由于X的引入而使Y的不确定度减少的量,这时候互信息与信息增益相同。

 最小冗余最大相关性(Minimum Redundancy Maximum Relevance,mRMR)。由于单变量过滤方法只考虑了单特征变量和目标变量之间的相关性,因此选择的特征子集可能过于冗余。mRMR方法在进行特征选择的时候考虑到了特征之间的冗余性,具体做法是对跟已选择特征的相关性较高的冗余特征进行惩罚。mRMR方法可以使用多种相关性的度量指标,例如互信息、相关系数以及其他距离或者相似度分数。假如选择互信息作为特征变量和目标变量之间相关性的度量指标,特征集合S和目标变量c之间的相关性可以定义为,特征集合中所有单个特征变量f_i和目标变量c的互信息值I(f_i;c)的平均值:

图像说明文字

S中所有特征的冗余性为所有特征变量之间的互信息I(fi;fj)的平均值:

图像说明文字

则mRMR准则定义为:

图像说明文字

通过求解上述优化问题就可以得到特征子集。在一些特定的情形下,mRMR算法可能对特征的重要性估计不足,它没有考虑到特征之间的组合可能与目标变量比较相关。如果单个特征的分类能力都比较弱,但进行组合后分类能力很强,这时mRMR方法效果一般比较差(例如目标变量由特征变量进行XOR运算得到)。mRMR是一种典型的进行特征选择的增量贪心策略:某个特征一旦被选择了,在后续的步骤不会删除。mRMR可以改写为全局的二次规划的优化问题(即特征集合为特征全集的情况):

图像说明文字

F为特征变量和目标变量相关性向量,H为度量特征变量之间的冗余性的矩阵。QPFS可以通过二次规划求解。QPFS偏向于选择熵比较小的特征,这是因为特征自身的冗余性I(fi;fj )。

另外一种全局的基于互信息的方法是基于条件相关性的:

图像说明文字

其中,Qii=I(fi;c),Qij=I(fi;c│fj ),i≠j。SPECCMI方法的优点是可以通过求解矩阵Q的主特征向量来求解,而且可以处理二阶的特征组合。

 相关特征选择。相关特征选择(Correlation Feature Selection,CFS)基于以下一个假设来评估特征集合的重要性:好的特征集合包含跟目标变量非常相关的特征,但这些特征之间彼此不相关。对于包含k个特征的集合,CFS准则定义如下:

图像说明文字

其中,rcfi 和rfifj )是特征变量和目标变量之间的相关性以及特征变量之间的相关性,这里的相关性不一定是皮尔森相关系数或斯皮尔曼相关系数。

过滤方法其实是更广泛的结构学习的一种特例。特征选择旨在找到跟具体的目标变量相关的特征集合,结构学习需要找到所有变量之间的相互联系,结构学习通常将这些联系表示为一个图。最常见的结构学习算法假设数据由一个贝叶斯网络生成,这时结构为一个有向图模型。特征选择中过滤方法的最优解是目标变量节点的马尔可夫毯,在贝叶斯网络中,每一个节点有且仅有马尔可夫毯。

2.2.2 封装方法

由于过滤方法与具体的机器学习算法相互独立,因此过滤方法没有考虑选择的特征集合在具体机器学习算法上的效果。与过滤方法不同,封装方法直接使用机器学习算法评估特征子集的效果,它可以检测出两个或者多个特征之间的交互关系,而且选择的特征子集让模型的效果达到最优,如图2-2所示。封装方法是特征子集搜索和评估指标相结合的方法,前者提供候选的新特征子集,后者则基于新特征子集训练一个模型,并用验证集进行评估,为每一组特征子集进行打分。最简单的方法则是在每一个特征子集上训练并评估模型,从而找出最优的特征子集。

图像说明文字

封装方法需要对每一组特征子集训练一个模型,所以计算量很大。封装方法的缺点是:样本不够充分的情况下容易过拟合;特征变量较多时计算复杂度太高。下面详细介绍几种常用的特征子集搜索算法。

 完全搜索。完全搜索分为穷举和非穷举两类。广度优先搜索的时间复杂度太高,它不实用;分支定界搜索在穷举搜索的基础上加入了分支限界,若断定某些分支不可能搜索出比当前找到的最优解更优的解,则可以剪掉这些分支;定向搜索首先选择N个得分最高的特征作为特征子集,将其加入一个限制最大长度的优先队列,每次从队列中取出得分最高的子集,然后穷举向该子集加入一个特征后产生的所有特征集,将这些特征集加入队列;最优优先搜索与定向搜索类似,唯一的不同是不限制优先队列的长度。

 启发式搜索。序列向前选择,特征子集从空集开始,每次只加入一个特征,这是一种贪心算法;序列向后选择则相反,特征子集从全集开始,每次删除一个特征;双向搜索同时使用序列向前选择和向后选择,当两者搜索到相同的特征子集时停止。对于增L去R选择算法,若算法从空集开始,每轮先添加L个特征,再删除R个特征;若算法由全集开始,则每轮先删除R个特征,再添加L个特征。序列浮动选择每次选择添加和删除的特征个数不是固定的。

 随机搜索。执行序列向前或者向后选择的时候,此算法随机选择特征子集。

2.2.3 嵌入方法

过滤方法与机器学习算法相互独立,而且不需要交叉验证,计算效率比较高。但是嵌入方法没有考虑机器学习算法的特点。封装方法使用预先定义的机器学习算法来评估特征子集的质量,需要很多次训练模型,计算效率很低。嵌入方法则将特征选择嵌入到模型的构建过程中,具有封装方法与机器学习算法相结合的优点,而且具有过滤方法计算效率高的优点,如图2-3所示。嵌入方法是实际应用中最常见的方法,弥补了前面两种方法的不足。

图像说明文字

嵌入方法最经典的例子是LASSO(Least Absolute Shrinkage and Selection Operator)方法。

图像说明文字

在LASSO方法之前,大家都采用岭回归,通过对回归系数进行衰减来防止过拟合,但是岭回归不能进行特征选择,对模型的可解释性没有帮助。LASSO方法类似岭回归,它通过对回归系数添加L1惩罚项来防止过拟合,可以让特定的回归系数变为0,从而可以选择一个不包含那些系数的更简单的模型。实际应用中,λ越大,回归系数越稀疏,λ一般采用交叉验证的方式来确定。除了对最简单的线性回归系数添加L1惩罚项之外,任何广义线性模型如逻辑回归、FM/FFM以及神经网络模型,都可以添加L1惩罚项。除了简单的LASSO算法,嵌入方法还有结构化LASSO算法。常见的如Group LASSO算法,它对特征集合分组,对每一组采用类似LASSO的方法进行选择。

图像说明文字

另外一类嵌入方法是基于树模型的特征选择方法。在决策树中,深度较浅的节点一般对应的特征分类能力更强(可以将更多的样本区分开)。对于基于决策树的算法,如随机森林,重要的特征更有可能出现在深度较浅的节点,而且出现的次数可能越多。因此,可以基于树模型中特征出现次数等指标对特征进行重要性排序。

2.2.4 小结

表2-1对前面提到的三种常用的特征选择方法进行了比较。

图像说明文字

2.2.5 工具介绍

针对特征选择,目前已经有很多开源的工具包可以使用。针对过滤方法,若数据量较小,可以使用Sklearn里面的feature_selection模块;若数据量较大,可以使用Spark MLlib。针对嵌入方法,一般机器学习包的线性模型都支持L1正则,如Spark MLlib和Sklearn等。除此之外,在实际应用中比较常用的特征选择方法还有基于树模型的算法包,如Sklearn中的随机森林以及目前在工业界广泛使用的XGBoost,它们都支持根据不同指标(如增益或者分裂次数等)对特征进行排序。针对XGBoost模型,Xgbfi提供了多种指标对特征以及特征组合进行排序。

参考文献

[1] Ng A. Machine learning and AI via brain simulations. 2013.

[2] Tukey J W. Exploratory data analysis. 1977, 2.

[3] Tukey J W. We need both exploratory and confirmatory. The american statistician, 1980, 34(1): 23-25.

[4] Chen T Q , Guestrin C. XGBoost: a scalable tree boosting system. Proceedings of the 22nd acm sigkdd international conference on knowledge discovery and data mining. ACM, 2016.

[5] Juan Y C, Zhuang Y, Chin W S, et al. Field-aware factorization machines for CTR prediction. Proceedings of the 10th ACM conference on recommender systems. ACM, 2016.

[6] He X R, Pan J F, Jin O, et al. Practical lessons from predicting clicks on ads at facebook. Proceedings of the eighth international workshop on data mining for online advertising. ACM, 2014.

[7] Micci-Barreca D. A preprocessing scheme for high-cardinality categorical attributes in classification and prediction problems. ACM SIGKDD explorations newsletter, 2001, 3(1): 27-32.

[8] Leskovec J, Rajaraman A, Ullman J D. Mining of massive datasets. Cambridge university press, 2014.

[9] Mikolov T, Chen K, Corrado T, et al. Efficient estimation of word representations in vector space. arXiv preprint arXiv:1301.3781, 2013.

[10] Peng H C, Long F H, Ding C. Feature selection based on mutual information criteria of max-dependency, max-relevance, and min-redundancy. IEEE transactions on pattern analysis and machine intelligence, 2005, 27(8): 1226-1238.

[11] Hall M A. Correlation-based feature selection for machine learning. 1999.

[12] Tibshirani R. Regression shrinkage and selection via the lasso. Journal of the royal statistical society. Series B (Methodological) ,1996: 267-288.

[13] Guyon I, Gunn S, Nikravesh M, et al. Feature extraction: foundations and applications. Springer, 2008, 207.

[14] Zheng A. Mastering feature engineering: principles and techniques for data scientists. 2016.

目录

  • 序言
  • 前言
  • 第一部分 通用流程
  • 第1章 问题建模
  • 第2章 特征工程
  • 第3章 常用模型
  • 第4章 模型融合
  • 第二部分 数据挖掘
  • 第5章 用户画像
  • 第6章 POI实体链接
  • 第7章 评论挖掘
  • 第三部分 搜索和推荐
  • 第8章 O2O场景下的查询理解与用户引导
  • 第9章 O2O场景下排序的特点
  • 第10章 推荐在O2O场景中的应用
  • 第四部分 计算广告
  • 第11章 O2O场景下的广告营销
  • 第12章 用户偏好和损失建模
  • 第五部分 深度学习
  • 第13章 深度学习概述
  • 第14章 深度学习在文本领域中的应用
  • 第15章 深度学习在计算机视觉中的应用
  • 第六部分 算法工程
  • 第16章 大规模机器学习
  • 第17章 特征工程和实验平台