《速通机器学习》

前言:

读者朋友们大家好,本书从传统的机器学习,如线性回归、逻辑回归、朴素贝叶斯、支持向量机、集成学习,到前沿的深度学习和神经网络,如DNN、CNN、BERT、ResNet等,对人工智能技术进行零基础讲解,内容涵盖数学原理、公式推导、图表展示、企业应用案例。

本书面向初,中级读者,能帮助读者迅速掌握机器学习技术的相关概念及原理。本书内容结合作者多年的科研工作经验,理论和实践并重,对科研、学习、面试等均有帮助。

如若想要《速通机器学习》与《速通深度学习数学基础》二书电子档,可以评论区留言获取;如对机器学习感兴趣想一起学习讨论也可后台留言,我看到就会回复;谢谢大家。


机器学习是人工智能领域最活跃的分支之一,作为多学科交叉的重要工具,为计算机领域解决实际学习问题提供了理论支撑与应用算法。近年来,机器学习在互联网应用中崭露头角,计算机视觉、自然语言处理、推荐系统、搜索系统等积累了大量的数据和丰富的场景,促进了包括机器学习在内的诸学科的发展与繁荣。与此同时,机器学习的快速发展,也让我们切实领略了人工智能给人类生活带来各种改变的潜力。
这是一本涵盖机器学习现有重要领域和关键算法的读物,主要面向人工智能、机器学习、模式识别、数据挖掘、计算机应用、数学和统计学等领域的研究生和相关技术人员。这本书为我们介绍了经典机器学习、深度学习的常见模型,涉及领域包括图像处理、自然语言处理、推荐系统等。
不同于侧重理论的机器学习读物,本书作者摒弃了复杂烦琐的数学公式和理论推导,转而采用对各类知识点给出应用实例和绘制图表等方式进行讲解。同时,书中蕴含了作者对机器学习理论及各类模型的内在关系的理解与思考,并通过细致的对比和说明,透彻地讲述了不同概念之间的传承与发展,使读者可以快速领略机器学习的精髓并掌握一定的自学能力。
本书作者勤于思考、关注技术发展,在工作中积累了丰富的机器学习实战经验,这些经验正是本书的灵感和和创意来源。难能可贵的是,书中的大量示例均源于作者亲身参与的项目,对读者具有借鉴意义,这也是本书的亮点之一;特此推荐。

中国科学院院士 樊文飞


第一章 数据的量化和特征提取

1.1 机器学习概述

1956年夏季,以麦卡赛、明斯基、罗切斯特、申农等为首的一批有远见卓识的年轻科学家举办了一次聚会,共同研究和探讨用机器模拟智能的一系列有关问题,并首次提出了“人工智能”这一术语。这次聚会标志着“人工智能”这门新兴学科的正式诞生。

经过数十年的发展,人工智能已从最初的感知机,历经逻辑回归和支持向量机,发展到目前最为火热的深度学习。人工智能的研究成果已经从实验室落地,其工程实践涉及的应用也从个别领域延伸至各行各业。目前,绝大多数人工智能都是通过机器学习实现的(这里的“机器”特指计算机),因此,在本书中,人工智能和机器学习同指一个概念。

机器学习是什么呢?通俗地讲,就是机器(计算机)使用模型进行学习,以解决特定任务。模型可以理解为一个数学运算函数。模型的输入是图像等信息(函数的自变量),模型的输出是我们想要的结果(函数的因变量),例如识别图像中的动物是“猫”还是“狗”。函数里的很多参数是未知的,学习阶段就是通过已知结果的数据来寻找合适的参数,使模型能够给出正确的输出。学习一般被形象地称为训练。模型训练完成后,我们就可以使用它对未知类别的数据进行预测。

任何一项技术都有自己的业务边界,业务边界决定了技术的应用场景。机器学习只能处理有规律的、平滑连续的任务,例如声音识别、图像识别、文本分类等,但对猜骰子点数、预测彩票等完全随机事件无能为力。平滑连续是指输入的微小改变不会影响预测结果,例如“预测一个数字是否为质数”等非连续任务,输入从12到13,仅增大了1,预测结果却完全不同(机器学习很难在这类任务上取得较好的效果)。

人工智能的目的是使用机器代替人类的脑力劳动。人类的脑力劳动一般分为创新性脑力劳动和重复性脑力劳动。识别声音、文字、图像等属于重复性脑力劳动,这类任务在不久的将来可以由机器胜任;而在创新性脑力劳动方面,例如写作、发明创造等,机器学习还有很长的路要走。


1.2 特征提取

在开展人工智能相关工作时,我们面临的业务大都是客观世界中的问题,例如图片、视频、文本的识别及推荐系统的设计等。这些业务包含各式各样的数据——图片对应的是像素值,文本对应的是字符串,语音对应的是声波,推荐系统则包含大量的用户行为数据——五花八门、无奇不有。但是,机器学习模型作为一个数学函数,接受的输入一般是浮点数数组。这个数组用专业术语表述,叫作特征向量,数组的长度叫作特征向量的维度。特征向量的某个具体位置的数值表示真实世界中某个属性的强度。因此,无论何种业务,都需要将业务特征表示为向量 x,这个过程叫作特征提取,如图1-1所示。

图1-1

如果各类业务特征统一以向量表示(不同的特征提取方法),后续的模型设计环节就可以与业务解耦。模型本身可以部分脱离业务(但不能完全脱离),仅需要针对特征向量进行研发,而这些特征向量可能来自完全不同的业务场景。

一些业务特征天然就是数值化的。例如,一个年龄30岁、身高175厘米的人,可以直接表示成特征向量 〖[30,175]〗^T。另一些业务特征不太容易直接表示成特征向量。例如,“我喜欢机器学习”这句话对应的是一个字符串,需要使用特征提取技术对其进行向量化(如转换成向量 〖[-0.1,0.3,0.2,0.4]〗^T)。特征提取有很多方法,并且往往和业务有关。即使是同一客观事物,在面向不同的业务时关注的目标也是不一样的。因此,特征的关注点千差万别。

下面介绍一些常用的特征提取方法。

在做图像识别时,首先会对输入的图片进行尺寸归一化,既将不同尺寸的图片缩放至同一尺寸,例如200像素×200像素。我们知道,图片是由大量像素点以二维方式排列而成的。在彩色图片中,每个像素点由一个3维数组组成,分别表示R、G、B(红、绿、蓝)颜色的强度,每种颜色的取值范围为0~255。例如,[255,0,0] 表示红色,[0,125,125] 则对应于黄色。因此,彩色图片对应于 200×200 的矩阵,矩阵中的每个元素都使用一个3维向量来表示颜色信息,彩色图片可以表示为 200×200×3 的向量,其中的“3”也称作通道数。黑白图片每个像素点的取值范围为0~255,0表示白色,255表示黑色,其他数值则表示从白色到黑色的渐变色(灰色)。黑白图片对应的是 200×200×1 的向量(黑白图片为单通道图片)。彩色图片和黑白图片的特征,如图1-2所示。在一些颜色不是特别重要的场景中,会将彩色图片转换成黑白图片,这时特征维度只有原来的 1/3,计算量和模型复杂度有所降低。

图1-2

在做视频处理时,一个视频其实是由多幅有序图片组成的。一幅图片称为一帧。常见的帧频是30帧/秒,即一段1秒的视频其实是快速播放30幅有序图片形成的。视频特征和图片特征类似,只不过加上了时间维度。例如,一段5秒的彩色视频(5秒×30帧/秒=150帧)所对应的特征向量的长度为 200×200×3×150。长视频往往会对应非常多的帧,这对计算来说负担很重。为了减轻计算压力,通常会使用关键帧技术,从视频中抽取一些视觉效果发生了急剧变化的帧作为特征,其他帧则会被舍弃。

除图像外,文本处理也是人工智能的一个重点领域。与文本处理相关的技术和应用主要包括文本内容理解、信息提取、智能聊天对话等,这些技术和应用称为自然语言处理(Nature Language Process,NLP)。假设词库中有a、b、c、d、e、f、g、h、i、j共10个词(实际词库中的词往往在20万个以上),每个词可以表示为一个10维向量,a~j分别对应于特征向量的1~10位,那么词a可以用10维向量 〖[1,0,0,0,0,0,0,0,0,0]〗^T 来表示,这种向量 化方法叫作one-hot。

如何对文章进行向量化呢?如果在一篇文章中,词a、b、e、f各出现了一次,则对应的特征向量为 〖[1,1,0,0,1,1,0,0,0,0]〗^T。而如果在一篇文章中,词a出现了两次,就可以进一步用词频来表示,即 〖[2,1,0,0,1,1,0,0,0,0]〗^T。这种对文章进行向量化的方法叫作multi-hot。

one-hot和multi-hot比较粗糙,有很多缺点,列举如下。

汉语的常用词有约20万个,但在一篇文章中可能仅出现几百个,因此,特征值会出现大量的0,向量稀疏,信息不紧凑,造成了存储资源的浪费。

没有考虑词的顺序问题。例如,“我借给你钱”和“你借给我钱”这种意思相反的句子的multi-hot向量是一样的。

中文的语义歧义问题。例如,“苹果手机”和“吃苹果”中的“苹果”是完全不同的事物,但这两个“苹果”所对应的one-hot和multi-hot向量是一样的。

在使用one-hot对文本进行编码时,无法体现语义的相似度。例如,“手机”“互联网”“红烧肉”三个词,在语义上,“手机”和“互联网”比较近,“红烧肉”和它们没有关系。采用one-hot编码,这三个词的对应向量为 〖[1,0,0]〗^T、〖[0,1,0]〗^T、〖[0,0,1]〗^T。从向量的角度看,这三个词彼此之间的夹角都为90°,表达不出语义上的相似性。

尽管one-hot方法有以上缺点,但在2014年之前,做自然语言处理的人基本上都在使用它——毕竟方法简单,在要求不高的场景中效果也能达标。在深度学习得到广泛应用之后,one-hot式微。目前流行的方法是让每个词对应于一个稠密低维(常见128维、256维,远低于one-hot中动辄几十万维)向量,例如词“苹果”对应于向量 〖[-0.1,1.2,3.3,2.1,4.3]〗^T。这类向量也称为词向量或Word embedding。词向量的生成方法,一般是先进行随机初始化,再进行任务驱动(例如文本分类、情感分析),从而训练模型以改变稠密向量,其经典方法是Word2vec。在使用稠密向量时,每个词所对应的embedding将会不同,具体表现为:近义词的embedding之间的夹角很小,语义无关的词的embedding之间的夹角很大。

对于包含多个词的文本,可以把每个词所对应的词向量相加作为文本向量。不过,相加(求和)忽略了词出现的顺序。为了解决这个问题,可以把词向量按顺序串联起来。例如,词向量有128维特征,一共10个词,那么该文本对应的就是 128×10 维的特征向量。可以使用配套的时序模型(例如RNN、LSTM、Transformer),将这个 128×10 维的向量转换成低维(例如128维)向量来表示文本语义。特别地,一词多义问题也可以通过BERT之类的模型来解决。从整体看,人工智能处理文字的难度远高于处理图像。目前,图像处理技术已经比较成熟了,有很多固定的方法和模式,但文字处理的难度仍然很大,技术仍然很不成熟。

除了图像、文字、语音等自然特征,还有很多业务特征需要向量化。例如,电商场景需要对每个用户进行用户画像。用户画像的一个维度是性别,而性别这个特征可以用以下两种方式表达。

男:〖[0]〗^T。女:〖[1]〗^T。

男:〖[0,1]〗^T。女:〖[1,0]〗^T。

第一种方式只有1维特征,男、女用数值来区分,但这样做是有问题的:同一位置具有可比性,从数值上看女大于男,但实际上男、女只是两个状态而已,没有大小关系。第二种方式其实就是one-hot。这样看来,第二种方式更合适——虽然存在冗余问题,但保证了男、女的平等性。在机器学习中通常会采用第二种方式。由此可见,虽然one-hot在NLP领域不适用,但并非一无是处,仍然有其适合的场景。这也说明,在机器学习领域,方法本身没有好坏之分,关键在于方法和场景是否契合。

再举个例子。在电商场景中,将年龄的取值范围设置为0~100,最简单的方法是用1维特征来表示,例如将32岁表示成 [32]。但是,在电商场景中,单纯的年龄数据并不重要,我们更关心“小孩”“年轻人”“中年人”“老年人”这种能够反映消费能力和消费习惯的特征。因此,用1维特征来表示的方法欠妥——单纯的数值特征,尽管具有数值的含义(例如,20岁和50岁的平均值是35岁,而在实际的电商场景中不会这样使用),但没有将业务的特点明确表示出来。

作为改进,我们可以把0~100岁分成四段,用一个4维向量来表示。不同年龄段有如下特征。

小孩:〖[1,0,0,0]〗^T,0<age ≤ 18。

年轻人:〖[0,1,0,0]〗^T,18<age ≤ 40。

中年人:〖[0,0,1,0]〗^T,40<age ≤ 60。

老年人:〖[0,0,0,1]〗^T,60<age。

通过这种方法提取的特征能更好地反映用户的消费能力和购物特点,例如小孩喜欢为游戏充值、年轻人愿意购买新奇的商品、中年人容易购买贵重商品、老年人经常购买保健品,与场景的贴合度很高。

从机器学习的角度看,这个方法的一个好处就是特征较为稳定。例如,25岁和26岁其实没有本质的差别,因为它们在同一区间内。这个方法的缺点在于对分段点附近的年龄过于敏感,例如17岁和19岁会被划分到两个区间。因此,这个方法对划分区间提出了较高的要求。为了缓和边界点的敏感性,可在划分时令相邻区间有交集,例如“0~18、15~40、35~60、55~100”,这样,30岁的人所对应的特征为 〖[0,1,1,0]〗^T,即同时具备中年人和年轻人的特点。

还有一个特点值得研究。电商网站一般会在后台存储用户的消费能力数据,例如:16~40岁的人购买能力比较强,消费能力为 10;女性的购买欲望比较强,消费能力为 15;若两者同时满足,例如“25岁的女性”,则其消费能力可能会飙升到100 ——不是简单的 10+15。因此,除了直接特征,还需要一些组合特征。例如,对一位26岁的女性,原来表示为性别 [1,0]^T、年龄 [0,1,0,0]^T,拼接后得到一个6维特征向量 x=〖[1,0,0,1,0,0]〗^T;而现在需要引入第7维作为组合特征,当第1维和第4维同时为1时将其置1,即 x_7=x_1 x_4,x_7 代表“年轻女性”这种更高层次的特征,特征向量为 〖[1,0,0,1,0,0,1]〗^T。

一些资讯类App会提供视频、图片和文字等内容。对于视频,可以考虑的特征有时长、清晰度、完成率等;对于图片,涉及的特征有清晰度、敏感信息等;对于文章,主要特征有篇幅、关键字、作者等。各种特征组合起来,数量巨大且具有较强的业务性。这些特征的具体组合方式,需要代码编写者和策略产品经理共同确定。随着机器学习的发展,现在也出现了很多能够进行特征自动组合的模型。

在二手汽车交易平台中,汽车的颜色是一个很重要的特征。能否用数组 [0~255,0~255,0~255] 表示颜色?答案是:不能。因为在汽车交易领域,颜色只代表购买者的审美倾向,并无大小之分。同时,汽车颜色种类有限,如果有20种颜色,就用一个20维的one-hot向量表示即可。

总之,特征向量的定义方式要根据具体的业务场景确定,特征要能尽量客观地描述实际问题。

综上所述,机器学习的步骤如图1-3所示。

图1-3

在使用非深度学习(传统)模型时,对特征工程的要求比较高。而深度学习模型与非深度学习模型相比,对特征工程的要求大幅降低,它通过计算机的运算能力对所处场景进行理解,模型可以根据目标任务自动提取特征,减轻了人的工作量——尽管模型复杂度增加、运算量增大,但对人的要求降低了。同时,硬件的迅速发展使机器成本不断降低——这也是近年来深度学习流行的原因之一。

1.3 向量距离计算

前面详细讲解了如何使用向量来表示各类特征。除了将向量 x 输入模型作为特征,我们有时也需要通过向量之间的距离来衡量特征之间的差异。

有多种方法可以度量向量之间的距离,每种方法都有其应用场景和优缺点。这些方法有一些共性,列举如下。

同一性:d(x,x)=0,同一点到自身的距离为0。

非负性:d(x,y) ≥ 0,距离不能小于0。

对称性:d(x,y)=d(y,x)。

直递性:d(x,y) ≤ d(x,z)+d(y,z),即三角形法则(由3个点组成的三角形,两边长之和大于第三边)。

多种函数可以同时满足上述条件。理论上,这些函数都可用于度量距离。但是,这些函数中的大部分在机器学习中并不常用。下面介绍机器学习中的常用距离。

欧氏距离是机器学习中最为常见的距离之一,它源自两点之间的距离公式。两个特征向量分别为

x=[x_1,x_2,⋯,x_n ]^T

y=〖[y_1,y_2,⋯,y_n]〗^(T )

欧氏距离的计算公式如下。

d_Euclidean (x,y)=√(∑_(i=1)^n▒〖(x_i-y_i)〗^2 )=√((x-y)^T (x-y) )

d_Euclidean (x,y) 常写作 ‖x,y‖。特别地,‖x‖ 表示 x 距离原点的欧氏距离,‖x‖=√(∑_(i=1)^n▒〖(x_i)〗^2 )。

曼哈顿距离(Manhattan Distance)也可用于度量两点之间的距离。想象一下:你在曼哈顿街头,要开车从一个十字路口到另一个十字路口,实际驾驶距离是这两个十字路口之间的直线距离吗?显然不是——除非你能穿越大楼。这里的实际驾驶距离就是曼哈顿距离。曼哈顿距离也称为城市街区距离(City Block Distance),其计算公式如下。

d_Manhattan (x,y)=∑_(i=1)^n▒|x_i-y_i |

d_Manhattan (x,y) 也常写作 |x,y|。特别地,|x| 表示 x 距离原点的曼哈顿距离,即 |x|=∑_(i=1)^n▒|x_i | 。

在国际象棋棋盘上,国王可以朝8个方向移动。国王移动到目标点所需的步数就是切比雪夫距离(Chebyshev Distance)。切比雪夫距离用于计算各维度数值差中的最大值,计算公式如下。

d_Chebyshev (x,y)=max⁡(|x_1-y_1 |,|x_2-y_2 |,⋯,|x_n-y_n |)

切比雪夫距离和曼哈顿距离的区别在于:在斜向移动时,曼哈顿距离所需的距离为2,切比雪夫距离所需的距离为1。

广义圆可以定义为到圆心距离相等的点的集合。分别使用以上介绍的三种距离画出来的“圆”,如图1-4所示。

图1-4

闵可夫斯基距离(Minkowski Distance)的计算公式如下。

▒〖〖〗〗d(Minkowski)(x,y)=(∑(i=1)n▒〖〖|x〗i−yi|〗p)(1/p)

其中,p 是一个变参数。

闵可夫斯基距离公式其实是一个通项公式。以上介绍的三种距离其实都是闵可夫斯基距离的特例。

当 p=1 时,就是曼哈顿距离。

当 p=2 时,就是欧氏距离。

当 p→∞ 时,就是切比雪夫距离。

以上三种距离都有一个缺点,就是容易受特征量纲的影响。例如,用一个2维特征表示人的体重和身高,体重的单位为千克,身高的单位为毫米,如 〖[60,1700]〗^T。此时,体重的数量级远小于身高,这会导致在计算距离时放大身高的作用。

我们以欧氏距离为例,讨论如何解决这个问题。对数据进行归一化,即将各个维度的均值和方差分别归一至 (0,1),以消除量纲不同带来的差异。归一化在各个维度独立进行,公式如下。

x_i^'=x_i/σ_i

σ_i 为第 i 维特征所对应的标准差。修正后的距离计算公式如下。

d_(Standardized Euclidean) (x,y)=√(∑_(i=1)^n▒〖(x_i^'-y_i^')〗^2 )

上述方法称作标准化欧氏距离(Standardized Euclidean Distance)。

在提取特征时,特征之间并不是独立的,维度之间往往存在冗余的问题。例如,体重和身高之间就存在较强的相关性。特征冗余带来的影响是:某些因素在各个维度重复出现,在计算距离时会被重复计算,从而使其影响被放大。为了降低特征冗余带来的影响,可以使用马氏距离(Mahalanobis Distance)进行计算,公式如下。

d_Mahalanobis (x,y)=√((x-y)^T Σ^(-1) (x-y))

这里使用了向量的表示方式。Σ 为各维度的协方差矩阵,其中,对角线元素表示各维度自身的方差,非对角线元素表示各维度之间的相关性。可以看出,对于马氏距离,如果不考虑特征之间的相关性(非对角线元素为0),就会退化为标准欧氏距离。在使用标准欧氏距离或马氏距离时,因为涉及估计方差(协方差矩阵),所以需要一定的数据量,且数据量越大,方差(协方差矩阵)的估计结果越准。

我们用one-hot向量来表示所观看的电影的特征。假设有五部电影,那么向量的维度为5维。在看过的电影的特征位置写1,在没看过的电影的特征位置写0。我们是否可以通过one-hot向量的距离来度量两个人观影习惯的差异呢?答案是:不可以。因为我们无法确定这两个人是否全部看过这五部电影——如果没有观影,那么自然无法提供关于喜好的信息,而在都为0的位置计算出来的距离是没有意义的。假设有三个人,user1和user2共同观看了两部电影,user1和user3共同观看了一部电影,则他们观看电影所对应的向量分别为

user1=[1,0,0,1,0]

user2=[1,0,1,1,0]

user3=[0,0,0,1,0]

而我们的期望是 user1 和 user2 的距离更近。使用欧氏距离计算 user1 和 user2、user1 和 user3 的距离,公式如下。

d_Euclidean (user1,user2)=1

d_Euclidean (user1,user3)=1

user1 和 user2、user1 和 user3 的欧氏距离相等,与我们的期望不符。因此,欧氏距离不能在此场景中有效度量观影习惯的差异。

然而,对于两个人都看过的电影,即两个人都为1的位置,却能反映出两个人的喜好相同。可以使用Jaccard距离度量两个集合之间的差异,计算公式如下。

d_Jaccard (user1,user2)=1-|A∩B|/|A∪B|

在这里,A 和 B 分别为这两个人看过的电影的集合,A∩B 为这两个人看过的电影的交集,A∪B 为这两个人看过的电影的并集。使用Jaccard距离进行计算,公式如下。

d_Jaccard (user1,user2)=1-2/3=1/3

d_Jaccard (user1,user3)=1-1/2=1/2

显然,此时 d_Jaccard (user1,user2)<d_Jaccard (user1,user3),user1 和 user2 之间的距离比较近,而这也符合我们的认知。Jaccard距离的用途很广,可用于度量购物偏好的差异、文章内容的差异等具有同质集合属性的特征。

在机器学习中,除了距离,也常使用相似度来度量两个向量。顾名思义,两个向量的相似度越高,说明它们越相似。因此,相似度和距离成反相关。余弦相似度(Cosine Similarity)是一种常见的相似度,其计算公式如下。

cos(x,y)=(∑_(i=1)^n▒〖x_i y_i 〗)/‖x‖‖y‖

余弦相似度的值域是 [-1,+1]。它用于衡量两个向量的夹角,夹角越小,两个向量越相似。+1 表示两个向量的相似度相同,即两个向量的方向完全相同(cos0=1)。-1 则表示两个向量的方向完全相反(cosπ=-1),此时两个向量呈高度负相关。当余弦相似度为0时,两个向量是互相垂直的(cos π/2=0),称作正交。相互正交的向量彼此线性无关。

余弦相似度,如图1-5所示。

图1-5

可以看出,余弦相似度和向量的长度无关,它是用来衡量各个维度比例的相似性的。当两个向量各维度的比例相同时,它们的夹角为0,相似度为1。

∑_(i=1)^n▒〖x_i y_i 〗 称为向量 x 和 y 的内积,记作 〈x,y〉=∑_(i=1)^n▒〖x_i y_i 〗=x^T y。内积可以理解成未

必归一化的余弦相似度,值域为 (-∞,+∞),有时也用于度量向量的相似性。‖x‖ 为归一化因子,用于将向量 x 的长度归一至1。相比较而言,cos(x,y) 只考虑了 x 和 y 的角度差,〈x,y〉 则综合考虑了 x 和 y 的角度差与长度差。

有时需要将余弦相似度转换为余弦距离,公式如下。

d_cos (x,y)=1-cos(x,y)

特别地,当 ‖x‖=1、‖y‖=1 时,d_cos (x,y) 和 d_Euclidean (x,y) 有如下关系。

d_Euclidean (x,y)=√(2d_cos (x,y)))=√(2(1-cos(x,y)))

即欧氏距离和余弦相似度之间存在单调关系。


第二章:线性回归

在企业中,技术人员会将商品的价格、品牌等作为输入来预测商品的销量,甚至通过上市公司的财报、行业信息等来预测公司股票价格的变化。它们的共同点是通过输入来预测输出。在机器学习中,这类业务有一个专门的名字——回归(Regression)。

回归是指通过大量已知数据发现输入 x 和输出 y 的内在关系,并对新的输入进行预测。发现内在关系后,就可以通过它来预测新的输入 x 所对应的输出 y^'。在本章中,我们用 y 表示真实的输出,用 y^' 表示预测的输出。

在使用回归前,需要假设 y^' 和 x 之间的关系类型。这种关系类型称为模型。例如,在 y^'=wx+w_0 中,y^' 和 x 成线性关系(x 的变化按比例影响 y^'),因此该模型也称为线性回归。需要注意的是,y 和 x 之间的关系未必满足我们的假设,它甚至是未知的。

以上只对 y^' 和 x 之间的关系进行了假设,而 w 和 w_0 的值是未知的,因此,需要通过一些方法求解 w 和 w_0。

要想求解 w 和 w_0,首先需要 x 和 y 的一些过往真实数据,例如 (x=3,y=4)、(x=1,y=2.5) 等。这些数据称为训练数据。通过训练数据求解未知的 w 和 w_0 的过程称为学习。学习过程通常是由机器自动进行的,这也是“机器学习”这个词的由来。总之,模型选择是一项人工假设工作,而求解 w 和 w_0 是一个自动定量过程。

当模型训练完毕,w 和 w_0 将对应于已知的数值,例如

y^'=3.2x+1.1

有一个新的输入(可以是从未在训练数据中出现的),就可以计算相应的 y^',这个过程称为预测。

在使用回归时,y^' 和 x 之间的对应关系不仅可以假设成 y^'=wx+w_0 这种简单的线性形式,也可以由诸如 y^'=w_1 x^2+w_2 x+w_0 这种复杂的形式来表示。形式越复杂,模型蕴含的 x 和 y^' 之间的关系就越复杂,捕捉 x 和 y 之间的关系的能力就越强。但是,复杂的模型会带来一些负面效应,本书后续会进行系统的论述。

2.1 线性回归的基本概念

当输入为1维数据时,线性回归模型如下式所示。

y^'=wx+w_0

显然,此时线性回归在平面上对应于一条直线,这也是“线性回归”名称的由来。

线性回归模型在平面上对应的直线,如图2-1所示。

图2-1

w_0 也称作偏置项。尽管它和输入并无直接关系,但它有重要的作用。如果没有 w_0,那么直线 y^'=wx 必须经过原点,而这极大地限制了模型的能力。

更为一般的情况是,线性回归模型往往是多输入(m 个输入)的。此时,线性回归可以由下式表示。

y^'=w_1 x_1+w_2 x_2+⋯+w_m x_m+w_0

为了简化书写,上式通常可以表示成矩阵相乘的形式。

y^'=w^T x+w_0

其中

有了线性回归模型 y^'=w^T x+w_0,就可以利用训练数据计算模型中的未知参数 w=[w_1,⋯,w_m ]^T 和 w_0 了。

已知数据 〖{x_((i)),y_((i))}〗_(i=1)^N(训练样本)是客观事实。样本数据 x_((i)),y_((i)) 都是成对出现的,

角标 (i) 表示第 i 个训练样本。训练样本一般是通过收集已经发生的事件数据得到的,例如人工标注数据、互联网公司产生的大量日志。

如果输入 x 可以通过运算得到 y^'=w^T x+w_0,那么 y^' 和真实的 y 越接近,w 和 w_0 就越合理,也就是我们越想要的。

有些读者可能会问:是否能够通过解方程的方法求解 w 和 w_0 呢?在这里,我们简单讨论一下。例如,通过已知数据,可以得到如下方程组。

在这里,w_0,w_1,⋯,w_m 为未知数。从数学的角度看,这是一个典型的多元一次方程组。多元一次方程组的求解比较简单,本书不再赘述。然而,在机器学习场景中,解方程本身会遇到以下问题。

训练样本量通常很大(例如,互联网公司的日志数据量往往都以GB为单位计),这意味着可能有海量的方程。这些方程之间往往存在矛盾,很难协调。而如果采用矩阵的形式求解方程,则涉及百万维的矩阵运算,这对算力、机器配置等提出了巨大的挑战,中小型公司通常无法承担。

在线性回归中,因为对应的是多元一次方程,所以方程尚有解析解。但是,模型远不止线性回归一种,当模型非常复杂时,例如

y^'=1/(1+e^(〖-(w〗^T x+w_0)) )

就很难找到有效的解析解了。即使有了解析解,也需要“特事特办”,为每种模型设计一套特有的方法,而这对机器学习的大规模普及和应用是不利的。

在互联网公司中,数据量往往非常大。例如,以过去半年的日志作为训练样本是非常困难的(因为如此规模的数据很难被一次性加载到机器中)。但是,在解方程时需要加载全部数据,这对实操性提出了不小的挑战。

综合上述三个原因,在机器学习领域,很少会采用解方程的方法求解模型的未知参数。为了顺利求解模型参数 w 和 w_0,梯度下降法诞生了。

2.2 损失函数和梯度下降法

首先,让训练数据图形化。当 x 是1维数据时,{x,y} 为二维坐标系中的一个点。训练样本在该坐标系中对应于若干散点,每个点都代表一个样本,如图2-2所示。

图2-2

线性回归希望找到一条合适的直线来尽量多地穿过坐标系中的点,从而使模型和数据尽可能契合。直线由参数 w 和 w_0 决定,不同的参数对应于不同的直线。那么,该如何调整 w 和 w_0 呢?

在实际工程中,每个数据点都具有一定的随机干扰和自身特例,所以大量数据点很难恰巧落在一条直线上(往往散落在直线附近)。因此,无论参数 w 和 w_0 如何取值,都会产生偏离直线的误差。模型学习的目的就是找出一条合适的直线,使各个数据点上的误差之和尽可能小(理想状况为0,但在实际应用中几乎不可能达到)。显然,误差是一个不小于0的数。误差可以表示为下式。

其中,y_((i))^' 表示模型在 x_((i)) 的输出,y_((i)) 表示真实的输出。在这里选择均方误差(Mean Square

Error,MSE)函数作为损失函数,平方计算保证了误差不小于0。需要注意的是,损失函数的类型很多,MSE只是其中之一。

相信细心的读者能看出来,Loss 计算就是求所有数据的预测值 y_((i))^' 和真实值 y_((i)) 之间的

欧氏距离(只是少了开根号的过程)的平均值。

如果 w_0 不变,那么 w 和 Loss 是一一对应关系,即一个 w 值对应于唯一的 Loss 值。投影到二维坐标系,横轴为 w,纵轴为 Loss。如图2-3所示,这是一条典型的抛物线(对应于高维空间中的抛物面)。

图2-3

此时,问题变为找到一个使 Loss 最小的 w。在图2-3中,点 w^* 为 w 的理想位置,即

可以证明 Loss 为凸函数,其存在唯一极小值且极小值为最小值。因此,最小值(极小值)所对应的 w 满足下式。

▒〖〗∂Loss/∂w=2/N∑(i=1)N▒〖(wx((i))+w0−y((i)))〗x((i))=0

同理,最小值(极小值)所对应的 w_0 满足下式。

▒〖〗∂Loss/(∂w0)=2/N∑(i=1)N▒〖(wx((i))+w0−y((i)))〗=0

综合以上二式求解,可得

其中

▒¯x=1/N∑(i=1)N▒x((i))

尽管通过上述方法可以求出最优的 w 和 w_0,但仍存在以下问题。

在训练样本量和特征维度较大时,计算性能和机器内存会成为瓶颈。

上述方法不是通用的。如果 y 和 x 之间的关系比较复杂,并不是简单的线性关系,那么方程可能不存在解析解。

因此,我们需要寻找其他具备通用性的方法,以便应用在大多数机器学习场景中。

在高等数学中,导数可用于衡量函数和变量之间的关系。以输入1维数据为例,模型为 y=wx+w_0,很容易就能得出 Loss 对 w 求导的形式,如下式所示。

▒〖〗∂Loss/∂w=1/N∑(i=1)N▒〖2x((i))(wx((i))+w0−y((i)))〗

∂Loss/∂w>0,表示 w 的变化方向与 Loss 相同。当 w 变大时,Loss 就变大;当 w 变小时,

Loss 就变小。我们的目的是使 Loss 变小。在这种情况下,如果 w 变小,就可以得到一个更

小的 Loss,即变化方向为 -∂Loss/∂w。

∂Loss/∂w<0,表示 w 的变化方向与 Loss 相反。当 w 变大时,可以得到一个更小的 Loss,

即变化方向仍为 -∂Loss/∂w(因为 ∂Loss/∂w<0,所以 -∂Loss/∂w>0)。

∂Loss/∂w=0,表示 w 的变化不会对 Loss 产生影响。在这种情况下,调整 w 是没有任何效

果的,可以认为 w 学习完毕。

学习步骤如图2-4所示。

图2-4

通过以上分析,我们可以得到一个朴素的结论:如果要得到一个更小的 Loss,就需要先随机初始化 w,再让 w 朝一个特定的方向变化。w 的变化方式如下。

w→w-μ ∂Loss/∂w

同理,w_0 的变化方式如下。

w_0→w_0-μ ∂Loss/(∂w_0 )

其中

∂Loss/(∂w_0 )=1/N ∑_(i=1)^N▒〖2(wx_((i))+w_0-y_((i)))〗

μ 是一个 (0,1) 之间的常数,用于控制 w 的变化幅度,避免因 w 变化过大而造成震荡。μ 对学习过程的具体影响,会在本节的结尾进行详细分析。

通过以上分析可以发现,通过导数 ∂Loss/(∂w_0 ) 和 ∂Loss/∂w 分别不断更新 w_0 和 w,Loss 会变得越

来越小。

上述分析过程也可以推广到多维输入。此时,有线性回归

y_((i))^'=w^T x_((i))+w_0 (i=1,2,⋯,n)

x_((i)) 为输入向量,y_((i))^' 为根据 x_((i)) 得到的估计值,y_i 为第 i 个数据的真实值,w 和 x_((i)) 都是

m 维的列向量。损失函数对参数 w 的导数为

∂Loss/∂w=1/N ∑_(i=1)^N▒〖2(w^T x_((i))+w_0-y_((i)))x_((i)) 〗

显然,∂Loss/∂w 也是一个 m 维的列向量。多元函数在某个点的梯度,就是对每个自变量求偏导

并将结果组成一个向量。

同理,可以求出

∂Loss/(∂w_0 )=1/N ∑_(i=1)^N▒〖2(w^T x_((i))+w_0-y_((i)))〗

综上所述,线性回归参数 w 和 w_0 的学习方法,具体如下。

 随机初始化 w 和 w_0,表示为 w(0) 和 w_0 (0)。此时,迭代次数 t=0。

 求当前点 ∂Loss/∂w 和 ∂Loss/(∂w_0 ),公式如下。

∂Loss/∂w(t) =1/N ∑_(i=1)^N▒〖2(〖w(t)〗^T x_((i) )+w_0 (t)-y_((i) ) ) x_((i) ) 〗

∂Loss/(∂w_0 (t))=1/N ∑_(i=1)^N▒〖2(〖w(t)〗^T x_((i) )+w_0 (t)-y_((i) ) ) 〗

 对 w 和 w_0 进行更新,表示为 w(t+1) 和 w_0 (t+1),公式如下。

w(t+1)=w(t)-μ ∂Loss/∂w(t)

w_0 (t+1)=w_0 (t)-μ ∂Loss/(∂w_0 (t))

 当 t 等于指定的迭代次数或 Loss 的值足够小时,迭代结束。此时得到的 w(t) 和 w_0 (t) 就是学习完成后的参数 w 和 w_0。如果迭代不满足结束条件(t=t+1),则返回第步,进行下一轮学习。

在这里,∂Loss/∂w 就是梯度。w 通过梯度使 Loss 的值不断减小。因此,上述迭代过程也称为梯度下降法。

值得注意的是,梯度 ∂Loss/(∂w(t)) 仅提供了 w 移动的方向,并未提供其移动的距离。如图2-5

所示,在使用梯度下降法时,如果某个点的 ∂Loss/(∂w(t)) 很大,那么在更新参数时可能会出现 w 的

移动幅度过大的问题——在“谷底”两侧不断振荡——矫枉过正。因此,需要对 w 的变化幅度进行限制。

这就是学习率 μ 的作用——防止梯度过大引发的震荡。但是,μ 也不宜过小,因为过小的 μ 会使学习时间延长,如图2-6所示。

图2-5

图2-6

由此可见,合适的学习率对能否快速学习到理想的 w 有重要的影响。

2.3 训练集和测试集

在机器学习中有两个基础的术语——训练集和测试集,它们分别用于模型的训练阶段和训练后的效果评估阶段。

我们在处理一批数据时,一般将数据随机分成两份,训练集占90%,测试集占10%。从概率的角度看,训练集和测试集的数据是从同一概率分布上独立采样得到的。在使用梯度下降法时,用训练集的数据进行训练,测试集不参与训练。训练完成后,我们通常更关心模型在未观测数据上的效果,所以要使用测试集的数据进行效果评测。这样做的好处是能够检测出模型的真实效果,从而避免在训练集上拟合得非常好、Loss 降得很低,但上线后在真实环境中(大量的输入是训练集中并未出现的)对数据模型的拟合效果比较差的问题。

Loss 在训练集和测试集上的差异,如图2-7所示。

图2-7

同一个模型,为什么会在训练集和测试集上效果差异很大呢?我们采集的数据,往往会在一定的规律上添加一些噪声。例如,真实数据由下式产生。

y=4x+3+ε

y=4x+3 是数据产生的规律。ε 为随机噪声,一般符合均值为0的正态分布,即 ε~N(0,σ^2)。噪声通常是由测量误差、一些随机行为或极端特例导致的。噪声这种纯随机事件对机器学习来说是不可学习且不必学习的。

模型在学习时,希望能学到规律,即 y=4x+3,其中并不包含噪声 ε。但是,在训练

样本 〖{x_((i)),y_((i))}〗_(i=1)^N 中,y_((i)) 是包含噪声 ε_((i)) 的(噪声是随机值,可大可小,因此无法剔

除),这就要求模型学习阶段的 Loss 要降低(学会规律),但不能降得过低(把噪声也学会了)。

在训练时 Loss 的值已经降得很低了,但在真实环境中面对大量新数据时仍表现不佳,这种现象称为过拟合(Overfitting),即泛化能力差。产生过拟合的一个原因是模型不仅拟合了规律,还拟合了噪声,另一个原因是真实数据的分布很广,但训练样本过少,无法覆盖全部情况。例如,模型在预测“年龄—消费能力”时,训练样本的数据集中在40岁以下的人群,而在真实场景中出现了50岁以上的人群,必然无法正确进行预测。

解决过拟合问题有多种方法,最直接的方法就是增加训练样本的数量,使模型在训练阶

段实现训练噪声抵消(随机变量 1/N ∑_(i=1)^N▒ε_((i)) 的方差趋近于0,且 N 越大越接近0)。这样,

模型学到噪声的可能性就会大大降低。增加训练样本的数量,也能使模型在学习阶段考虑更多的情况——见多识广。还有一种方法是提前终止学习,只要使 Loss 下降到一定程度即可,无须下降到极小值,以免将噪声拟合进来。

通过以上分析,我们可以得到模型效果的两个评价标准。

降低训练集上的误差,即在训练过程中降低 Loss。

缩小训练误差和测试误差之间的差距。

如果以上第一点没有被满足,那么训练集上的误差将会很大,这就是欠拟合。如果以上第二点没有被满足,就是过拟合。

除了训练集和测试集,还有一个非必需的有效集。有效集是指在训练阶段使用的测试集。例如,有三个学习率 μ_1、μ_2、μ_3,我们并不知道哪一个是最好的。在训练阶段,分别用学习率 μ_1、μ_2、μ_3 做实验,每组实验用相同的训练样本进行模型训练,然后用有效集对这三个模型进行评测,将效果最好的模型作为最终结果。有效集常用于在训练阶段寻找合适的超参数。超参数一般是指梯度无法表达的参数,例如学习率。

打个比方:在准备考试时,训练集相当于平时做的练习题,有效集相当于模拟试卷中的题目(用来找寻最佳学习方法),测试集相当于真实的考试题目。当出现过拟合时,训练集的效果好,测试集的效果差,相当于把训练集中的数据都记住了,但没有真正学到东西,考试时题目稍有变化就抓瞎了。

2.4 多项式回归

在使用模型时,其实隐含了一个潜在要求:模型能力和数据分布相匹配。只有在模型能力和数据分布相匹配时,模型才能得到较好的效果。用机器学习术语来描述,就是归纳偏置(Inductive Bias),即算法对所要学习的问题做出的一些假设。

归纳偏置也称为先验(Priors)。在使用线性回归时,默认数据和模型其实是匹配的,即数据尽量在一条直线(在高维空间中对应的是平面)上。但是,如果数据本身不满足模型的归纳偏置,那么在线性回归时数据点将不在一条直线上,如图2-8所示。

图2-8

这时,如果仍然拿线性回归模型去拟合数据,那么无论如何训练,效果都是非常差的。其原因在于,如果模型和数据不匹配,就不可能找出一条直线来很好地拟合抛物线。

我们可以改变模型,使其能尽可能贴近真实数据。例如,可以对线性回归进行扩展,增加一个二次项,使其变为如下抛物线模型。

y^'=w_2 x^2+w_1 x+w_0

这个模型对应的是一条抛物线,该抛物线与数据的分布相吻合,因此可以得到不错的效果。

我们可以从以下两个角度看待这个新模型。

如果把 x^2 和 x 看成两个独立的变量,那么该模型仍然是线性回归,只不过输入有两个维度(x^2 和 x)。

如果把 x 看成一个变量,那么模型就是一个抛物线回归模型(非线性多项式回归模型)。

如果点的分布更加复杂,就可以通过提高拟合函数的阶次来取得更好的效果,例如引入 x^3、x^4 等。阶次越高,函数在训练集上的效果就越好,能够拟合的曲线的种类就越多,模型的复杂度就越高、容量就越大。这里的容量是指模型的潜在能力,即能够拟合的曲线的种类有多少。

当然,模型的复杂度不能一味提高(避免发生过拟合)。一方面,高阶次函数的引入会带来输入的轻微变化,导致输出迅速增大,引起震荡。另一方面,当函数的阶次过高时,拟合曲线可能会经过训练样本中所有的点,同时把噪声学到了,导致过拟合。例如,使用线性回归拟合一条二次曲线:在只采用一次项时,会发生欠拟合,在训练集上 Loss 的值过大;如果采用二次项,就可以拟合得刚好(这正是我们需要的);如果继续增加高阶项,如增加到9阶,就会发生严重过的过拟合(尽管曲线会将所有训练数据完美匹配,但曲线已不是二阶抛物线了),在测试集上的效果必然很差。

上述分析,如图2-9所示。

图2-9

因此,不仅在线性回归上,在任何模型的选择上,复杂度和容量的添加一定要适可而止,切忌画蛇添足。

在机器学习领域有一条“金科玉律”,即没有免费午餐定理(No Free Lunch Theorem)。没有免费午餐定理是由Wolpert和Macerday在最优化理论中提出的,它证明了:对基于迭代的最优化算法,不会存在某种算法对所有问题(在有限的搜索空间内)都有效的情况。如果一种算法对某些问题有效,那么它一定在另一些问题上比纯随机搜索算法的效果差。也就是说,任何算法都有自己的优势和劣势,不能脱离具体问题讨论算法的优劣,必须“具体问题具体分析”。没有免费午餐定理告诉我们:没有绝对好的模型,模型在一些问题上“好”的表现一定是以在另一些问题上“坏”的表现为代价的。

在上述例子中:如果数据天然是以线性分布的,那么线性回归的效果就比较好,其代价是在非线性分布的数据上欠拟合;如果数据本身是以多项式分布的,那么阶次合适的多项式回归就能很好地完成任务,其代价是在线性分布和低阶次数据上过拟合。

2.5 线性回归的高级技巧

2.5.1 特征敏感性研究

在一维线性回归中,x 是输入,y^' 是输出,模型为 y^'=wx+w_0。现在,将输入数据增加1维,使其变成 [x_1,x_2 ]^T,x_1 为原来的输入 x,x_2 为符合 N(0,σ^2) 的随机数,模型将变为 y^'=w_1 x_1+w_2 x_2+w_0。例如,我们希望通过模型预测一个人的退休金是多少,x_1 表示他的工龄,x_2 表示他的身高,可以看出,x_2 对预测结果毫无帮助,纯粹是一个随机变量。

通过实验可以发现,当训练的数据量足够大时,经过训练,w_2 将趋近于0。假如原来的学习结果为

y^'=400x+1000

那么维度扩增后的学习结果为

y^'=4〖00x〗_1+0.001x_2+1000

可以看出,x_2 对于曲线的拟合基本没有帮助——这符合我们的认知。这同时说明,线性回归具有对抗噪声的能力,即无关的随机输入不会对模型的效果产生影响。

值得注意的是:当样本量较小时,随机特征 x_2 很难相互抵消(这会造成负面影响)。例如,只有A、B两个样本,恰好“A_退休金>B_退休金”“A_身高<B_身高”,模型就会被误导,认为身高对收入有负面影响,为 x_2 分配小于0的权重 w_2。

换一个角度看,如果某维度特征所对应的 w 在数值上接近0,就可以从侧面反映出该特征不是特别重要,或者和其他特征放在一起时出现了冗余现象,即不同的特征代表了相同的信息,那么,该特征可以被剔除,从而降低运算量。

接下来我们讨论特征冗余现象。假设有一个2维特征,其第二维特征不是随机的,而是通过简单复制第一维特征得到的,即输入特征为 [x_1,x_2 ]^T,x_1 和 x_2 均为原有特征,x_1=x_2。可以看出,虽然增加了1维特征,但没有增加信息量,x_1 和 x_2 仍是相互冗余的。

假如原来的学习结果为

y^'=400x+1000

那么维度扩增后的学习结果为

y^'=ax_1+bx_2+1000

通过实验可以发现,如果满足 a+b=400 这一约束条件,那么 a 和 b 可以是任意值。特别地,如果在训练时使用L2正则(将在3.4节详细介绍),那么 a=b=200。由此可知,如果特征出现了冗余现象,那么权重将会分散到各个冗余维度上。因此,我们不能简单地通过权重来衡量特征的重要性。特征所对应的权重低,虽然可能是该特征不重要造成的,但不能排除其他维度的特征和它形成冗余现象从而造成权重被稀释的情况。

由上面两个例子可知:如果单纯增加噪声,那么在样本量足够时,虽然不会对最终的学习结果产生很大的影响,但会增加运算量;如果样本量不足,那么为特征增加噪声会对模型产生误导。如果发生了特征冗余,那么不仅无法提升最终的学习效果,还会稀释权重。

上面两个例子有哪些应用场景呢?首先需要说明的是,在这两个例子中,冗余现象(完全复制)和噪声(完全随机)的假设过于极端。在真实场景中,除非刻意,这样的情况是不太可能出现的。但是,一定程度的冗余现象和噪声经常会出现。例如,婚介场景使用的特征为月收入、房产(房屋数量和面积)、汽车品牌、天气。月收入、房产、汽车之间存在一定程度的冗余现象,但不是完全冗余的,例如汽车品牌除了和月收入有关,还和个人喜好及品味相关。而天气对相亲成功与否来说是无关因素,因此作为噪声出现。

在企业里做项目,涉及的特征往往会达到上千维甚至更多。大量特征难免相互冗余,或者有些特征因为对任务的帮助不大而被当作噪声。因此,弄清楚冗余现象和噪声这两个问题,对特征提取和模型的可解释性都会有帮助。

2.5.2 损失函数的选择

一般来说,线性回归的损失函数为MSE。MSE用于衡量预测值和真实值之间的差别,并且是恒大于0的。可能有读者会问:是否有其他形式呢?当然有。例如,将MSE换成平均绝对误差(Mean Absolute Error,MAE),损失函数的公式如下。

Loss=1/N ∑_(i=1)^N▒Loss_((i)) =1/N ∑_(i=1)^N▒| y_((i))^'-y_((i)) |

上式也能用来衡量实际值 y_i 和预测值 y_i^' 之间的差异,并能保证值不小于0。但是,在真实场景中,几乎不会将绝对值函数作为损失函数,原因大体如下。

在模型求解时一般采用梯度下降法,这就要求损失函数的导数是存在的,如果导数不

存在,后续的步骤就无从谈起。但是,由于 Loss_((i))=|y_((i))^'-y_((i)) |,在 y_((i))^'=y_((i)) 这个点

导数不存在,因此,使用梯度下降法会遇到障碍。在机器学习中,对于导数不存在的点,一般可以根据经验为其设置一个导数,从而在一定程度上解决这个问题。

然而,更麻烦的是下面这一点。

当 y_((i))^'≠y_((i)),Loss 分别为MSE和MAE时,(∂Loss_((i)))/(∂y_((i))^' ) 的函数图像如图2-10所示。可以发现,在将MSE作为损失函数时,对距离目标点 y_((i)) 较远的数据点的导数 〖∂Loss〗_((i))/(∂y_((i))^' ) 较大,所以更新幅度 〖∂Loss〗_((i))/∂w=〖∂Loss〗_((i))/(∂y_((i))^' ) 〖∂y〗_((i))/∂w 较大。而在将MAE作为损失函数时,无论误差是多少,更新“力度”都是一致的,即 〖∂Loss〗_((i))/(∂y_((i))^' )=1 或 〖∂Loss〗_((i))/(∂y_((i))^' )=-1。因此,MSE更智能,更看重误差较大的数据点。

图2-10

我们还可以从最大似然估计的角度来论证将MSE作为损失函数的合理性。正如前面分析的,假设数据的产生过程如下。

y_((i))=w^T x_((i))+w_0+ε

在上式中,ε 为随机变量,满足0均值正态分布,即

P(ε=e)=1/(σ√2π) exp^(-e^2/(2σ^2 ))

因此,y_((i)) 也是一个随机变量,符合正态分布,即当 x_((i)) 已知时,满足

P(y=y_((i)) |x_((i)) )=1/(σ√2π) exp^(-〖(y_((i) )-w^T x_((i) )-w_0)〗^2/(2σ^2 ))

机器学习的目标是从数据中找到最优的 w 和 w_0。量化最优除了可以让预测的 y^' 和真

实的 y 的差别最小,还可以从统计学的角度,通过调整参数使训练样本 〖{x_((i)),y_((i))}〗_(i=1)^N 出现

的概率最大,即使真实的 y 所对应的似然函数最大。因此,对于所有训练样本,似然函数为

likehood=∏_(i=1)^N▒〖P(y=y_((i) ) |x_((i) ) )=∏_(i=1)^N▒〖1/(σ√2π) exp^(-〖(y_((i) )-w^T x_((i) )-w_0)〗^2/(2σ^2 )) 〗〗

为了运算方便,我们对似然函数取对数,使似然函数变为

likehood=log⁡[∏_(i=1)^N▒〖1/(σ√2π) e^(-〖(y_((i) )-w^T x_((i) )-w_0)〗^2/(2σ^2 )) 〗]=∑_(i=1)^N▒[-〖(y_((i) )-w^T x_((i) )-w_0)〗^2/(2σ^2 )-logσ√2π]

模型学习的目标就是最大化似然函数 likehood,即已经发生的事实,因此,其对应的概率应该最大。

max⁡(likehood) 即最小化 min⁡(-likehood),因此,优化目标为最小化下式。

∑_(i=1)^N▒[〖(y_((i) )-w^T x_((i) )-w_0)〗^2/(2σ^2 )+logσ√2π]

由于在似然函数中,只有 w 和 w_0 为变量是我们希望求解的,其他无关项均可去除,所以,优化目标变为最小化下式。

∑_(i=1)^N▒〖〖(y_((i) )-w^T x_((i) )-w_0)〗^2=∑_(i=1)^N▒〖(y_((i) )-y_((i))^')〗^2 〗

可以发现,上式就是前面所讲的MSE。可见,当数据符合正态分布时,使用MSE优化线性回归模型等价于最大似然估计。


第三章 逻辑回归

线性回归是指特征 x 通过模型运算得到预测值 y^'。在理论上,y^' 的取值范围是 (-∞,+∞),即 y^' 可以是任何值,例如销量、价格、负债等。

在回归任务中,有一类特殊场景值得注意,就是预测概率。概率可用于解决分类问题。在这类场景中,模型的输出是输入样本属于某个类别的概率。例如,输入的是用户消费习惯和商品特征等信息,输出的概率 p 表示用户是否会购买商品。再如,输入的是一幅图片,输出的概率 p 表示该图片是否包含人脸。

我们知道,概率的取值范围是 [0,1],因此,模型输出的范围要在此区间之内,在此区间以外的预测是没有实际意义的。预测概率是一个非常普遍的场景,如图3-1所示。分类问题大都属于预测概率。例如,输入一幅图片,模型能够计算出图片中包含一只猫、一条狗或二者都不是的概率,从而完成分类。

图3-1

在图3-1中,P_1、P_2、P_3 分别表示模型判断输入 x 属于猫、狗、二者都不是的概率。根据概率的定义和性质,有 P_1∈[0,1]、P_2∈[0,1]、P_3∈[0,1] 且 P_1+P_2+P_3=1。

分类问题的特殊之处在于,其输出要有明确的取值范围 [0,1] 和物理含义(概率),这一点和回归任务(值域为 (-∞,+∞))不尽相同。由于分类问题在人工智能场景中有丰富的应用,因此得到了专门的处理和优化。

在分类问题中,二分类是一个简单但应用广泛的场景。假设有P和N两个类别,y 表示P类的概率,1-y 表示N类的概率,而在训练样本中,样本的类别都是客观存在的,不存在随机性,因此 y=1 或 y=0。值得注意的是,二分类的两个类别必须完全互斥并包含所有情况。例如,二分类的两个类别可以是“狗”和“非狗”,但不可以是“狗”和“猫”。

在二分类场景中,模型只需要一个输出 y^'。如果 y^' 表示输入 x 属于P类的概率,那么 x 属于N类的概率自然就是 1-y^'。模型的输出 y^'∈[0,1] 不再局限于一个二值选择,可以是一个属于0~1的连续值,以表示模型判断的概率结果。

在机器学习数十年的发展过程中,出现了很多分类模型,其中就包括逻辑回归。逻辑回归作为二分类问题的一个经典模型,是神经网络学习的基础,因此,我们有必要对其进行系统的学习和研究。

3.1 逻辑回归的基本原理

通过对第2章的阅读,相信读者已经对线性回归有所了解。当训练完成时,可以得到一个用于预测的函数

y^'=w^T x+w_0

通过该函数,可以对输入进行输出值的计算。

线性回归和分类任务相悖的地方在于,线性回归输出的值域为 (-∞,+∞),而这超出了概率的取值范围 [0,1]。

不过,问题还是有办法解决的。例如,对输出进行改造,对线性回归的输出进行判断。如果 w^T x+w_0 ≥ 0,就认为 x 属于P类的概率为 y^'=1;如果 w^T x+w_0<0,就认为 x 属于P类的概率为 y^'=0。改造后的模型函数如下。

函数图像如图3-2所示。

图3-2

上述模型虽然能够满足分类的需求,但仍存在一些问题,其中,以下两个比较重要。

很明显,这种曲线的缺点是判断太“硬”、太绝对、非黑即白,无法体现输入 x 与两个类别的相似程度。在很多应用场景中,用户都倾向于得到一个能够反映程度的值,而非简单的1或0。例如,属于P类的概率为0.75,属于N类的概率为0.25,这种结果是无法通过上述模型得到的。事实上,所有的分类都属于“抽刀断水”,并不存在绝对性。

上述模型在 d=0 这一点的导数 (∂y^')/∂d 不存在,当 d≠0 时导数 (∂y^')/∂d=0。现在的主流学习方法仍然是梯度下降法,当导数不存在或为0时,w 无法得到更新,而这会导致学习失效。

既然发现了问题,就要解决问题。人工智能先驱们经过努力,找到了逻辑函数(Logistics Function),如下式所示。

f(d)=1/(1+e^(-d) )

逻辑函数的图像,如图3-3所示。

图3-3

逻辑回归的导数为 ∂f/∂d=f(d)(1-f(d)),其图像如图3-4所示。

图3-4

与之前过“硬”的方案相比,这个函数的特点如下。

值域为 [0,1],不仅满足了概率值域的约束,也可以输出0.75、0.6这类相对比较“软”的概率值。

处处都有导数且都不为0,保证了梯度下降法的可操作性。

因此,我们用逻辑函数代替条件判断,将线性回归改造成分类模型,公式如下。

其中

上述模型就是逻辑回归(Logistic Regression,LR),即加载逻辑函数的线性回归。在这里,d 实际上是一个线性回归,输出概率 y^' 随着 d 的增大而增大且趋近于1;反之,y^' 随着 d 的减小而减小且趋近于0。

在预测阶段,我们可以设一个阈值 θ(通常可以取0.5)。当模型输出 y^'>θ 时,认为输入的样本 x 属于P类;当模型输出 y^'<θ 时,认为输入的样本 x 属于N类;当模型输出 y^'=θ 时,认为输入的样本 x 位于两个类别的临界点。

假设有一种自动诊疗仪,输入 x 为人的一些生理指标,用逻辑回归判断就诊者是否患有癌症。如果诊疗仪判断就诊者患有癌症,则由医生对病人进行会诊,否则就诊者可以结束就诊。模型输出P类表示患有癌症,N类表示未患癌症,这就是一个典型的二分类问题。在这个场景中,宁可让模型错误地把一个健康的人判断为癌症患者(再由医生做进一步检查和判断),也不要出现漏判——因为在这两个类别上,错分(“假阴”和“假阳”)的代价是不一样的。这时可以适当降低阈值 θ,例如 θ=0.3。这样,模型输出为 y^'=0.4、y^'=0.35 的就诊者就会被诊疗仪判断为患有癌症,由医生进行进一步的会诊,以免遗漏。

当 θ=0.5 时,表示对P类和N类没有特殊的偏好。当 θ<0.5 时,反映了对于分类结果为P类的“宁错勿漏”。当 θ>0.5 时,判断输入 x 为P类是更加严格的,表示“宁缺毋滥”。需要强调的是,模型输出 y^' 是一个客观数字,但阈值是使用者主观设定的。

在一些场景中,阈值 θ 也不是必需的。例如,在推荐系统中,我们用逻辑回归预测用户是否会对商品进行点击。假设有100件候选商品,在一个页面上只能展示10件给用户,此时需要使用逻辑回归分别对这100件商品进行预测打分,然后将得分排在前10位的商品展示给用户。这些分数可能整体偏低,也就是“矮子里拔将军”,或者整体偏高,即“优中选优”。

接下来,我们看一个更有意思的例子。如果输入是2维的,即 x=〖[x_1,x_2]〗^T,逻辑回归模型如下。

y^'=1/(1+e^(-d) )=1/(1+e^(-d) )

d=w_1 x_1+w_2 x_2+w_0

此时,可以在坐标系中画出数据点,其中横坐标为 x_1,纵坐标为 x_2,如图3-5所示。

图3-5

当 d=0 时,y^'=0.5。当 θ=0.5 时,w_1 x_1+w_2 x_2+w_0=0 对应于坐标系中的一条直线,这条直线称为分界线。

如果数据点(椭圆形点)位于分界线左上方区域,则将这些数据点代入直线方程,可得

d=w_1 x_1+w_2 x_2+w_0>0

由此可以推导出 y^'>0.5>θ,意味着这些数据点的分类结果都为P类。

同理,当数据点位于分界线右下方区域时,d<0,即 y^'<0.5<θ,这些数据点的分类结果都为N类。

进一步,当 d>0 时,d=10 和 d=100 的区别在于数据点与分界线距离的远近不同(d=10 时离分界线近),体现在分类结果为P类的概率和 d 的关系上,如图3-6所示。d<0 时的情况同理。

图3-6

结合图3-5和图3-6可以看出,数据点离分界线越远,它所对应的概率值就越大,分类结果就越可信。

在本节的最后,我们一起讨论一个多分类问题。在实际应用中有很多分类场景。例如,我们要预测一首歌的类型(例如摇滚乐、流行乐、爵士乐等),该怎么使用逻辑回归呢?对

多分类问题,可以使用多个分类器 h_1,h_2,⋯,h_k,k 为类别数量。其中,h_j 表示二分类模型

的逻辑回归模型,用于判断样本 x 属于第 j 类的概率。在训练阶段,第 j 类的样本属于P类,其他样本都属于N类。这种多分类方法称为OvR(One-vs-Rest)。样本 x 的类别为

(arg max)┬j⁡〖h_j (x)〗

也就是说,取 k 个分类模型中输出值最大的模型所对应的类别作为多分类结果。

因为在使用OvR进行多分类时不需要类别互斥,所以不必满足 ∑_(j=1)^k▒〖h_j (x)=1〗。假设一

首歌可以同时属于摇滚乐和流行乐,那么对应的 h_流行乐 和 h_摇滚乐 的输出值都比较大。因此,

OvR也可用于多标签/多类别问题,即“一个样本可以属于多个分类”。此时,有 Class(x)=

{j|h_j (x)>θ_j},θ_j 是为各类别独立设置的阈值。

所谓分类,其实都是人主观设定的标准,不存在客观的分类标准,这就是所谓丑小鸭定理(Ugly Duckling Theorem)。丑小鸭定理是1969年由渡边慧提出的。丑小鸭是白天鹅的幼雏。尽管在常人的眼里,丑小鸭和白天鹅的区别大于不同白天鹅之间的区别,但在遗传学家的眼里,丑小鸭与其父亲或母亲的差别小于其父母之间的差别。正因为没有客观的分类标准,所以分类模型需要通过标注数据来明确类别的种类。标注数据的不同会导致模型不同的分类结果。

假设:在第一个场景中,需要区分一种生物是否为水产品,那么此时螃蟹和鱼属于同一类别;在第二个场景中,需要区分一种生物是否为脊椎动物,那么此时螃蟹和鱼就不属于同一类别了。这种类别信息都是通过数据标注告诉模型的。如果需要模型很好地区分类别,那么提取的特征也需要进行相应的修改。在第一个场景中,提取的特征为鱼和螃蟹的共性,例如水生、蛋白质含量高;在第二个场景中,应提取有无脊柱之类的特征。

3.2 交叉熵和KL距离

3.2.1 KL距离

在3.1节中,我们分析了将逻辑回归应用在分类任务中的一些性质和优点。一个问题随之出现了:如何学习参数 W?逻辑回归的参数求解仍然采用线性回归中使用的梯度下降法,但使用的损失函数不是MSE。

在线性回归中,误差函数MSE其实是表示预测值与真实值之间的欧氏距离。然而,欧氏距离并不适合用来度量概率之间的差异(本章最后会详细讨论这个问题)。在概率计算中,一般采用KL(Kullback-Leibler)距离来度量不同概率分布之间的差异。在计算离散概率时,KL距离的计算公式如下。

对于连续型概率,可以把 Σ 替换成 ∫,把 P 和 Q 替换成概率密度。

如果概率分布 P 和 Q 处处相等,那么 P 和 Q 这两个概率分布就是形同的,即对于

所有 y∈Y 都有 P(y)=Q(y),也就是说 log (P(y))/(Q(y))=log1=0,此时KL距离为0。反之,

概率分布的差异越大,KL距离就越大。值得注意的是,与欧氏距离满足交换性不同,KL距离并不具备交换性,即

KL(P,Q)≠KL(Q,P)

因此,严格来说,KL距离不能完全满足距离条件。

逻辑回归一般用于解决二分类问题,此时 y∈{0,1}。先看看训练样本 x_((i)),y_((i)),y_((i)) 表示样本属于P类的概率,1-y_((i)) 表示样本属于N类的概率。因为训练样本的数据是一个确定事件,所以 y_((i))=1 或 y_((i))=10。y_((i))^' 表示模型预测为P类的概率,〖1-y〗_((i))^' 表示模型预测为N类的概率。

因为只有两个类别,所以将 ∑_(y∈{0,1})^ ▒〖y_((i)) log y_((i))/(y_((i))^' )〗 展开成两项。此时,真实的概率分布和

模型输出的概率分布之间的差异可以用KL距离表示成

KL(y_((i)),y_((i))^' )=y_((i)) log y_((i))/(y_((i))^' )+(1-y_((i)))log 〖1-y〗_((i))/(〖1-y〗_((i))^' )

在本书中,为了求导方便,采用以 e 为底的对数函数,即 logy=lny。

使用KL距离的目的是量化模型输出概率和真实概率之间的差异,并通过改变参数 w 使KL距离变小,因此,我们只需要关注与参数 w 有关的项。

对 y_((i)) log y_((i))/(y_((i))^' ) 进行变换,公式如下。

y_((i)) log y_((i))/(y_((i))^' )=y_((i)) logy_((i))-y_((i)) logy_((i))^'

上式的第一项 y_((i)) logy_((i)) 中的 y_((i)) 表示输入的真实类别,它是客观存在的,和参数 w 没有关系,也就是说,改变 w 不会对 y_((i)) 产生任何影响。因此,可以忽略 y_((i)) logy_((i)),即

y_((i)) log y_((i))/(y_((i))^' )=y_((i)) logy_((i))-y_((i)) logy_((i))^'⇒-y_((i)) logy_((i))^'

同理,可以忽略 〖(1-y〗_((i)))log〖(1-y〗_((i))),即

(1-y_((i) ) )log 〖1-y〗_((i) )/(〖1-y〗_((i))^' )⇒-(1-y_((i)))log(1-y_((i))^')

因此,在逻辑回归中,对于训练样本 x_((i)),y_((i)),KL距离的计算公式可以化简为

Loss_((i))=KL(y_((i)),y_((i))^' )=-y_((i)) logy_((i))^'-(1-y_((i)))log(1-y_((i))^')

其中,y_((i))^' 为逻辑回归模型的输出

y_((i))^'=f(x_((i)) )=1/(1+e^(-(w^T x_((i))+w_0)) )

值得注意的是,Loss_((i)) 虽然是由两项组成的,但因为 y_((i)) 只能取1或0,所以对一个具体的训练样本来说,这两项有且仅有一项不为0。

当真实类别 y_((i))=1 时,Loss_((i))=-logy_((i))^'。因此,最小化 Loss_((i)) 相当于最大化 y_((i))^',即模型的输出越接近1,Loss_((i)) 就越小。

当真实类别 y_((i))=0 时,Loss_((i))=-log⁡(1-y_((i))^')。因此,最小化 Loss_((i)) 相当于最小化 y_((i))^',即模型的输出越接近0越好。

上面的分析符合我们的认知和期望。需要注意的是,由 y_((i))^' 的计算公式可知,y_((i))^' 只能无限接近1或0(但无法达到),因此 Loss_((i)) 没有极小值。这一点和线性回归中使用的MSE不同。当考虑所有训练样本 〖{x_((i) ),y_((i))}〗_(i=1)^N 时,损失函数为所有样本上的平均误差

Loss=1/N ∑_(i=1)^N▒Loss_((i)) =1/N ∑_(i=1)^N▒〖-y_((i)) logy_((i))^'-(1-y_((i)))log(1-y_((i))^')〗Loss=1/N ∑_(i=1)^N▒Loss_((i)) =1/N ∑_(i=1)^N▒〖-y_((i)) logy_((i))^'-(1-y_((i)))log(1-y_((i))^')〗

需要注意的是,尽管 Loss_((i)) 没有极小值,但 Loss 可能有极小值。

3.2.2 梯度下降法

在3.2.1节中,我们使用KL距离作为损失函数。损失函数确定后,仍然使用梯度下降法求解参数 w。因为逻辑回归就是在线性回归上套了一层逻辑函数,所以逻辑回归是一个复合函数。对复合函数求导,可以采用链式法则。

先看只有一个样本 x_((i)),y_((i)) 的情况,模型预测的结果为

y_((i))^'=1/(1+e^(-(w^T x+w_0)) )

根据链式法则,(∂Loss_((i)))/∂w 可以有如下等价变换。

(∂Loss_((i)))/∂w=(∂Loss_((i)))/(∂y_((i))^' )∙(∂y_((i))^')/∂d∙∂d/∂w

其中

(∂Loss_((i) ))/(∂y_((i))^' )=-y_((i) )/(y_((i))^' )+(1-y_((i) ))/(1-y_((i))^' )

(∂y_((i))^')/∂d=y_((i))^' (1-y_((i))^' )

∂d/∂w=x_((i))

将上述三式代入并化简,可得

(∂Loss_((i)))/∂w=(y_((i))^'-y_((i)))x_((i))

同理,可得

(∂Loss_((i)))/(∂w_0 )=(y_((i))^'-y_((i)))

考虑所有训练样本 〖{x_((i) ),y_((i) )}〗_(i=1)^N,有

∂Loss/∂w=1/N ∑_(i=1)^N▒(∂Loss_((i) ))/∂w=1/N ∑_(i=1)^N▒〖(y_((i))^'-y_((i) ) ) x_((i) ) 〗

∂Loss/(∂w_0 )=1/N ∑_(i=1)^N▒(∂Loss_((i)))/(∂w_0 )=1/N ∑_(i=1)^N▒〖(y_((i))^'-y_((i)))〗

和线性回归一样,我们在使用梯度下降法求解 w 和 w_0 时,可以通过以下步骤进行迭代学习。

 随机初始化 w 和 w_0,记为 w(0) 和 w_0 (0)。此时 t=0(t 表示迭代次数)。

 求当前点的梯度,公式如下。

∂Loss/∂w(t) =1/N ∑_(i=1)^N▒〖(y_((i))^'-y_((i) ) ) x_((i) ) 〗

∂Loss/(∂w_0 (t))=1/N ∑_(i=1)^N▒〖(y_((i))^'-y_((i)))〗

 更新参数,公式如下。

w(t+1)=w(t)-μ ∂Loss/∂w(t)

w_0 (t+1)=w_0 (t)-μ ∂Loss/(∂w_0 (t))

当 t 等于指定迭代次数或 Loss 足够小时,迭代结束,此时得到的 w 和 w_0 就是学习后的参数。如果迭代不满足结束条件(t=t+1),则返回第步,进行下一轮学习。

与线性回归的学习步骤相比,除了第步求导的形式不一样,其他都是一样的。这就是梯度下降法的好处——相当于提出了一个学习框架,不同类型的模型只需要求出自己相应的梯度即可,其他步骤都可以复用。

3.2.3 上采样和下采样

在真实场景中,训练数据属于P类和N类的样本数量往往是不平衡的,这种情况在企业中是常态。

例如,在做视频点击率预测(Click Through Rate,CTR)时,P类为用户点击,N类为用户不点击,输入 x 为用户和视频的一些基本信息(例如用户年龄、观看历史、视频类型、视频长度等),我们需要通过模型预测用户是否会对某个视频产生点击行为,将点击概率高(P类)的视频推送给用户。

这类问题一般会将以往的曝光点击日志作为训练样本。例如,分析昨天的日志,将曝光给用户但没有被点击的“用户—视频”划入N类,将曝光给用户并被点击的“用户—视频”划入P类。显然,大多数视频是不会被点击的。一般来说,推荐视频的用户点击率为15% 已经是很好的成绩了。因此,N类的样本数量远大于P类的样本数量,甚至可能达到P类样本100个、N类样本10000个的程度。如果用这些数据直接训练逻辑回归模型,则 Loss 大都由N类决定,因此 w 的更新受N类的影响较大。这样,w 的值会随属于N类的样本的变化而变化。最终,只要N类预测正确,就能得到一个很小的 Loss,而P类的数据正确与否影响很小。举个极端的例子,把所有样本都预测为N类,正确率仍然是 10000/10100=99%,但这种模型是没有用的,因为我们真正关心的P类全都被预测错了。在这种情况下训练出来的模型是有偏的,即模型只需要在N类上预测正确,就能使 Loss 降得很低,而在P类上是否预测正确只会对 Loss 产生微弱的影响(几乎没有影响)。

我们可以从另一个角度分析样本不平衡带来的影响。在训练阶段,每个样本 i 都会对参数 w 产生影响。为了使预测结果更准确(属于P类时无限接近1,属于N类时无限接近0),提升概率的方法就是让分类线远离自己。因此,每个点都会把分类线朝远离自己的方向推,如图3-7所示。

图3-7

此消彼长,最终的分类线就是在训练样本中达到平衡时的结果。但是,如果两个类别是不平衡的,例如N类的样本数量远大于P类的样本数量,那么在推直线时,N类的“力道”明显更大,直线会被推成如图3-8所示的样子。此时,训练出来的分类线不再位于中间,而是紧挨着训练样本中的P类。在这种情况下,训练出来的分类线对测试集中P类样本的预测结果基本上是错的,模型的泛化能力很差。

图3-8

综上所述,从训练阶段到预测阶段,样本不平衡都会给模型带来负面影响。要想平衡样本,即让P类和N类样本的数量差不多(平滑样本),有如下方法。

上采样技术:复制P类样本,最终使P类和N类样本的数量相同。

下采样技术:随机抽取部分N类样本作为训练样本,使N类和P类样本的数量大致相同。

上采样技术和下采样技术都能解决样本不平衡问题。在机器性能允许的情况下,一般使用上采样。与下采样相比,上采样能保证数据的多样性。使用下采样技术,需要抛弃一些属于N类的样本,数据的多样性将会降低。如果两个类别的训练样本的数量差异过大,则可以对数量较大的类别进行下采样,对数量较小的类别进行上采样,最终使两个类别样本的数量相同。当面对海量数据时(例如广告、推荐等场景),为了提高模型的训练速度,也经常会使用负采样。

3.3 线性不可分及其解决方案

如果数据点所对应的类别在平面(空间)上可以被一条直线分开,就称这些数据点是线性可分的。当数据点线性可分时,使用逻辑回归可以很好地对数据的类别进行预测。然而,在很多时候,数据点是线性不可分的,如图3-9所示。

图3-9

其中,三角形为一个类别,圆形为另一个类别。此时,无论怎么画直线,都无法把数据点准确地分开(读者可以自己尝试)。这类问题就是线性不可分问题。特别地,这类问题也称为异或问题,即 y=x_1 或 y=x_2。

逻辑回归的本质是在平面上画直线,从而对数据点进行分割。因此,我们很容易就能知道,逻辑回归是解决不了线性不可分问题的,这表现在训练时损失函数总是一个较大的值上(因为有错误的分类点)。

为了在线性不可分的情况下提高逻辑回归的准确率,可以对特征进行扩充。采用增加特

征维度方法,将原来的数据点 x=[■(x_1@x_2 )] 增加1维,变成 x=[■(x_1@x_2@x_3 )],其中 x_3=x_1 x_2。此

时,就可以用一个平面(二维空间中的直线相当于三维空间中的平面)将属于两个类别的数据点分开了。数据点在空间中的分布,如图3-10所示。

图3-10

模型如下式所示。

如果将 x_1 x_2 作为一个新特征,那么模型在三维空间中仍然是线性的逻辑回归模型。从另一个角度,可以将 x_1 x_2 看成一个二次项,模型相当于二维空间中的非线性模型,分割线为双曲线,如图3-11所示。

图3-11

在实际项目中,大多数问题都是线性不可分问题,因此,可以按照上面的方法实现大量的特征工程,提高特征的组合数量和维度,从而提升逻辑回归的分类能力。但是,在高维空间中,数据分布异常复杂且特例较多,即使实现了特征工程,也无法使数据完全线性可分。这也没关系,因为没有哪个模型能够做到100% 准确。如果特征维度过高而训练样本数量较少且模型在训练集上做到了100% 准确,模型反而容易发生过拟合,即在测试集上效果不佳。

前面分析过,单个样本 x_((i)) 的损失函数 Loss_((i)) 没有最小值。下面我们分析一下整体损

失函数 Loss=1/N ∑_(i=1)^N▒Loss_((i)) 。

如果数据点是线性可分的,那么每个数据点都会被正确地分类,此时 Loss 没有最小值。例如,成倍放大 w 可以使数据点的概率相应增大(P类的模型输出趋近于1,N类的模型输出趋近于0),从而使 Loss 的值相应减小,因此需要提前终止学习。如果数据本身是线性不可分的,就会出现数据点被错误预测的情况,此时放大 w 会减小正确的数据点 i 的 Loss_((i))、

增大错误的数据点 j 的 Loss_((j))——此消彼长——因此 Loss 有最小值。

3.4 L1正则和L2正则

如3.3节所述,逻辑回归的几何含义就是在平面上找到一条分类线 w^T x+w_0=0。值得注意的是,平面上的同一条直线其实可以由无数组方程来表示。例如,下面两个方程对应的是同一条直线。

0.6x_1+0.4x_2+0.2=0

6x_1+4x_2+2=0

那么,这两个对应于同一条直线的方程表达的意思是否有区别呢?如果有区别,哪个更好呢?

虽然以上两个方程在平面上对应于同一条直线,但是,将运算结果分别代入逻辑回归函数,得到的概率是不同的,即对应于不同的输出 y^'。将数据点 (1,1) 代入第一个方程,可得

y^'=1/(1+e^(-(0.6+0.4+0.2)) )≈0.77;将数据点 (1,1) 代入第二个方程,可得 y^'=1/(1+e^(-(6+4+2)) )≈1.000。

一般来说,我们不希望 w 过大。w 过大主要有以下三个缺点。

w 过大会放大 〖d=w〗^T x+w_0(d 趋近于非常大的正数或非常小的负数),这样逻辑回归的预测值将趋近于0或1,模型的输出结果过“硬”,区分度不高。y^' 挤在0或1附近,几乎没有区分度,从而难以选取分类阈值 θ。

w 过大会使逻辑回归进入饱和区域,即 ∂Loss/∂w≈0,从而使学习变得困难。

x 的任何轻微变化都会通过乘以 w 而放大。这对输出的影响很大,将导致模型不稳定。

为了在训练时避免 w 过大,可以在损失函数上添加一项以限制 w 的大小(这里的大小是指各维度的绝对值)。这样,损失函数就变为

Loss=1/N ∑_(i=1)^N▒[-y_((i) ) logy_((i))^'-(1-y_((i) ) ) log⁡(1-y_((i))^' ) ] +λRegularization(w)

λ 是一个超参数(λ>0),用于衡量模型对 w 大小的在意程度。λ 越大,模型越对 w 的减小越在意,对分类效果的重视程度越低。Regularization(w) 称为正则项,主要有两种计算方式,具体如下。

L1正则:Regularization(w)=|w|=|w_1 |+|w_2 |+⋯+|w_m |。

L2正则:Regularization(w)=‖w‖=√(w_1^2+w_2^2+⋯+w_m^2 )。

需要注意的是,无论是L1正则还是L2正则,都不包含 w_0 项,因为 w_0 项不会对输入 x 产生影响。

正则项展现了使用者的主观偏好,即希望 w 较小。使用者可通过 λ 控制主观偏好的“强度”。L1正则用于度量 w 到原点的曼哈顿距离,L2正则用于度量 w 到原点的欧氏距离,其中隐含了我们不希望 w 离坐标原点过远的期望。

虽然L1正则和L2正则的效果都是使 w 减小,但在细节上还是有一些不同的。这些不同会影响最终的学习结果。在使用L2正则时,倾向于对 w 的各个维度进行一定程度的缩减。在使用L1正则时,会优先将对分类影响最小的特征所对应的权重降为0。示例如下。

[0.3,0.2,0.4]^T □(→┴L1正则 ) [0.25,0,0.35]^T

[0.3,0.2,0.4]^T □(→┴L2正则 ) 〖[0.2,0.1,0.3]〗^T

如果使用L1正则,那么,当第 k 维所对应的 w_k=0 时,就相当于模型忽略了第 k 维的特征(〖w_k x〗_k≡0)。我们可以直接在输入中把第 k 维特征去掉。因为具有上述特性,所以L1正则具有特征选择功能。

还有一点值得注意:如果训练样本是线性可分的,则损失函数可以有如下变换。

以上变换根据类别把损失函数分为如下两类。

对于 Loss_(y_((i))=1),因为训练样本是线性可分的,所以 ∑_(y_((i))=1)^ ▒log⁡〖y_((i))^' 〗 中的 y_((i))^'>0.5,

即 w^T x_((i) )+w_0>0,w 的各个维度将按比例放大,使 w^T x_((i) )+w_0→+∞,即 y_((i))^'→

1,从而使 Loss_(y_((i))=0)→0。

对于 Loss_(y_((i) )=0),因为训练样本是线性可分的,所以 ∑_(y_((i) )=0)^ ▒log⁡(1-y_((i))^' ) 中的 (1-y_((i))^' )

>0.5,即 w^T x_((i))+w_0<0,w 的各个维度将按比例放大,使 w^T x_((i))+w_0→-∞,

即 (1-y_((i))^' )→1,从而使 Loss_(y_((i))=0)→0。

通过以上分析可以看出,当训练样本线性可分时,如果按比例将 w 的各个维度放大,那么 Loss 会不断减小并趋近于0(但永远不会为0)。如果此时训练模型,那么 w 会不停地按比例放大,直至各个维度趋近于无穷(+∞ 或 -∞)。从实践的角度看,除非设置了迭代次数或最小化 Loss 的目标值,否则学习将持续进行,且 w 会变得非常大(w 趋近于无穷将导致数值溢出),从而使模型变得非常“硬”。

为了克服上述问题,在常见的开源工具中,逻辑回归大都默认使用L2正则来防止 w 无限增大。

在使用线性回归时,也可以在损失函数中添加正则项。特别地,在使用L2正则训练线性回归模型时,线性回归就是我们常说的“岭回归”。在线性回归中,数据点沿抛物线分布(二次项)。正如前面分析的,使用9阶线性回归来拟合抛物线会发生严重的过拟合,此时,使用正则项即可解决过拟合问题。

使用L2正则,不同的 λ 对模型拟合的影响,如图3-12所示。

图3-12

过大的 λ 会使 w_2~w_9 都趋近于0,模型退化成一阶模型,从而发生欠拟合。

合适的 λ 会使 w_3~w_9 都趋近于0,模型为二阶模型,能很好地完成任务。

过小的 λ 会使正则力度过低,模型容易发生过拟合。

正则项除了具有防止参数 w 过大、模型过“硬”的作用,还具有防止模型过拟合的作用。虽然正则项实现起来相对简单,但其蕴含了贯穿机器学习的思想——泛化能力。当我们使用正则项时,优化目标变为

Object=Loss+λRegularization

Loss 是在全体训练样本上进行计算的,因此,降低 Loss 将使模型尽可能保证训练样本分类正确。Loss 的一般形式比较简单,例如MSE或KL距离,优化起来也相对容易。尽管训练数据包含噪声(极端特例、偶然事件、采集错误),但在模型训练阶段,损失函数会不断调整模型,使其尽可能满足训练数据的需要。当数据量比较大时,样本之间的噪声数据一般会彼此抵消,此时单纯地降低 Loss 并没有太大的问题。然而,当数据量不足时,模型就容易被噪声影响,从而产生过拟合。

例如,预测一个学生在高考中是否能考上一类本科院校(y=1)。以这个学生过往的成绩为训练样本,一共有四个特征,分别为 x_1=语文成绩、x_2=数学成绩、x_3=英语成绩、x_4=理综成绩。假设样本只有以下两个。

y=1,x=[120,131,123,220]^T

y=0,x=〖[110,120,110,30]〗^(T )

我们使用这组训练数据对模型进行训练。只看这两个训练样本,二者的主要差别在于理综成绩,即 x_4 的特征对能否考上一类本科院校有决定性作用,所以,x_4 所对应的 w_4 的数值比较大,而 w_1~w_3 的数值比较小(起的作用不大)。然而,这个结果与我们的认知和事实相悖。实际上,另外三门课的成绩同样重要。在这里,因为训练样本过少,所以模型出现了偏差。如果将这个模型放到真实的场景中,那么预测结果会倾向于“只要理综成绩高,考上一类本科院校的概率较高”—— 这就是过拟合。我们只有收集更多的数据,让样本尽可能多样化,才能降低片面依赖 w_4 的程度。

如果数据量不足,该怎么办呢?我们可以在训练模型时给损失函数添加正则项。这相当于把我们的认知强加给模型,让模型除了能根据数据说话,还能满足我们的主观意愿。在这里,我们的主观意愿就是 w 的取值不要太大。我们的主观意愿合理吗?当然合理。我们处理的任务往往是具有平滑性的。平滑性是指输入的微小变化不会导致结果的巨变。然而,过大的 w 会放大 x 的变化,从而引发输出的巨变。因此,较小的 w 在大多数任务上是适用的。

那么,有没有不平滑的任务呢?例如,预测一个整数是否为质数,这就是一个典型的不平滑任务。在大多数时候,数值的变化不会导致类别的变化(大部分整数都是非质数),但个别的输入变化(10→11)会导致类别的巨变(非质数→质数)。目前,机器学习在不平滑任务上表现很差,在上述极端不平滑任务中几乎没有用武之地。

因此,当我们遇到一个分类任务时,要先判断它是否为平滑任务。如果是平滑任务,就可以放心大胆地使用正则项,根据经验和数据量酌情设置 λ。如果是非平滑任务,那么连机器学习是否适用都有待商榷。

正则项在机器学习中是一个相对通用的方法,在神经网络中也会广泛地使用它,后面我们会详细讨论。

3.5 分类模型的评价标准

训练完成后,我们需要对训练好的模型进行评测,看看模型是“好”还是“坏”。

首先需要定义评价标准。对分类模型来说,不同的应用场景有不同的评测指标。下面介绍一些常用的指标。

在二分类任务中,两个类别为P和N,模型的输出 y^' 表示样本属于P类的概率。在实际使用时,一般会设置一个阈值 θ:当 y^'>θ 时,模型预测样本为P类;当 y^'<θ 时,模型预测样本为N类。阈值一般为0.5。当然,也可以根据实际情况设置阈值。

同时,在二分类任务中,每个数据点都有真实客观存在的标签(P或N)。模型会对数据点的标签进行判断,从而得到预测标签。假设一共有 M 个测试样本,它们由四种情况组成,如图3-13所示。

图3-13

TP 表示真实标签为P、模型预测为P类的样本数量。

FP 表示真实标签为N、模型预测为P类的样本数量。

FN 表示真实标签为P、模型预测为N类的样本数量。

TN 表示真实标签为N、模型预测为N类的样本数量。

显然,M=TP+FP+FN+TN。

另外,可以得到真实标签为P的样本数量(MP=TP+FN),以及真实标签为N的样本数量(MN=FP+FN)。

在上述四种情况中,只有前两种情况(TP 和 TN)的模型预测结果和真实结果是一致的,因此,正确率(acc)为

acc=(TP+TN)/M

但是,上式存在一些缺陷。当测试样本类别不平衡时,例如N类的样本数量远大于P类的样本数量(MN≫MP),指标 acc 将会失效。假设有1010个样本,其中 MN=1000,MP=10。在1000个真实标签为N的样本中,所有样本都被预测为N类,模型对这1000个样本的预测正确率为100%。而在10个真实标签为P的样本中,只有1个被预测为P类,另外9个都被预测为N类,那么正确率仅为10%。

如果我们用正确率来评价模型,则有

acc=(1000+1)/1010=99.1%

这样看来,模型的正确率其实不低。但真实的情况确是,模型对P类的预测正确率非常低(只有10%),整体正确率高是因为属于N类的样本数量远大于属于P类的样本数量,将正确率拉上来了。因此,如果仅看正确率,那么模型对P类的预测正确率过低这一事实将被掩盖。

为了克服测试样本数量不平衡时重要信息被隐藏的问题,需要引入准确率和召回率。准确率和召回率不是一个整体指标,它们都是针对具体一类(P类或N类)的预测情况进行评测的。以P类为例,准确率和召回率的定义如下。

准确率=TP/(TP+FP)

召回率=TP/(TP+FN)

通俗地讲,对于P类,准确率是指在模型预测结果为P类的样本中有多少比例是真的属于P类的,召回率是指在属于P类的样本中有多少比例会被模型判断为属于P类。上述定义对N类同样成立。准确率高,说明模型的误判少;召回率高,说明模型的漏判少。在上述例子中,P类的准确率和召回率如下。

P类的准确率=1/(1+0)=100%

P类的召回率=1/10=10%

正确率、准确率、召回率都需要模型输出确定的类别(P或N)。预测的类别不仅与模型的输出概率 y^' 有关,也与主观设定的阈值有关。阈值的变化会影响预测结果,进而引起指标的变化。因此,这三个指标不是完全客观的。

为了使模型的评测更加客观,常使用ROC曲线(Receiver Operating Characteristic Curve,接受者操作特性曲线)和AUC(Area Under Curve,指ROC曲线下方的面积)对分类模型进行评测。下面我们了解一下这两个指标的具体含义。

在二分类问题中,有 MP 个样本属于P类,有 MN 个样本属于N类,模型对每个样本计算一个得分。在理想情况下,我们希望P类的得分高于N类的得分。把P类中的每个样本和N类中的所有样本分别进行比较,一共进行 MP×MN 次比较。将P类的模型得分高于N类的模型得分的次数记为 H,可以定义如下指标。

AUC=H/(MP×MN)

显然,如果所有P类的模型得分均高于所有N类的模型得分,那么 H=MP×MN,即 AUC=1。此时,我们认为模型是非常好的,因为它可以将预测结果为P类和N类的得分完美地分开。

如果 AUC=0.5,那么一半P类样本的得分比N类样本的得分高,另一半P类样本的得分比N类样本的得分低,两类样本的模型得分混在一起,没有任何区分度——这样的模型是比较差的。

如果 AUC<0.5,那么模型比“随机猜”还差,因为大部分N类样本的得分都比P类样本的得分高。

将AUC作为模型指标,有以下两个优点。

计算不涉及阈值,仅涉及对模型输出得分的比较,因此是完全客观的。

AUC的值是一个比例,因此,即使两类测试样本的数量差异很大,也不会对该值造成影响。

我们通过一个例子了解一下如何计算AUC。例如,有P类和N类样本各100个,模型预测P类得分为0.9、0.8、0.7的样本分别有30个、40个、30个,N类得分为0.75、0.6的样本分别有20个、80个。此时:

P类得分为0.9的30个样本比100个N类样本的得分都高,对应于 30×100 个组合;

P类得分为0.8的40个样本比100个N类样本的得分都高,对应于 40×100 个组合;

P类得分为0.7的30个样本只比80个N类样本的得分(得分为0.6的80个N类样本)高,对应于 30×80 个组合。

因此,可以计算

AUC=(30×100+40×100+30×80)/(100×100)=0.94

接下来,我们认识一下ROC曲线。在二分类任务中,取一个阈值 θ。在 MP 个P类样本中,模型预测有 m 个P类样本,所以,m 越大,预测结果就越准确。在 MN 个N类样本中,模型预测有 n 个P类样本,所以,n 越大,预测结果就越不准确。如果模型使用不同的阈值,就会产生不同的分类结果,对应于不同的 m 和 n。

画一个坐标系,横坐标为 n/MN,纵坐标为 m/MP,每个具体的阈值唯一确定 (m,n)(对应于坐标系中的一个点)。此时,只要遍历阈值,就能在坐标系中画出一条ROC曲线,如图3-14所示。

当 θ=0 时,无论模型是“好”还是“坏”,所有数据样本都会被模型预测为P类。对P类样本来说,这表示所有数据预测正确,即 m/M=1。对N类样本来说,这表示所有数据预测错误,即 n/N=1。所以,对应的坐标系中的点是 (1,1)。

当 θ=1 时,无论模型是“好”还是“坏”,所有数据样本都会被模型预测为N类。对P类样本来说,这表示所有数据预测错误,即 m/M=0。对N类样本来说,这表示所有数据预测正确,即 n/N=1。所以,对应的坐标系中的点是 (0,0)。

图3-14

因此,ROC曲线一定经过 (0,0) 和 (1,1) 两个点——与模型无关。不过,曲线中的其他点与模型有关。

我们不加证明地给出如下结论(具体证明过程比较复杂,感兴趣的读者可自行查阅相关文献)。

ROC曲线下的面积=AUC

这也是AUC的值的几何意义。

AUC的值常用于对数据进行排序的场景,例如推荐、搜索、广告等。

3.6 逻辑回归的特征提升技巧

3.6.1 特征归一化

为了更直观地理解训练阶段 w 各维度的数值更新,我们可以画出 w 坐标系中损失函数的等高线图。尽管每个 w 对应于唯一的 Loss,但一个 Loss 会对应于多个取不同值的 w。对应于同一个 Loss 值的 w 连接起来组成的线,称为等高线。

当 w=〖[w_1,w_2]〗^T 时,等高线图如图3-15所示,箭头表示在学习阶段 w 的变化路径。同一条等高线上的 Loss 值相同。在学习阶段,梯度下降法会迭代移动 w,使 w 移动到低势的等高线上(靠近中心)。

图3-15

如果特征 x_1 的数量级远大于特征 x_2,那么 Loss 将对 w_1 更敏感,w_1 的轻微波动会对逻辑回归结果造成很大的影响,并最终导致 Loss 的剧烈波动;w_2 的变化对 Loss 的影响则相对较小。

例如:x_1 表示身高,单位为毫米;x_2 表示体重,单位为千克;数据特征为 〖[1750,60]〗^T。可以看出,x_1 在数量级上是 x_2 的100倍,在等高线上表现为:Loss 等高线在 w_1 方向比较“窄”,w_1 的轻微变化会导致等高线上较大的移动,即 Loss 对 w_1 方向较为敏感。相应的,Loss 对 w_2 方向较为迟钝。因此,在学习阶段,为了使 w_1 和 w_2 对 Loss 下降的贡献一致,理想的状态是:敏感的 w_1 每次更新幅度相对较小,迟钝的 w_2 每次更新幅度相对较大。

我们再看看当特征维度 x_1 和 x_2 的数量级差异过大时各维度 w 更新梯度的实际情况,公式如下。

可以发现,∂Loss/(∂w_i ) 和 x_i 成正比。

在这个例子中,∂Loss/(∂w_1 ) 在数量级上大于 ∂Loss/(∂w_2 ),因此,每次更新 w 时,在 w_1 方向上的移

动幅度大于 w_2,这与上面的理想情况相悖。实际学习过程如图3-16所示。

图3-16

这种现象称为zigzag,等高线 Loss 对 w_1 和 w_2 方向的敏感程度差异过大,非常不利于参数学习。

在理想情况下,我们希望 w_1 和 w_2 的变化对 Loss 的影响处于同一量级,即 ∂Loss/(∂w_1 ) 和

∂Loss/(∂w_2 ) 在数值上处于同一量级(有利于优化)。∂Loss/(∂w_1 ) 和 ∂Loss/(∂w_2 ) 数量级不一致的原因是特征 x_1

和 x_2 的数量级不一致。因此,需要制定一个标准,把各维度的特征归一到同一个数量级。

通过方差将 x_1 和 x_2 归一,也就是说,先计算 x_1 和 x_2 维度的标准差 δ_1 和 δ_2,再更新 x_1 和 x_2,公式如下。

x_1^'=x_1/δ_1 ,x_2^'=x_2/δ_2

此时,w_1 和 w_2 对 Loss 的影响一致,等高线为圆形,如图3-17所示。

图3-17

当等高线为圆形时,等高线对各个维度的敏感程度就是相同的了。此时,可以设置较大的学习因子来减少梯度下降的迭代次数,加快训练进程。图3-17中箭头的方向就是 w 的更新方向,w 不再反复震荡,学习速度得到了提高。

3.6.2 特征分段

对同一个特征使用不同的提取方式,会对逻辑回归的效果产生影响。例如,在电商场景中,年龄是一个重要特征,我们可以通过年龄预测用户购买某商品的概率。年龄(age)可以用两种方式来表达。

第一种方式是直接编码。用1维特征表示年龄,例如23岁,特征 x=[23]。此时,年龄对 d=w^T x+w_0 只存在线性影响,即 d=w_1 x_1+w_0=w_1 age+w_0,如图3-18所示。这种特征提取方式简单、直接,但忽略了不同年龄对购买行为影响的差异(正负、强弱)。

图3-18

第二种方式是采用one-hot编码。我们把年龄从0到100岁分成四段,用4维向量来表示。不同年龄段有如下特征。

小孩:〖[1,0,0,0]〗^T,0<age ≤ 18。

年轻人:〖[0,1,0,0]〗^T,18<age ≤ 40。

中年人:〖[0,0,1,0]〗^T,40<age ≤ 60。

老年人:〖[0,0,0,1]〗^T,60<age。

例如,25岁的购物者的年龄所对应的特征为 〖[0,1,0,0]〗^T。使用one-hot编码,不同的区间特征有不同的权重,表达更加多样且稳定(24岁和25岁其实没有很大的差别)。此时,d=w^T x+w_0 与年龄特征 x 的关系如下式所示。

d=w_1 x_1+w_2 x_2+w_3 x_3+w_4 x_4+w_0

其中,x_1、x_2、x_3、x_4 有且仅有一个为1。d 和 age 的关系,如图3-19所示。

图3-19

可以看出,age 和 d 成非线性关系,不同的年龄对最终分类结果的影响的权重不同,这增强了模型的表达能力。

我们可以进一步在one-hot编码的相应位置填写某个年龄在该年龄段中所占的比例,如下式所示。

此时,会在one-hot编码的各个位置对 age 进行更加细致的分段表达,即 x_i∈[0,1],且每一段都有对应的参数

d=w_1 x_1+w_2 x_2+w_3 x_3+w_4 x_4+w_0

此时 d 和 age 的关系,如图3-20所示。

图3-20

可以看出,age 和 d 的非线性关系进一步加强,并且,在0~18岁和18~40岁这两个年龄段,购买欲望和年龄成正相关,而在40~60岁和60~100岁这两个年龄段,年龄越大,购买欲望越低。

3.7 深入理解损失函数和逻辑函数

在面试人工智能相关岗位时,我们经常会被面试官问一个问题:为什么逻辑回归不能像线性回归一样使用MSE作为损失函数呢?主要原因有以下两个。

第一,将MSE作为逻辑回归的损失函数,即当

Loss=1/N ∑_(i=1)^N▒〖(y_((i))^'-y_((i)))〗^2

时,有

∂Loss/∂w=2/N ∑_(i=1)^N▒〖(y_((i))^'-y_((i)))y_((i))^' (1-y_((i))^')x_((i)) 〗

在这里,y_((i))^' (1-y_((i))^') 非常容易趋近于0(无论预测是否准确:当样本被预测为P类时,1-y_((i))^'≈0;当样本被预测为N类时,y_((i))^'≈0),导数值非常小,w 的更新效率极低,学习时间极长。

第二,w-MSE 曲线存在局部极小值。w 落在局部最小位置(如图3-21所示)后就不会再更新了,但此时 Loss 仍比较大,模型效果不佳,将发生欠拟合。

图3-21

可能有些读者会认为:虽然将MSE作为损失函数并不合适,但只要是能度量距离的函数,理论上都可以作为损失函数,所以也不一定要使用KL距离。在这里选择KL距离,其实是有统计学理论作为支撑的。下面我们一起了解一下KL距离背后的数学原理。

在使用模型预测样本 x_((i)) 的类别时,模型的输出为 y_((i))^',即预测结果为P类的概率为 y_((i))^',预测结果为N类的概率为 〖1-y〗_((i))^'。

如果 x_((i) ) 的真实类别为P类,也就是 y_((i) )=1,那么模型预测结果为P类的概率为 P(y=y_((i) ) |x_((i) ) )=y_((i))^'。

如果 x_((i)) 的真实类别为N类,也就是 y_((i))=0,那么模型预测结果为N类的概率为 P(y=y_((i)) |x_((i)) )=1-y_((i))^'。

这是一个典型的二项分布,可以统一写成

P(y=y_((i)) |x_((i)) )=〖y_((i))^'〗^(y_((i)) ) (1-y_((i))^' )^((1-y_((i))))

N 个训练样本 〖{x_((i)),y_((i))}〗_(i=1)^N 的似然函数为

likelihood=∏_(i=1)^N▒P(y=y_((i)) |x_((i)) )

为了方便计算,我们对似然函数取对数。似然函数变为

likelihood=log∏_(i=1)^N▒P(y=y_((i) ) |x_((i) ) ) =∑_(i=1)^N▒logP(y=y_((i) ) |x_((i) ) )

=∑_(i=1)^N▒〖log⁡[〖y_((i))^'〗^(y_((i) ) )∙(1-y_((i))^' )^((1-y_((i) ) ) ) ]=∑_(i=1)^N▒〖y_((i)) log⁡〖y_((i))^' 〗+(1-y_((i)) ) log⁡(1-y_((i))^' ) 〗〗

因为训练样本是已经发生的事件,所以“好模型”的标准就是能够使似然函数最大化(最大似然估计)。优化目标为最大化似然函数,即 max⁡(likelihood),它等价于 min(-likelihood),故优化目标为

min(-likelihood)〖=min〗⁡[∑_(i=1)^N▒〖-y_((i)) log⁡〖y_((i))^' 〗-(1-y_((i)) ) log⁡(1-y_((i))^' ) 〗]

可以看出,-y_((i)) log⁡〖y_((i))^' 〗-(1-y_((i)) ) log⁡(1-y_((i))^' ) 就是 y_((i))^' 和 y_((i)) 的KL距离,优化目标就是最小化各样本的KL距离之和。

通过以上分析可以发现,使用KL距离的原因就是它等价于最大似然估计。最大似然估计是一种经典的统计学参数估计方法,有充分的理论依据和实践基础。

讨论一个问题:能把 w^T x+w_0 归一至 (0,1) 的函数有很多,为什么一定要选择逻辑函

数 f(x)=1/(1+e^(〖-(w〗^T x+w_0)) ) 呢?

假设通过身高 x 来预测性别 y,y=1 表示男性,y=0 表示女性,男性和女性的身高分布都满足正态分布,如下所示。

男性的身高分布为

P(x|y=1)=1/√2πσ e^(-〖(x-μ_1)〗^2/(2σ^2 ))

女性的身高分布为

P(x|y=0)=1/√2πσ e^(-〖(x-μ_2)〗^2/(2σ^2 ))

其中,男性身高的均值为 μ_1,女性身高的均值为 μ_2,方差都为 σ。我们知道一个人的身高 x,想通过身高预测他(她)的性别,这就是一个典型的二分类问题——其实就是比较 P(y=1│x) 和 P(y=0│x) 的大小。需要注意的是,P(y=1│x)+P(y=0│x)=1。

根据贝叶斯公式,当一个人的身高为 x 时,他(她)为男性的概率为

P(y=1│x)=(P(y=1))/(P(x)) P(x|y=1)

同理,当一个人的身高为 x 时,他(她)为女性的概率为

P(y=0│x)=(P(y=0))/(P(x)) P(x|y=0)

将二者相除,有

(P(y=1│x))/(P(y=0│x) )=(P(y=1))/(P(y=0)) (P(x|y=1))/(P(x|y=0))

根据身高分布,可知

P(x|y=1)=1/√2πσ e^(-〖(x-μ_1)〗^2/(2σ^2 ))

P(x|y=0)=1/√2πσ e^(-〖(x-μ_2)〗^2/(2σ^2 ))

令 (P(y=1))/(P(y=0))=α,则 (P(y=1│x))/(P(y=0│x) ) 可表示为

(P(y=1│x))/(P(y=0│x) )=αe^(-〖(x-μ_1 )^2-(x-μ_2 )〗^2/(2σ^2 ))

=e^lnα e^(-((2μ_2-2μ_1 )x+(μ_1^2-μ_2^2 ))/(2σ^2 ))

=e^(-((2μ_2-2μ_1 )x+(μ_1^2-μ_2^2 ))/(2σ^2 )+lnα)

结合 P(y=1│x)+P(y=0│x)=1,可以得出

P(y=1│x)=1/(1+e^(-(((2μ_1-2μ_2 )x+(μ_2^2-μ_1^2 ))/(2σ^2 )+lnα) ) )

令 w=(μ_1-μ_2)/σ^2 ,w_0=(μ_2^2-μ_1^2)/(2σ^2 )+lnα,则

P(y=1│x)=1/(1+e^(-(wx+w_0)) )

看看上式,是不是很眼熟?对,这就是逻辑回归。通过推导可以发现,逻辑回归是假设数据符合正态分布,然后使用贝叶斯定理推导出来的。它虽然形式简单,但有很强的数学特性——逻辑函数可不是数学家们拍脑袋选出来的。

不过,在这里需要注意:将逻辑回归作为分类函数,相当于默认了偏置条件“数据满足正态分布”。经统计学方法验证,当数据量足够大时,概率分布都会趋近于正态分布,这就是中心极限定理。这也说明,在训练模型时,数据量越大,效果越好。

如果P类样本的数量远高于N类样本的数量,那么 α=(P(y=1))/(P(y=0)) 的值将变得很大,从而导

致 w_0=(μ_2^2-μ_1^2)/(2σ^2 )+lnα 的值较大,使结果 P(y=1│x) 在所有特征上都偏大,样本容易被预测为

P类。这也从侧面印证了样本平衡的重要性。


第四章 因子分解模型

4.1 基本原理和特征交叉

4.1.1 基本原理

逻辑回归简单实用,没有复杂的数值运算,非常适合在对性能要求较高的场景中进行在线预测,目前已经成为企业应用的标配和基线。但是,随着互联网的发展,以及应用场景的日益复杂,人们对机器学习的期待日渐提高,在一些复杂的场景中,逻辑回归显得有些力不从心。例如,在电商推荐场景中预测用户是否会购买某商品,商品和用户都将作为模型特征,购买行为的发生与否将作为预测类别。输入为 x=〖[x_1,x_2]〗^T,x_1=0 表示女性,x_1=1 表示男性,x_2=0 表示女鞋,x_2=1 表示男鞋,输出 y 表示用户的购买概率,特征分布如图4-1所示。

图4-1

其中,椭圆形表示用户会购买(y=1),三角形表示用户不会购买(y=0)。可以看出,这是一个典型的异或问题(在需要判断二者是否匹配的分类场景中,这种问题广泛存在)。通过前面的学习我们知道,要想用逻辑回归解决异或问题,就要对特征进行升维。特征交叉是一个非常好用的特征升维方法。例如,将 x=〖[x_1,x_2]〗^T 升维至 x=〖[x_1,x_2,x_1 x_2]〗^T,就可以解决异或问题。

然而,在真实的场景中,直接使用特征交叉会面临以下困难。

一般来说,特征维度有成千上万维,如果人工进行特征交叉,是不太容易把所有需要的交叉特征都找出来的,并且很多交叉特征并不是我们能想象出来的。因此,只能以穷举的方式对所有的特征进行两两交叉。例如,6维特征的交叉特征有 C_6^2=15 维。再如,在实际场景中并不算高的1000维特征,有 C_1000^2=499500 维的交叉特征。如此规模的特征,会给存储和计算带来沉重的负担并造成维数灾难(将在5.4节介绍)。

对于交叉后的高维特征,很多交叉特征非常稀疏,甚至在训练集里从未出现过(例如交叉项 x_i x_j=0、x_j=1 和 x_j=1 在训练样本中从未同时出现)。这时,特征所对应的系数 w_(i,j) 在使用梯度下降法时不会更新,w_(i,j) 永远都是一开始的随机值。但是,一旦在真实的生产环境中上线使用,只要有交叉特征出现(x_i x_j=1),w_(i,j) x_i x_j=w_(i,j) 就是一个随机数,相当于给模型注入了噪声。

待学习的特征系数 w_(i,j) 有上百万个。在机器学习领域,需要学习的参数越多,往往就会要求越多的数据。训练百万参数所需的样本是很难获得的,且如此高的维度几乎注定导致维数灾难。目前,参数数量和训练样本数量的对应关系是一个研究热点,尚无定论,但二者成正相关是毋庸置疑的。

很多特征本身具有一定的相似性。假设用户对商品的颜色“大红色”和“桃红色”的喜好没有差别或差别较小。如果在训练样本中“女鞋”(x_i)和“大红色”(x_j)的组合经常出现,那么 w_(i,j) 将多次得到训练,结果也相对准确。如果“女鞋”(x_i)和“桃红色”(x_p)的组合没有出现过,那么 w_(i,p) 将不会得到更新,一直是刚开始的随机值。因此,只要样本中出现“女鞋”和“桃红色”的组合,就很难得到准确的预测结果。其实,完全可以借鉴“女鞋”和“大红色”这个特征所对应的 w_(i,j),将其作为 w_(i,p) 的近似特征。但很遗憾,直接对特征进行交叉无法实现这一点。

因为上述缺点,在实际应用中很少直接进行特征交叉,通常会采用间接交叉的方式。以特征 x_1 和 x_2 为例,间接交叉会将 x_1 x_2 的系数 w_1,2 解耦,拆解成向量 v_1 和 v_2,向量维度为 k,即

拆解向量后,v_1 只和特征 x_1 有关,v_2 只和特征 x_2 有关。此时,系数 w_1,2=〈〖v_i,v〗_j 〉。〈〖v_i,v〗_j 〉 表示 v_1 和 v_2 的向量内积,用于衡量两个向量之间的相似度(不熟悉内积的读者可以参考本书第1章)。同理,在计算 x_1,2 的系数 w_1,3 时,可以解耦成 v_1 和 v_3,v_3 和特征 x_3 有关。这样,组合特征系数 w_1,2 和 w_1,3 就不是完全独立的了,它们都会受 v_1 的影响。上述分析如图4-2所示。

图4-2

因此,逻辑回归将被改造成以下模型。

〖w_0+w〗_1 x_1+w_2 x_2+⋯+w_m x_m 和标准逻辑回归并无二致。∑_(i=1)^m▒∑_(j=i+1)^m▒〖〈〖v_i,v〗_j 〉 x_i x_j 〗 为交叉

特征项,通过拆解 w_(i,j)=〈〖v_i,v〗_j 〉 来表达特征交叉,覆盖了所有的特征两两配对。上述模型

称为因子分解机(Factorization Machine,FM)。“Factorization”的意思是分解,意味着对 w_(i,j) 的拆解。那么,因子分解模型有哪些优点呢?

假设一共有 m 维特征。如果直接两两交叉,那么一共有 C_m^2=(m(m-1))/2 个待学习参数。如果使用系数解耦的方法,每个特征对应于一个 k 维向量 v,那么待学习参数有 m×k 个。k 的值一般都不大——k=100 已经足够大了。显然 mk≪(m(m-1))/2,待学习参数的数量大幅减少了。参数的数量减少后,对训练样本数量的要求就降低了,同时,使用的存储空间减少了。

特征之间的相似度都可以用 v 来表示。如果 x_1 和 x_2 分别对应于特征“大红色”和“桃红色”,那么它们所对应的向量内积 〈〖v_i,v〗_j 〉 会比较大。这反映了特征的相似性。相似的特征表明,它们在特征组合中所起的作用类似。

在训练样本中,如果交叉项 x_i x_j 从未出现,但 x_i、x_j 分别和其他特征的组合在样本中经常出现,那么 v_i 和 v_j 也能得到充分的训练。在实际使用时,即使碰到训练集中未出现过的交叉特征 x_i x_j,也能计算出靠谱的 w_(i,j)=〈〖v_i,v〗_j 〉。

4.1.2 特征交叉简化

尽管交叉项 ∑_(i=1)^m▒∑_(j=i+1)^m▒〖〈〖v_i,v〗_j 〉 x_i x_j 〗 巧妙地解决了特征两两交叉时产生的系数过多的

问题,但没有解决运算量过大的问题。∑_(i=1)^m▒∑_(j=i+1)^m▒〖〈〖v_i,v〗_j 〉 x_j 〗 的运算量为 O(km^2)。如果运

算量过大,在进行在线预测时,就会给机器造成很大的性能压力。因此,需要对其进行化简。

首先,从 〈〖v_i,v〗_j 〉=∑_(h=1)^k▒〖v_(i,h) v_(j,h) 〗 中可以看出,在计算内积时,只有处于同一维度的特

征才会相乘,因此,可以进行第一次化简,公式如下。

下面讨论一下在维度 h 下 ∑_(i=1)^m▒∑_(j=i+1)^m▒〖v_(i,h) v_(j,h) x_i x_j 〗 如何化简。复习中学阶段学过的一

组数学公式,具体如下。

依此类推,有

可以在维度 h 下得到

那么,在所有的维度上,最终结果为

其中

所对应的运算量为 O(km)。通过对模型的化简,运算量从 O(km^2) 降至 O(km)。所以,最终的模型为

w_0+w^T x 对应于逻辑回归,∑_(h=1)^k▒(1/2 [(∑_(i=1)^m▒〖v_(i,h) x_i 〗)^2-∑_(i=1)^m▒(v_(i,h) x_i )^2 ]) 对应于新增的特征

交叉项。

4.1.3 参数学习

作为逻辑回归的改进版本,因子分解模型仅在特征处巧妙地使用向量 v 进行了特征的两两交叉,并把参数的增量控制在可以接受的范围内。在模型训练阶段,因子分解模型仍使用梯度下降法。

因子分解模型是一个二分类模型,其损失函数使用模型输出和样本标签之间的KL距离进行计算,即

模型的待求参数为 w 和 v_(j,h),它们分别对应于逻辑回归的参数和交叉项的参数。

上述求导过程和逻辑回归并无二致。

4.2 因子分解模型和矩阵分解

熟悉推荐系统的读者都知道,用户的点击行为可以构成一个行为矩阵。该矩阵的行表示用户(User),列可以表示视频、新闻、商品等(通常称为Item)。假设一共有 N 个User和 M 个Item,矩阵的维度是 N×M,矩阵中的元素表示用户对商品的喜欢程度(1为喜欢,0为不喜欢)。这里的“喜欢”通常是根据具体的产品形态定义的,例如在短视频场景中涉及观看完成度、是否收藏等,在电商场景中涉及购买与否、评价星级等。

在推荐系统中有一个经典的方法,就是将行为矩阵分解成两个矩阵相乘的形式,例如用户矩阵和商品矩阵(具体的分解方法涉及很多数学知识,本书不再赘述)。其中,用户矩阵的维度为 N×K,商品矩阵的维度为 K×M,如图4-3所示。

图4-3

在用户矩阵中,每一行代表一个用户 u_i,它是一个 K 维向量(这个向量是用户的隐含表示)。在商品矩阵中,每一列对应于一个商品 v_j,每个商品也对应于一个 K 维向量。通过对用户向量和商品向量计算内积 〈〖u_i,v〗_j 〉,就可以表示用户对商品的喜欢程度,达到预测的目的。

矩阵分解在理论上是可行的,但实际的应用并不多,其原因在于计算量巨大。例如,有2000万个用户、200万个商品,那么矩阵中就有40万亿个元素——很难分解。在构建行为矩阵时:如果用户明确表示喜欢(例如愿意购买、观看等),就将相应的元素置1;如果用户明确表示不喜欢(例如给差评、打低分),就将相应的元素置0。然而,大部分商品是用户没有接触过的,何谈“爱恨”?矩阵分解的想法固然美好,但仍有缺陷。

我们回头看一下因子分解模型。在使用FM预测用户对商品的喜欢程度的场景中,采用one-hot方式对用户和商品进行编码(输入特征),N 个用户对应于 N 维向量,M 个商品对应于 M 维向量,因此,特征总维度为 M+N。每次训练 M+N 维特征时,有且仅有两个元素(用户 x_i,商品 x_j)为1,其他元素都为0。省略所有为0的特征,因子分解模型的核心部分为

d=w_i x_i+w_j x_j+〈〖u_i,v〗_j 〉 x_i x_j

u_i 为用户所对应的向量,v_j 为商品所对应的向量,内积 〈〖u_i,v〗_j 〉 就是用户和商品的相似度,这和通过矩阵分解进行预测的方式一模一样。可以看出,因子分解模型包括矩阵分解,或者说,矩阵分解是因子分解模型的特例(不考虑线性部分 w_i x_i)。

与矩阵分解相比,因子分解模型是一个更为宏大的框架,在特征层面可以引入更多维度(例如年龄、价格等)的特征来获得特征相似度,而矩阵分解只支持两类特征(用户、商品)。在训练样本的构建上,因子分解模型也没有矩阵分解不知道如何对未见过的部分进行赋值的问题。


第五章 经典分类模型

5.1 支持向量机

5.1.1 支持向量机的基本原理

通过前面的学习我们知道,逻辑回归其实就是在平面上通过画直线进行二分类,其学习过程就是通过梯度下降法在训练数据中寻找分类线。当训练数据线性可分时,能够正确进行分类的分类线有无数条,不同的分类线对应于不同的 w 和 w_0 及不同的 Loss,如图5-1所示。

图5-1

在图5-1中,直线 L_1 和 L_2 都可以把训练数据完美地分成两类,但哪条更好呢?Loss 最小的直线一定是最好的吗?我们可以从几何的角度审视这个问题。直线 L_2 与一些数据点的距离相对较近,如果测试集中的数据点发生轻微的移动(特征轻微变化),那么测试数据将跑到直线的另一侧,如图5-2所示。

图5-2

这种直线虽然能够在训练样本中实现正确分类,但在实际应用中面对大量没有见过而与训练样本有偏差的数据时,其准确性就会打折扣(其实这就是过拟合)。相对来说,数据点离直线 L_1 较远,即使发生了轻微的移动,也不会跑到直线的另一侧(导致分类结果改变),因此,直线 L_1 的泛化能力相对较强。

综上所述,在这两条直线中 L_1 更好,因为它离边界数据点更远。

在数据线性可分的情况下,我们把以上分析细化一下。数据点可以分为两种类型,即边界点和内部点。边界点是指一个类别中距离分类线最近的点,每个类别可以有不止一个边界点。除了边界点,其他的数据点都是内部点,如图5-3所示。

图5-3

因为内部点远离直线,所以,它们即使发生了轻微移动,也不会来到直线的另一侧。但是,因为边界点靠近分类线,所以它们的随机移动很容易跨越直线,被分类器判断为另一类别。因此,分类器在边界点附近的稳定性差,即泛化能力弱。

如何提高分类线的稳定性呢?可以增大边界点到分类线的距离——距离越远,边界点随机移动至直线另一侧的概率就越小。

为了方便,我们以输入数据为2维的情况为例进行分析,所有结论均可推广至高维空间。首先看一下点到分类线的距离公式。因为分类线有无数条平行线,所以,可以把分类线放在两个类别的边界点的中间位置,即

distance_N类=distance_P类

已知分类线的方程为 w_1 x_1+w_2 x_2+w_0=0,那么P类的边界点 〖[x_1,x_2]〗^T 到直线的距离为

distance_P类=distance_N类=|w_1 x_1+w_2 x_2+w_0 |/√(w_1^2+w_2^2 )

在讲解逻辑回归时提到过,对同一条直线,可以在系数上进行放缩,即

w_1 x_1+w_2 x_2+w_0=0

α_P类 (w_1 x_1+w_2 x_2+w_0 )=0,〖 α〗_P类≠0

以上两个方程对应的是同一条直线。对直线进行系数缩放不会改变直线本身,因此,点到直线的距离也不会改变。因为我们总能找到一个合适的缩放方法,使得边界点满足 |w_1 x_1+w_2 x_2+w_0 |=1,所以,P类的边界点到分类线的距离变为

distance_P类=|w_1 x_1+w_2 x_2+w_0 |/√(w_1^2+w_2^2 )=1/√(w_1^2+w_2^2 )

P类的内部点满足 w_1 x_1+w_2 x_2+w_0>1。

同理,N类的边界点到分类线的距离为

distance_N类=1/√(w_1^2+w_2^2 )

N类的内部点满足 w_1 x_1+w_2 x_2+w_0<-1。

我们的优化目标是在保证分类正确的前提下使边界点远离分类线,从而提高泛化能力,即找到一个合适的 w 使下式的值最大。

〖distance=distance〗_P类+distance_N类=2/√(w_1^2+w_2^2 )

distance 也称作margin,是指两类边界点中间的空白部分。

现在,我们的优化目标变为最大化下式。

distance=1/√(w_1^2+w_2^2 )

也就是说,最优目标为:在保证正确分类的情况下,最小化 min⁡√(w_1^2+w_2^2 )。

可以发现,min⁡√(w_1^2+w_2^2 ) 和 min⁡〖(w_1^2+w_2^2)〗 是等价的。为了求解方便,最小化目标变为

min⁡〖〖(w〗_1^2+w_2^2)〗

那么,如何通过数学方法表示“保证分类正确”呢?不同于逻辑回归的两个类别(标签为1或0),在这里可以分别设P类和N类所对应的标签 y 为 +1 和 -1。此时,y 已不具备概率意义,仅代表一个类别(如图5-3所示)。

P类:当标签为 y=+1 时,w_1 x_1+w_2 x_2+w_0 ≥ 1。

N类:当标签为 y=-1 时,w_1 x_1+w_2 x_2+w_0 ≤ -1。

以上两式可以统一写成

y(w_1 x_1+w_2 x_2+w_0 )≥1

当 x 为边界点时,“=”成立;当 x 为内部点时,取“>”。y(w_1 x_1+w_2 x_2+w_0 )≥1 作为约束条件,保证了分类的正确性。

但是,在实际应用中,大部分情形都是线性不可分的,即肯定不能正确地进行分类(无法保证下式成立)。

y(w_1 x_1+w_2 x_2+w_0 )≥1

不满足上式的数据点称为误差点。因此,可以进一步将数据点分成三类,即内部点、边界点、误差点。误差点有两种:一种是正确误差点,它的分类正确,但位于边界点外(分类正确,但到分类线的距离小于1);另一种是错误误差点,它不仅位于边界点外,而且分类错误。

对P类来说,误差点如图5-4所示。

图5-4

需要注意的是,正确误差点比边界点更靠近分类线。

为了使误差点满足上式,我们放宽(松弛)条件,引入松弛系数 ε ≥ 0。此时,约束条件变为

y(w_1 x_1+w_2 x_2+w_0 )≥1-ε

这样,不等式就相对没有那么严格了。数据点在不同约束条件下的情况如下。

内部点:y(w_1 x_1+w_2 x_2+w_0 )>1,即 ε=0。

边界点:y(w_1 x_1+w_2 x_2+w_0 )=1,即 ε=0。

正确误差点:y(w_1 x_1+w_2 x_2+w_0 )=1-ε,且 1>ε>0。

错误误差点:y(w_1 x_1+w_2 x_2+w_0 )=1-ε,且 ε ≥ 1。

也就是说

ε={█(0, 如果 y(w_1 x_1+w_2 x_2+w_0 )≥1@1-y(w_1 x_1+w_2 x_2+w_0 ),如果 y(w_1 x_1+w_2 x_2+w_0 )<1)┤

可以看出,ε 越小,分类效果就越好。因此,最小化 ε 也成为优化目标之一。

综上所述,考虑所有训练样本,我们的优化目标是

〖min(〗⁡〖w_1^2+w_2^2 〗+C∑_(i=1)^N▒〖ε_((i)))〗

C 为超参数,表示我们对“分类正确”的重视程度。

对于 i=1,⋯,N,x_((i))=〖[x_((i),1),x_((i),2)]〗^T 满足

y_((i)) (w_1 x_((i),1)+w_2 x_((i),2)+w_0 )≥1-ε_((i))

N 是训练样本的数量。

在求解分类线 w=〖[w_1,w_2]〗^T 和 w_0 时,一般不使用梯度下降法,而使用成熟的拉格朗日乘子法。其中的数学计算较为复杂,感兴趣的读者可自行查阅相关资料。

由于我们的优化目标始终围绕最大化边界点和分类线之间的距离,所以,可以不加推导地得到“分类线仅由边界点决定”这一结果(具体推导过程过于复杂,在此不再详述),如图5-5所示。

图5-5

由于内部点和误差点不会影响分类线(w 和 w_0),所以,我们可以不加推导地得到 w,公式如下。

SV 为P类和N类的边界点的集合。可以看出,w 是所有边界点通过 α_((i)) y_((i)) 加权求和得到的。将任意边界点代入分类线,都可以求出 w_0。例如,当边界点 x_((i))=〖[x_((i),1),x_((i),2)]〗^T 对应于类别 y_((i))=1 时,有

y_((i)) (w_1 x_((i),1)+w_2 x_((i),2)+w_0 )=1

w_0=1-w_1 x_((i),1)+w_2 x_((i),2)

在诸多边界点中,任意选择一个代入即可。

因为边界点直接决定了分类线,且每个边界点都是一个向量,所以,边界点也称为支持向量(Support Vector),这种分类方法称为支持向量机(Support Vector Machine,SVM)。在求解支持向量机时,对于训练样本,不需要特意指明内部点、误差点和边界点,这些点都由拉格朗日法求出的 ε_((i)) 的值决定。

模型训练完成后,在进行分类时,对于待预测数据 x,可以使用以下模型。

y^'={█(1, 如果 w^T x+w_0>0@-1,如果 w^T x+w_0<0)┤

其中

w=(w_1¦w_2 ),x=(x_1¦x_2 )

特别的

w^T x=∑_(i∈SV)▒α_((i)) y_((i)) x_((i))^T x=∑_(i∈SV)▒α_((i)) y_((i)) 〈x_((i))^ ,x〉

这一步相当于输入样本 x 对训练样本中的各个边界点 x_((i))^ 、i∈SV 求内积(距离)。但要注意,支持向量机的结果不具备任何概率意义,这也是它和逻辑回归的区别。

5.1.2 支持向量机和逻辑回归的比较

在机器学习领域,并不存在所谓能解决一切问题的“银弹”,任何模型在解决特定场景中的问题时,都会受到限制或存在不足。我们在学习时,可以通过横向对比加深对各种模型的理解。本节从不同的角度将SVM和逻辑回归进行对比,帮助读者了解二者的长处和不足。

对于模型的输出,逻辑回归的输出 y^'∈(0,1) 有概率意义,而SVM的计算结果 w^T x+w_0 没有概率意义。因此,逻辑回归的预测结果有可解释性,并能通过概率和其他决策联系起来。例如,在广告点击率预测场景中,广告的排序(位置)不仅与预测的点击率有关,也与广告主对每次点击的付费有关。因此,排序所依据的得分为

score=ctr×money

ctr 就是逻辑回归预测的结果 y^',表示预测用户点击的概率;money 为每次点击的获利;score 表示期望收益。如果将SVM作为点击率预测模型,那么,因为SVM的输出不具有概率意义,所以不太容易和 money 进行有业务意义的融合。

从另一个角度看,在进行模型训练时,逻辑回归需要使用全部数据样本来确定分类线。SVM在“看”过所有样本并从中挑出边界点后,只需要利用边界点来确定分类线,而不必关心那些对分类作用不大的内部点。因此,SVM更关注分类,其分类线不会受到大量对分类没有帮助的内部点的影响。此外,因为SVM只关注边界点,所以它非常鲁棒,当样本中存在异常点(远离其他点的数据点)时,异常点会对逻辑回归造成严重影响,但不会影响SVM。

下面我们分析一下,在训练阶段,同为线性分类模型的SVM和逻辑回归的优化目标有何不同。

SVM的优化目标为

min⁡〖(〖||w||〗^2 〗+C∑_(i=1)^N▒ε_((i)) )

并且所有训练数据点 x_((i)) 满足

y_((i)) (w^T x_((i))+w_0)≥1-ε_((i))

不难发现,〖||w||〗^2 就是逻辑回归中的L2正则。∑_(i=1)^N▒ε_((i)) 的作用和逻辑回归中的KL距离

相同,都用于减小分类误差,但二者的具体形式不同。下面对 ε_((i)) 进行分析。

在SVM中,以训练样本 x_((i)) 为例,它所对应的类别为 y_((i))=1,它在模型中的损失函数 ε_((i)) 是一个分段函数,公式如下。

ε_((i))={█( 0,如果 (w^T x_((i))+w_0)≥1@1-(w^T x_((i) )+w_0 ),如果 (w^T x_((i))+w_0)<1)┤

看看逻辑回归的损失函数。对于同一样本 x_((i)),它所对应的类别为 y_((i))=1,样本的损失函数(KL距离)为

ε_((i) )=-y_((i) ) log(y_((i))^' )-(1-y_((i) ) ) log⁡(1-y_((i))^' )

=-log(y_((i))^' )

=-log 1/(1+e^(-(w^T x_((i) )+w_0 ) ) )

=1+e^(-(w^T x_((i))+w_0))

略去与 w、w_0 无的关项,可得

ε_((i))=e^(-(w^T x_((i))+w_0))

逻辑回归和SVM的损失函数的对比,如图5-6所示。

图5-6

可以看出,因为逻辑函数永远不会预测出完全满意的概率(1或0),所以逻辑回归的 ε_((i)) 永远不会为0。因此,即使分类正确,逻辑回归仍然会不停地训练,以求得到更小的损失和更大的概率。然而,对SVM来说,分类正确的内部点可直接使 ε_((i))=0,不再进行对分类无益的训练,这一点和提前终止学习有异曲同工之妙,即到一定程度就不再学习了。

在机器学习中,SVM的损失函数

ε_((i))={█( 0,如果 y(w^T x_((i))+w_0)≥1@1-y(w^T x_((i) )+w_0 ),如果 y(w^T x_((i))+w_0)<1)┤

称为Hinge Loss。近年来,深度学习中的度量学习广泛使用Hinge Loss作为损失函数,并且取得了不错的效果。

从模型训练的角度看,在逻辑回归中,每个训练样本都会参与训练,因此都会对分类线产生影响,如果训练样本中出现了异常点,那么逻辑回归仍然会把分类器朝远离自己的方向推,如图5-7所示。在训练SVM时,只有边界点会对最终的分类线产生影响,从而避免了分类线被内部异常点影响。

图5-7

当数据线性不可分时,如何提高分类的准确率是一个重要的问题。在逻辑回归中,最简

单的方式就是特征组合。例如,不同维度特征的组合 x_i x_j,高阶特征 x_i^2(相同维度特征的

组合)。但是,这种方法会耗费较多的计算资源和人力。在5.2节中,我们将讨论SVM是如何解决这个问题的。

5.2 核方法

5.2.1 核函数

通过第3章的讨论我们已经知道,升维可以解决线性不可分问题。例如,把输入特征 x 的每个维度和其他维度(包括其自身)进行交叉,使特征从3维升至9维,公式如下。

x=[x_1,x_2,x_3 ]^T→x^'=〖[x_1 x_1,x_1 x_2,x_1 x_3,x_2 x_1,x_2 x_2,x_2 x_3,x_3 x_1,x_3 x_2,x_3 x_3]〗^T

通过交叉,逻辑回归具备了解决线性不可分问题的能力。然而,其代价是运算量过大。如果原始特征的维度为 m,那么二阶交叉的维度为 C_m^2—— 这种量级的运算在实际应用中很难实现。因此,我们需要找到能在升维的同时有效降低运算量的方法。

对以下两个向量进行相同的升维操作。

x=[x_1,x_2,x_3 ]^T→x^'=[x_1 x_1,x_1 x_2,x_1 x_3,x_2 x_1,x_2 x_2,x_2 x_3,x_3 x_1,x_3 x_2,x_3 x_3 ]^T

z=[z_1,z_2,z_3 ]^T→z^'=[z_1 z_1,z_1 z_2,z_1 z_3,z_2 z_1,z_2 z_2,z_2 z_3,z_3 z_1,z_3 z_2,z_3 z_3 ]^T

首先,计算 x 和 z 的内积,公式如下。

〈x,z〉=x_1 z_1+x_2 z_2+x_3 z_3

然后,计算升维后 x^' 和 z^' 的内积,公式如下。

〈x^',z^' 〉=x_1 x_1 z_1 z_1+x_1 x_2 z_1 z_2+x_1 x_3 z_1 z_3+x_2 x_1 z_2 z_1+x_2 x_2 z_2 z_2+x_2 x_3 z_2 z_3+

x_3 x_1 z_3 z_1+x_3 x_2 z_3 z_2+x_3 x_3 z_3 z_3

=(x_1 z_1+x_2 z_2+x_3 z_3 )^2

=〖(〈x,z〉)〗^2

可以发现,如果最终目标只是求升维后的内积 〈x^',z^' 〉,那么可以先求原始特征的内积 〈x,z〉,再进行平方运算,而不需要真正进行高运算量的升维操作。

通过对两个低维向量进行数学运算,得到它们投影至高维空间时向量的内积的方法,叫作核方法,相应的算法叫作核函数。如上面的例子所示,有

K(x,z)=〖(〈x,z〉)〗^2=〈x^',z^' 〉

除了 K(x,z)=〖(〈x,z〉)〗^2,还有一些常用的核函数。不同的核函数的区别在于把 和 z 映射到高维空间时采用的升维方法不同。不过,高维向量 x^' 和 z^' 不需要真正计算出来。例如,多项式核函数

K(x,z)=〖(α〈x,z〉+c)〗^d

α、c、d 对应于不同的核函数。可以看出,平方核函数 K(x,z)=〖(〈x,z〉)〗^2 是多项式核函数在 α=1、c=0、d=2 时的一个特例。

高斯核函数也是一个常用的核函数,其公式如下。

K(x,z)=e^((-‖x-z‖/(2σ^2 )))⁡

高斯核函数计算向量升维至无穷维后的内积,涉及的数学运算比较多,感兴趣的读者可以自行查阅相关资料。

5.2.2 核函数在支持向量机中的应用

核方法是一个非常有用的方法,下面我们将讨论如何在SVM中应用它。

首先,了解一下SVM的优化目标(如下式所示)。

min⁡〖‖w‖^2 〗+C∑_(i=1)^N▒ε_((i))

并且,所有训练样本 〖{x_((i) ),y_((i))}〗_(i=1)^N 满足

y_((i)) (w^T x_((i) )+w_0 )≥1-ε_((i))

我们知道,w 为边界点的加权和,公式如下。

w=∑_(i∈SV)▒α_((i)) y_((i)) x_((i))

w 也可以写成所有数据点的加权和,只不过非边界点的数据点所对应的权重 α_((i))=0,i∉SV,即

w=∑_(i=1)^N▒〖α_((i)) y_((i)) x_((i)) 〗

此时,优化参数从求 w 变为求加权系数 α_((i))。在这里,优化目标没有变化,只进行了变量的替换。

既然 w 可以由训练样本的加权和来表示,那么 ‖w‖ 可以有如下变换。

‖w‖^2=w^T w=(∑_(j=1)^N▒〖α_((j) ) y_((j) ) x_((j) ) 〗)^T (∑_(i=1)^N▒〖α_((i) ) y_((i) ) x_((i) ) 〗)

=∑_(j=1)^N▒∑_(i=1)^N▒〖α_((j) ) α_((i) ) y_((j) ) y_((i) ) x_((j))^T x_((i) ) 〗

=∑_(j=1)^N▒∑_(i=1)^N▒〖α_((j)) α_((i)) y_((j)) y_((i)) 〈x_((j)),x_((i)) 〉 〗

在SVM中,如果将 x 投影到高维空间 x^',那么 w 将变成高维空间中的 w^',即

‖w^' ‖^2=∑_(j=1)^N▒∑_(i=1)^N▒〖α_((j)) α_((i)) y_((j)) y_((i)) 〈x_((j))^',x_((i))^' 〉 〗

用核方法把 〈x_((j))^',x_((i))^' 〉 替换成 K(x_((j))^ ,x_((i)) ),无须进行真正的投影,有

‖w^' ‖^2=∑_(j=1)^N▒∑_(i=1)^N▒〖α_((j)) α_((i)) y_((j)) y_((i)) K(x_((j))^ ,x_((i)) ) 〗

同理,在高维空间中,约束条件 y_((i)) 〖w^'〗^T x_((i))^' ≥ 1-ε_((i))有如下变换。

y_((i)) 〖w^'〗^T x_((i))^'=y_((i)) (∑_(j=1)^N▒〖α_((j)) y_((j)) x_((j))^' 〗)^T x_((i))^'=y_((i)) ∑_(j=1)^N▒〖α_((j)) y_((j)) K(x_((i))^ ,x_((j)) )≥1-ε_((i)) 〗

综上所述,当我们为了解决线性不可分问题而采用核方法(升维)时,优化目标将变为

min⁡∑_(j=1)^N▒∑_(i=1)^N▒〖α_((j)) α_((i)) y_((j)) y_((i)) K(x_((j))^ ,x_((i)) ) 〗+C∑_(i=1)^N▒ε_((i))

并且,所有训练样本 〖{x_((i) ),y_((i) )}〗_(i=1)^N 满足

y_((i)) ∑_(j=1)^N▒〖α_((j)) y_((j)) K(x_((i))^ ,x_((j)) )≥1-ε_((i)) 〗

待求参数 α_((i)) 和 ε_((j)) 可以用拉格朗日乘子法求出。

求解完成后,模型在对输入 x 进行预测时将使用如下二式。

y={█(1, 如果 d>0@-1,如果 d<0)┤

d=∑_(i∈SV)▒[α_((i)) y_((i)) K(〖x,x〗_((i))^ )] +w_0

可以发现,使用核方法的SVM在预测时仅将内积替换成了核函数,其他项没有变化。

值得注意的是,在进行高维投影后,不仅数据的分布和相对位置会发生变化,边界数据点也会发生变化。因此,支持向量在低维空间和高维空间中一般对应于不同的数据点。

SVM中的 w^T x 可以分解成 w^T x=∑_(i∈SV)▒α_((i)) y_((i)) 〈x_((i))^ ,x〉 的形式,在预测阶段只需计

算 x 和支持向量 x_((i))^ 的内积,这为核函数的使用提供了便利。通过核函数,SVM可以隐式

地将数据投影到高维空间,以增强非线性处理能力。核函数的应用提高了SVM在处理线性不可分数据方面的能力,使其在传统机器学习方法中一枝独秀。

在逻辑回归中,w 无法进行以上分解,所以在升维时不可避免地要将高维向量 x^' 和 w^' 显式地表示出来。由于这一限制的存在,逻辑回归特征升维后无法写成核函数的形式,也就无法得到核函数带来的好处。

5.3 朴素贝叶斯

5.3.1 朴素贝叶斯原理

逻辑回归、支持向量机,以及本书后面将要讲解的神经网络,其基本原理都是通过给定的输入来预测输出。但是,其中有一个隐含的要求,即输入特征 x=〖[x_1,x_2,⋯,x_m]〗^T 是完备的,也就是说,特征 x_1~x_m 是已知的。这个看似简单的要求,在实际业务应用中并非那么容易达到。

例如,在电商场景中,很多用户出于对隐私保护的考虑,不会填写自己的性别、年龄等特征信息,而在预测用户购买行为时,这些特征是非常重要的。对这些可能缺失的特征,有如下两种处理方法。

当模型使用特征时,x 不考虑可能缺失的特征,即对用户可能不填写的特征“一刀切”,全都不予考虑。这种做法比较“粗暴”。事实上,年龄等特征对预测任务来说是非常重要的,仅因为个别用户不填写而剔除特征是一种因噎废食的行为。然而,如果强制用户填写 x 涉及的特征,那么必填项是很难确定的。

针对缺失的特征,专门训练模型。例如,针对特征 x=〖[x_1,x_2,x_3]〗^T,穷举可能缺失的特征:x1=〖[x_1,x_2]〗^T,x2=〖[x_1,x_3]〗^T,x3=〖[x_2,x_3]〗^T,x4=[x_1],x5=[x_2],x6=[x_3],x7=〖[x_1,x_2,x_3]〗^T(共训练7个模型,各种特征缺失的情况都有对应的模型)。但是,这样做也是不明智的——仅3个特征就需要7个对应的模型,当特征有上百个时模型的数量将非常惊人(不具备实际应用价值)。

特征缺失带来困扰的主要原因在于模型对各个维度的特征的需求是高耦合的,特征之间必须相互作用才能给出预测结果(例如,在逻辑回归中,特征之间需要加权求和)。为了从根本上解决特征缺失问题,需要对特征的各个维度进行解耦,使各个维度的特征都可以独立地进行分类。

为了解决这个问题,我们从统计学的角度来探寻分类问题的本质。分类任务就是在已知 x 时求 P(y=1│x)。通过贝叶斯定理,可以进行如下推理。

P(y=1|x)=P(x,y=1)/P(x) =(P(x|y=1)P(y=1))/(P(x))

P(y=1) 即样本中类别 y=1 的占比,比较容易计算。P(x) 为 x 出现的自然概率,与类别无关。

下面我们了解一下如何计算 P(x|y=1)。以 x=[x_1,x_2,x_3 ]^T 为例:

P(x|y=1)=P(〖[x_1,x_2,x_3]〗^T |y=1)

我们需要预测女生对男生是否喜欢的概率,y=1 为喜欢。

假设男生有3个离散特征,x_1∈{高个子,中等个子,矮个子},x_2∈{温和,暴躁},x_3∈{胖,匀称,瘦}。我们需要估计所有的 P(〖[x_1,x_2,x_3]〗^T |y)(y=1 或 y=0),共计 2×(3×2×3)=36 种概率。本例只有3个特征,在实际应用中,特征往往有上百个,待估计的概率将成指数级增长。这个问题的难点在于特征之间的耦合,因此,必须把 x_1 、x_2 、x_3 作为一个整体进行概率估计。

特征之间的耦合在真实世界中很常见,它对工程实践来说是一个难题。为此,工程师们进行了一些简化,假设 x_1、x_2、x_3 相互独立,可以得到

P(x_1,x_2,x_3 )=P(x_1)P(x_2)P(x_3)

同理

P(x_1,x_2,x_3 |y)=P(x_1 |y)P(x_2 |y)P(x_3 |y)

在这里需要强调的是,尽管上述独立性假设在真实的场景中不容易成立,但假设其成立能带来诸多好处,例如可以使问题得到有效解决。

根据贝叶斯定理和上述独立性假设,有如下推理。

P(y=1│x)=(P(y=1)P(x|y=1))/(P(x))=(P(y=1)P(x_1 |y=1)P(x_2 |y=1)P(x_3 |y=1))/(P(x))

P(y=0│x)=(P(y=0)P(x|y=1))/(P(x))=(P(y=0)P(x_1 |y=0)P(x_2 |y=0)P(x_3 |y=0))/(P(x))

可以通过比较 P(y=1│x) 和 P(y=0│x) 的大小来确定预测的类别,如下式所示。

d=(P(y=1│x))/(P(y=0│x) )=(P(x_1 |y=1)P(x_2 |y=1)P(x_3 |y=1)P(y=1))/(P(x_1 |y=0)P(x_2 |y=0)P(x_3 |y=0)P(y=0))

当 d>1 时,P(y=1│x)>P(y=0│x),x 属于类别 y=1。

当 d<1 时,P(y=1│x)<P(y=0│x),x 属于类别 y=0。

如果 x_2 缺失,就直接忽略 P(x_2 |y=1) 和 P(x_2 |y=0),判别公式变为

d=(P(y=1│x))/(P(y=0│x) )=(P(x_1 |y=1)P(x_3 |y=1)P(y=1))/(P(x_1 |y=0)P(x_3 |y=0)P(y=0))

上述分类算法叫作朴素贝叶斯算法。“朴素”体现在假设特征的各个维度相互独立上,即对问题进行了简化(这也属于归纳偏置);“贝叶斯”则体现在对模型进行分类时使用了贝叶斯定理上。

解耦后,在前面那个预测女生对男生是否喜欢的概率的例子中,只需估计 2×(3+2+3)=16 种概率,待估计概率由指数级增长变成了线性增长,从而使估计高维特征的概率变得可行。

如果不进行独立性假设,那么:一方面,当 P(x|y) 有特征缺失时,将无法进行概率估计;另一方面,直接估计所有 P(x|y) 不具备可操作性。

在5.3.2节中,我们将讨论如何估计模型中的所有概率,并分析 P(x|y) 难以直接估计的深层原因。

5.3.2 朴素贝叶斯的参数估计

朴素贝叶斯没有显式的参数,其核心在于如何通过训练样本对 P(y=1)、P(y=0)、P(x_i |y=1)、P(x_i |y=0) 等的概率进行估计。

P(y=1) 和 P(y=0) 的概率比较容易估计。如果训练样本是自然采样的(没有刻意进行上下采样平衡),类别 y=1 的样本数量为 N_1,类别 y=0 的样本数量为 N_0,那么

P(y=1)=N_1/(N_1+N_0 )

P(y=0)=N_0/(N_1+N_0 )

P(x_i |y=1) 和 P(x_i |y=0) 的概率估计相对复杂。下面分别对特征 x_i 为离散型和连续型的概率估计进行分析。

例如,在一个预测工作匹配程度的场景中,y=1 表示录用,y=0 表示不录用。当 x_1 为离散变量,例如表示学历时,其取值分别为

1-大专以下;2-大专;3-本科;4-硕士;5-博士

以频率作为概率的估计,公式如下。

P(x_1=本科│y=1)=(count(x_1=本科,y=1))/(count(y=1))

count(y=1) 表示在训练样本中类别为 y=1 且特征 x_1 未发生缺失时的样本数量(不同于 N_1,N_1 为所有类别为 y=1 的样本数量),count(x_1=本科,y=1) 表示类别为 y=1 且对应特征为“x_1=本科”的样本数量。这是一种统计方法,不像梯度下降法那样有迭代过程。这种方法的统计速度非常快,没有复杂的运算和求导过程,只要遍历训练样本就能得到结果。

但是,通过数量比例来估计概率,需要的样本数量相对比较大,如果样本数量不足,就容易出现较大的偏差(例如,在投硬币时,只投1次,出现的是正面,于是估计出现正面的概率为100%,出现反面的概率为0,而这显然是错误的)。因此,可以对上式进行如下改进。

P(x_1=本科│y=1)=(count(x_1=本科,y=1)+n_1/c_1 )/(count(y=1)+n_1 )

n_i 由用户自行定义,c_i 为 x_i 可取值的数量。在本例中,i=1,c_1=5。在这里,相当于给统计量添加了一个先验信息,即在训练样本之外有 n_1 个类别为 y=1 的样本,在这 n_1 个样

本中有 n_1/c_1 个样本的特征为“x_1=本科”。

当 x_2 为连续变量(例如表示工资)时,应该如何估计 P(x_2│y=1) 呢?因为 x_2 是连续的,可以取的值有无数个,所以,显然无法通过上面的频率来估计。一般认为 P(x_2│y=1) 符合正态分布。正态分布只有两个参数,即均值 μ 和方差 σ。所以,可先估计 P(x_2│y=1) 的均值 μ_2 和方差 σ_2。

定义类别为 y=1 且特征 x_2 未缺失的样本索引集合为 Set_(y=1)^(x_2 ),集合中元素的数量为 |Set_(y=1)^(x_2 ) |,公式如下。

μ_2=1/|Set_(y=1)^(x_2 ) | ∑_(i∈Set_(y=1)^(x_2 ))▒〖x_((i),2) 〗

σ_2=√(1/|Set_(y=1)^(x_2 ) | ∑_(i∈Set_(y=1)^(x_2 ))▒(x_((i),2)-μ_2 )^2 )

估计均值和方差后,可以得到 P(x_2│y=1) 的表达式

P(x_2│y=1)=1/(√2π σ_2 ) e^(-〖(x_2-μ_2)〗^2/(2σ_2^2 ))

朴素贝叶斯模型是通过数学方法推导出来的,因此公式相对较多,不过理解起来并不困难。与逻辑回归相比,朴素贝叶斯模型既没有损失函数,也没有迭代学习过程。

如果没有独立性假设,直接估计 P(x|y) 会遇到一些困难,举例如下。

没有特别有效的方法将离散变量和连续变量混在一起估计。

训练样本数量有限。例如,直接估计 P(x_1=1,x_2=0,x_3=1|y=1),同时落在 x_1=1、x_2=0、x_3=1 的样本数量会非常少,而在用频率估计概率时需要较多的样本来保证准确性。

待估计概率随特征维度成指数级增长。

朴素贝叶斯模型因具有简单、有效并能克服特征缺失的优点,在垃圾邮件筛选等文本分类任务中有不凡的表现。

值得注意的是,在使用朴素贝叶斯模型时,特征之间默认是相互独立的。如果实际业务中的特征不是相互独立的,而是有非常强的相关性的,那么,勉强使用朴素贝叶斯模型会得到很差的结果。例如,x_1 为身高,x_2 为体重,x_3 为血型,x_1 和 x_2 其实发生了部分冗余(不是相互独立的),如果通过进行概率估计强行让 x_1 和 x_2 相互独立,就会导致一些因素(身高和体重)的重要性被重复计算,从而降低其他特征(x_3)对分类结果的贡献的权重。

朴素贝叶斯模型忽略了特征之间(例如,在电商场景中,“年轻女性”和“节假日”之间)的交互关系,因此,它通常比其他算法需要更少的数据,且不容易发生过拟合。不过,正因为朴素贝叶斯模型过于简单,其效果的“天花板”也很明显,所以,在一些对准确率要求较高的场景中应谨慎使用。

5.4 维数灾难

本书前面的章节介绍了常见的分类模型。尽管这些模型各有所长,但它们的输入都是特征向量。那么,是否特征向量维度越高(特征数越多),分类效果就越好呢?图5-8展示了维度(特征数)和分类器性能之间的关系(适用于任何分类器)。

图5-8

当特征维度较少时,随着特征维度的增加,分类效果稳步提升。但是,当特征维度增加到一定程度时,继续增加特征维度反而会使分类效果降低。这种现象称为维数灾难。

下面分析一下维数灾难产生的原因。以在二分类任务中使用逻辑回归为例:当特征维度为1维时,分类器对应于一个点;当特征维度为2维时,分类器对应于一条直线;当特征维度为3维时,分类器对应于一个平面。

当特征维度为1维时,所有样本都集中在一条直线上,如图5-9所示。可以看出,两个类别“犬牙交错”地分布在一条直线上,几乎不可能找到一个点将它们分开。此时,模型的效果必然很差。

当特征维度为2维时,数据点在平面上的分布如图5-10所示。此时,数据点是线性不可分的,即一条直线无法把两个类别完全分开,但正确率已经有所提高。

将特征维度增加至3维。此时,数据分布在一个三维坐标系中,如图5-11所示,可以通过一个平面将两个类别完全分开,正确率达到最大值。将三维空间中的平面投影至一个二维坐标系,分类器就不再是线性的了。

图5-9

图5-10

图5-11

这个分类器非常复杂,并且学到了一些特例数据点的特征。因此,尽管训练集对3维特征的效果好于2维特征,但非常容易出现过拟合(在测试集上出现错误),如图5-12所示。

图5-12

随着维度的增加,过拟合现象将会加重,分类器的性能不升反降,产生维数灾难。

下面我们换一个角度讨论维数灾难。

在机器学习中,分类器为特征空间中的一条线(在高维空间中为一个面,具体形状取决于所用分类器和维度),训练过程就是调整线(面)的位置和形状,使其在训练集上尽可能准确。训练数据越多、越密,分类线越不容易被极端特例影响,学到的是具有普遍性的规律;训练数据越少,或者说数据分布越稀疏,分类器越容易学到特例,从而产生过拟合。

用数据密度 ρ 表示训练样本中数据的紧凑程度,ρ=样本数量/数据空间大小。例如,数据取值范围为

[-1,1],数据空间为直线(数据空间大小为2),一共有10个训练样本,在一维空间中数据密度为

ρ_1=10/2=5

当特征维度增加至2维,即 [-1,1]×[-1,1] 时,取值空间变成了一个平面,数据空间大小为 2×2=4,此时数据密度为

ρ_2=10/4=2.5

依此类推,当特征维度为 f,训练样本数量为 N 时,数据密度为

ρ_f=N/2^f

通过上式可以看出,当数据量不变时,随着维度的增加,数据密度以指数级降低,单位空间中的数据点变少,极易发生过拟合,造成维数灾难。因此,在增加数据维度 f 时,为了

保证 ρ_f 不变,训练样本数量 N 应成指数级增长。

维度过高还会带来数据分布不均匀的问题。例如,在二维空间中,数据取值范围为一个矩形(各维度取值为 [-1,1])。假设数据是随机分布的,计算位于中心圆内的数据点占比,如图5-13所示。

r_2=中心圆面积/矩形面积=(π×1^2)/(2×2)=π/4

当特征维度为3维时,计算位于中心球体内的数据点占比,如图5-14所示。

r_3=中心球体体积/立方体体积=(4/3×π〖×1〗^3)/2^3 =π/6

图5-13

图5-14

依此类推,当特征维度为 f 时,超球体体积和超立方体体积分别为

超球体体积=π^(f/2)/Γ(f/2+1) 〖×1〗^f

超立方体体积=2^f

所以

r_f=超球体体积/超立方体体积=π^(f/2)/(Γ(f/2+1)2^f )

可以看出,随着 f 的增大,r_f→0。也就是说,随着维度的增加,中心区域的数据点占

比越来越少,大部分数据点集中在边角处。

维度和超球体体积(中心区域数据占比)的关系,如图5-15所示。

图5-15

例如,在8维空间中,一共有 2^8=256 个角落,约99% 的数据点分布在这些角落,而在中心区域仅有不到1% 的数据点,模型在中心区域极易发生过拟合。

维度过高还会导致一个问题,就是欧氏距离失效。假设有两个 m 维的数据点,x=[x_1,⋯,x_m ]^T,y=[y_1,⋯,y_m ]^T,那么欧氏距离为

其中,s_i=(x_i-y_i )^2。假设特征的各个维度相互独立,当 m→∞ 时,由切比雪夫大数定理,可得

可以看出,随着 m 的增大,所有距离都会收敛至同一个常数 ∑_(i=1)^m▒〖〖E(s〗_i)〗,即所有数据之间

的距离几乎一样,而这将导致欧氏距离不再具有区分能力。

5.5 奥卡姆剃刀定律的应用

奥卡姆剃刀(Occam's Razor)定律是由逻辑学家William of Occam在14世纪提出的,表述为“如无必要,勿增实体”。

奥卡姆剃刀定律阐述了一个朴素的道理:能用简单的方法完成的任务,就不要用复杂的方法,也就是说,“切勿用高射炮打蚊子”,用当下的流行语说就是“极简主义”。那么,该定律如何应用在机器学习中呢?它和正则化又有什么关系呢?

在这里,我们首先需要了解何为模型的复杂度。机器学习中的模型对应的其实是一组函数,模型的训练过程就是从这组函数中选择一个最符合训练样本数据的。模型涵盖的函数越多,模型可能做出的选择就越多,模型就越复杂,模型的拟合能力就越强,越能应对复杂的数据分布。例如,在以下四个模型中,w_0 、w_1 、w_2 均为可变参数。

y=10

y=w_0

y=w_1 x_1+w_0

y=w_2 x_2+w_1 x_1+w_0

第一个模型没有可变参数,实际上只包含一个函数,因此,它在这四个模型中是复杂度最低的,也是最简单的。如果用它去做线性回归,则不可避免地会发生欠拟合(除非数据类别刚好都为 y=10)。但是,用它做线性回归不可能发生过拟合,因为它在训练数据和测试数据上的表现一样差。

第二个模型比第一个模型复杂,它不仅包含第一个模型(当 w_0=10 时),还包含 y=1、y=2 等情况。

第三个模型比第二个模型复杂,第四个模型比前三个模型都复杂。

将上述分析类推至逻辑回归,可以发现:特征维度越高,模型的参数越多,对应的模型就越复杂。奥卡姆剃刀定律希望模型简单,也就是说,当模型已经能完成分类任务时,就不要再扩增特征维度了(这一点和5.4节所讲的维数灾难不谋而合)。

比较了不同特征维度的复杂度,那同一个维度的情况如何呢?我们依然通过逻辑回归模型来分析。采用2维特征,有如下两个模型。

模型1:y^'=1/(1+e^(-(w_2 x_2+w_1 x_1+w_0)) )。

模型2:y^'=1/(1+e^(-(w_2 x_2+w_1 x_1+w_0)) ) 且 w_1^2+w_2^2 ≤ 1。

模型1的参数可以取任意值。模型2对参数的取值范围进行了限制(在半径为1的圆内)。因此,模型1涵盖的函数要多于模型2,模型1更复杂。

使用正则项进行模型训练,其实就是在限制模型参数 w 的取值范围——虽然没有像上述模型2那样直接限制 w 的取值范围,但可以通过给损失函数增加正则项使 w 取较大值的概率显著降低,从而间接实现限制 w 取值范围的效果,使模型得到简化。因此,正则表达式是奥卡姆剃刀定律的一个典型应用。

5.6 经验风险、期望风险和结构风险

在机器学习中,经验风险是指学习完成后模型 f 在训练样本上的平均 Loss,即

R_emp (f)=1/N ∑_(i=1)^N▒〖Loss_((i))=1/N ∑_(i=1)^N▒〖L(y_((i)),f(x_((i))))〗〗

然而,我们不仅希望模型在训练样本上表现得好,更希望它在所有样本(训练样本和尚未见过的样本)上都表现得好。于是,引入期望风险,公式如下。

R_exp (f)=∫_(X×Y)^ ▒〖L(y,f(x))ρ(x,y)dxdy〗

真正好的模型希望 R_exp (f) 足够小。

由于在实际应用中无法获得所有的样本,所以 R_exp (f) 只是一个概念,无法实际计算出来。不过,根据大数定律,当数据量 N 足够大时,经验风险近似于期望风险,即

lim┬(N→∞)⁡〖R_emp (f)〗=R_exp (f)

这就是逻辑回归、线性回归、因子分解模型的理论基础:当训练数据量 N 足够大时,优化经验风险,即最小化 R_emp (f),可近似等价于最小化 R_exp (f)。

但是,数据量 N 多大才算“足够大”呢?并没有人给出明确的答案。而且,在实际应用中,训练样本数量不太容易达到“足够大”。因此,引入结构风险 R_srm (f) 来近似期望风险 R_exp (f),即

R_srm (f)=1/N ∑_(i=1)^N▒〖L(y_((i)),f(x_((i))))〗+λJ(f)=R_emp (f)+λJ(f)≈R_exp (f)

结构风险的第一项仍然为经验风险 R_emp (f),第二项 λJ(f) 是模型复杂度。R_emp (f)+

λJ(f)≈R_exp (f) 的意思是经验风险 R_emp (f) 和期望风险 R_exp (f) 的差异与模型的复杂度 J(f) 成正相关。也就是说,对于同样的经验风险 R_emp (f),模型越复杂,J(f) 就越大,期望风险 R_exp (f) 也就越大。这里的模型复杂度是指模型的参数个数及模型的结构,例如5.5节提到的模型复杂度。

最小化结构风险 R_srm (f) 等价于同时降低经验风险和模型复杂度。通过最小化结构风险 R_srm (f),可以在 N 有限的情况下间接达到最小化期望风险 R_exp (f) 的目的。例如,在训练逻辑回归时增加了正则项优化,即在 Loss 下降的同时使模型复杂度降低(其实就是使结构风险 R_srm (f) 最小化)。最小化结构风险和奥卡姆剃刀定律在降低模型复杂度方面的目标是一致的,它们都希望模型越简单越好。

上述三种风险的推演过程是:设理想目标最小化期望风险为 R_exp (f),但因为不可能得到所有数据,所以实际上无法实现;当数据量 N 足够大时,用经验风险 R_emp (f) 近似期望

风险 R_exp (f),即 R_emp (f) □(⇒┴N足够大 ) R_exp (f)(最小化常见损失函数);当数据量 N 有限时,用

结构风险 R_srm (f) 近似期望风险 R_exp (f),即 □(R_srm (f) ⇒┴N无法达到足够大 ) R_exp (f)(在最小化损失

函数时增加正则项)。

下面分析一下SVM模型的效果特别好的原因。

因为SVM模型的经验风险所对应的损失函数存在最小值0,所以,当数据已经是内部点且可以正确分类时,SVM不会像逻辑回归那样没有限制地降低 Loss 以提升概率。

SVM的另一个目标是最大化边界距离,从而直接优化模型结构。这一点虽然在形式上和逻辑回归使用正则表达式进行优化相同,但在配合上和经验风险不同。在逻辑回归中,“KL距离+正则表达式”会在经验风险和 ‖w‖ 上通过权重进行权衡(整体下降)。而对SVM来说,只要分类正确,降低经验风险的目的就已经达到了(不需要进一步降低),接下来就是全力降低模型复杂度 J(f) 以提高泛化能力了(所以,SVM的泛化能力很强)。通过前面的分析也可以发现,SVM的优化重心在复杂度上,不像逻辑回归那样始终两者兼顾。因此,SVM更符合奥卡姆剃刀定律。


第六章 无监督学习

本书前面提到的各种模型,无论是回归还是分类,在训练阶段都有一个共同的前提条件,即需要有标注的训练样本。标注数据会告诉模型,“对这条数据,输入 x 后,我想要结果 y”。模型会根据要求,使用梯度下降法或其他求解方式,不断调整自身参数,使输出 y^' 尽可能接近标注 y。这类学习统称为有监督学习。标注 y 就是监督信号(也称为教师信号),用于告诉模型数据 x 所对应的正确类别 y。在企业中,标注数据的来源一般是人工标注,以及收集的用户反馈信息。

不过,现实很“残忍”。在互联网时代,企业每天都会产生海量的数据,人工标注的速度不可能赶上数据产生的速度。这就意味着大部分数据缺少人工标注,无法用于有监督学习。尽管我们可以通过收集日志的方法(例如收集用户点击日志或其他用户行为信息)获取有标注的训练样本,但这其实是把标注任务“外包”给了用户,用户获得的“报酬”是免费使用产品。

日志法固然好,但有局限性,例如产品刚上线时没有日志数据可用。另外,需要考虑作弊因素,即被注入的无效数据(这会导致训练样本不准确,训练出来的模型效果不好)。还有一些分类需求,用户需要的是分类结果,但不会提供标注数据,例如资讯类App需要把新闻等文章放入不同的频道以提供给不同的用户,这时就无法利用用户信息了。还有一些场景,例如图像识别、语音识别,标注数据尤其昂贵,甚至催生出一条数据产业链,诞生了不少知名公司。

面对没有标注数据可用的现状,算法工程师们只能感叹“巧妇难为无米之炊”。然而,绝望往往是滋生希望的土壤,针对大量的无标注数据,出现了一系列专门处理这类问题的模型。这些模型不需要使用标注数据(也就是说,只需要 x,不需要 y),而是利用数据自身的分布特点、相对位置来完成分类。这类模型称为无监督学习(y 可以理解成监督信号)或自组织模型。

下面我们从常用的无监督模型K-Means开始探讨无监督学习。

6.1 K-Means聚类

6.1.1 K-Means算法的基本原理

有一批无标注数据,数据点在空间中的分布,如图6-1所示。我们现在希望利用这些数据自身的分布特点自动进行聚类。在这里使用了一种朴素的思想:如果两个数据点的距离比较近,那么它们的类别就应该是一样的。同理,如果一堆数据点彼此接近,那么它们的类别也应该是一样的。于是,将这堆数据点的质心作为这个类别的代表,如图6-2所示。

图6-1

图6-2

需要注意的是:质心点在大部分情况下不是一个真实的数据点。

下面讨论一下如何使用以上朴素的思想对数据进行自动聚类。在无监督学习中,一般可以根据过往经验(拍脑袋)设置一个类别数 K(表示我们希望这堆数据中有多少个类簇)。在训练数据中随机挑选 K=3 个点作为各个类簇的质心,如图6-3所示。对剩下的数据点,分别计算它们和这3个类簇的质心之间的距离。在这里采用欧氏距离,每个点都将归入与它距离最近的类别,如图6-4所示。

图6-3

图6-4

对每个类别来说,一开始质心都是随机挑选的。现在,每个类别都有了一堆数据。对每一类数据的所有点求平均值,将平均值作为新的质心,会产生 K=3 个新的质心,如图6-5所示。

图6-5

定义损失函数 Loss=∑_(i=1)^K▒∑_(x_((j))∈cluster_i)▒〖||x_((j)),μ_i ||〗。K 为类簇数。μ_1~μ_K 表示各类簇的

质心。Loss 的含义是所有数据点 x_((j)) 到它所属类簇的质心 μ_i 的欧氏距离之和。模型训练过

程就是寻找最优的参数 μ_1~μ_K,使得 Loss 最小,而此时也能得到 x_((j)) 所属的类簇。但是,

x_((j))∈cluster_i 的出现将导致 Loss 是一个不连续函数,所以无法直接求解 ∂Loss/(∂μ_i )。不过,我们

可以使用EM算法(Expectation-Maximization Algorithm)来学习 μ_1~μ_K,步骤如下。

 根据经验和业务特点设置类簇数 K,即在所有数据中随机选择 K 个点作为质心 μ_1~μ_K。

 对数据点进行分类,使训练数据中的每个样本都归入与其距离最近的质心所代表的类

别。对于训练样本 x_((j)),其类别为 k=〖arg ( min)┬i〗⁡〖||x_((j)),μ_i ||〗,即 x_((j))∈cluster_k。

 对于类别 i(i=1,⋯,K),用第步的分类结果重新计算质心,也就是求每个类别中样本的平均值,公式如下。

μ_i=1/N_i ∑_(x_((j))∈cluster_i)▒x_((j))

N_i 为归入 cluster_i 的样本数量。

 对以下3个条件进行判断。如果其中任何一个被满足,就可以结束聚类。否则,返回第步。

没有(或最小数目)对象被重新分配给不同的聚类。

没有(或最小数目)聚类中心再发生变化。

Loss=∑_(i=1)^K▒∑_(x_((j))∈cluster_i)▒〖||x_((j)),μ_i ||〗 足够小。

聚类完成后,训练样本中的每个数据点 x_((j)) 都将有一个明确的类别 i(i=1,2,⋯,K)。质心 μ_1~μ_K 用于对非训练样本中的数据进行预测。一个数据点和哪个质心的距离最近,它就属于哪一类,即

k=〖arg min┬i〗⁡〖||x,μ_i ||〗

也就是 x∈cluster_k。

K 是一个超参数,是通过我们的经验设置的。K 越大,分类就越精细;K 越小,分类就越粗糙。上述方法称为K-Means,“K”代表设置的类别数,“Means”(均值)表示在以上第步求质心时使用的平均值。

K-Means算法的结果符合丑小鸭定理——数据是否在一个类簇中并无客观标准,数据是否会聚在一起,完全取决于提取出来的特征。如果特征为蛋白质含量、口感之类,那么鱼和螃蟹就可以归为一类;如果特征为生物学特征,例如有无脊柱、腿的数量之类,那么鱼和螃蟹显然会被分配到不同的类别。因此,特征提取方法隐式地表达了分类标准。

另一个值得注意的要点是,K-Means算法是以欧氏距离为基础的。我们在5.4节讨论维数灾难时提到过,当特征维度过高时,欧氏距离就会失效。因此,在使用K-Means算法时,特征维度不宜过高。

6.1.2 改进型K-Means算法

尽管K-Means算法足够简单,性能也不错,但仍有不少缺点。

K-Means算法对初始点比较敏感。尽管初始点是随机选取的,但选取不同的初始点会对最终的聚类结果产生影响,如图6-6和图6-7所示。

对初始点敏感意味着K-Means算法容易被随机选取的初始点影响,从而使同样的数据产生多种聚类结果。这些结果到底哪个更好呢?对同一批数据,可以重复使用K-Means算法,

每次选取不同的随机初始点,最后将 Loss=∑_(i=1)^K▒∑_(x_((j))∈cluster_i)▒〖||x_((j)),μ_i ||〗 最小的聚类结果作

为最终结果。

图6-6

图6-7

上述算法在数据量很大时往往不够经济,花费的时间和计算成本较高。因此,有人提出了K-Means++ 方法,在选择初始点方面对K-Means方法进行了改进,步骤如下。

 从 N 个数据点中随机选择一个作为类的中心。初始点为 μ_1。

 计算各数据点到已有的聚类中心的距离,并将各样本归入与其距离最近的聚类中心所

在的类别(如果只有初始的一个类别,那么所有样本都归为一个类簇)。对于样本 x_((j)),类

别为 (arg min)┬(i=1,2,⋯,k)⁡〖||x_((j)),μ_i ||〗,k 为当前类簇数。

 计算各数据点到其所属类簇中心的距离 ||x_((j)),μ_i ||。选择距离最远的数据点,将其作

为新的聚类中心 μ_(k+1),即

μ_(k+1)=(arg max)┬█(x_((j) )∈cluster_i@i=1,⋯,k)⁡〖||x_((j)),μ_i ||〗

 重复第步和第步,直至获得 K 个聚类中心为止。然后,将这 K 个聚类中心作为初始聚类中心,重新执行前面的K-Means算法流程。

K-Means++ 找寻初始质心的原则为:各类簇的质心尽可能相互远离,从而为质心的确定提供客观标准。K-Means++ 的运算量不大,没有随机过程,在实际应用中是一种有效的改进方法。

K-Means算法在训练数据的过程中,有时会遇到异常点,如图6-8所示。

图6-8

异常点的出现,会使类簇的质心发生偏移,从而影响最终的效果。针对这个问题,有两个常用的解决方法,具体如下。

第一个方法是,归类完成后,在一个类簇中计算各个点到同一类簇的其他点的平均距离。如果一个点到同一类簇的其他点的平均距离较大,就意味着该点偏离这个类簇中的大多数点,在计算类簇的质心时可将该点作为异常点剔除。

第二个方法是,将质心为类簇内所有点的平均值改为中位数(中位数不容易受极端值的影响)。

若数据点中第 x_1 维特征的变化量远大于其他维,则数据点的分布基本仅由第 x_1 维的特征决定,其他特征的影响很小,如图6-9所示。

图6-9

可以看出,特征 x_2 对聚类结果基本没有影响。该问题的解决方法是:参考逻辑回归,对数据点特征进行归一化,使各个维度的幅度保持一致。

在K-Means算法中,K 一般根据经验来设置,具有一定的主观性。

有一种方法可以客观地确定 K。假设有 N 个数据点,K 的取值范围是 1~N。K 越大,

分类就越细,Loss=∑_(i=1)^K▒∑_(x_((j))∈cluster_i)▒〖||x_((j)),μ_i ||〗 就越小。因此,随着 K 的增大,Loss 会不

断减小,但减小的幅度会越来越小,即 K 增大的边际收益越来越小。当这个边际收益小到一定程度时,就认为增大 K 的意义不大了,将此时的 K 作为分类结果。

K-Loss 关系图,如图6-10所示。

图6-10

当 K<4 时,随着 K 的增大,Loss 的下降速度加快,说明增大 K 的收益是显著的。当 K ≥ 4 时,Loss 的下降速度放缓,说明增大 K 的收益是不显著的。所以,K=4 就是最佳类别数。

有一种情况是K-Means算法无法解决的,即数据点组成两个同心圆,如图6-11所示。

图6-11

此时,我们希望椭圆形为一个类簇,三角形为另一个类簇。但是,直接使用K-Means算法无法聚类成理想的结果。其原因在于,K-Means算法基于一个假设,即在使用欧氏距离进行度量时,同一类别的数据点彼此接近,而同心圆中的数据分布显然不满足这种假设——前提条件不成立,后面的推理都会失败。

为了解决这个问题,可以使用特征转换的方法,将所有数据点 x_((i))=〖[x_((i),1),x_((i),2)]〗^T 转换

成点与圆心的距离 [〖(x〗_((i),1)-r_1 )^2+〖(x_((i),2)-r_2)〗^2],即将2维特征转换成1维特征。尽管特征

维度变小了,但问题得到了解决。这也说明,使数据和模型相匹配比单纯增加维度更有效。

6.1.3 K-Means算法和逻辑回归的结合应用

K-Means算法不仅可以用在聚类上,它和逻辑回归相结合,还能使分类效果得到提升。如图6-12所示,三角形为一类,椭圆形为一类。显然,这是一个线性不可分的数据分布。

图6-12

要想让逻辑回归在线性不可分时有效,就必须对特征进行修改。除了5.5节介绍的维度扩增方法,还可以用K-Means算法辅助完成逻辑回归。首先,忽略标签数据,使用K-Means算法对数据点进行聚类。然后,对每个类簇单独使用一个逻辑回归分类器进行分类。虽然数据整体是线性不可分的,但使用K-Means算法将数据分成两个类簇后,每个类簇中的数据就都是线性可分的了,如图6-13所示。

图6-13

在训练阶段,每个类簇中的数据都对应于一个独立的分类器,每个分类器都使用该类簇的标注数据进行训练。在预测阶段,可先找到输入 x 所对应的类簇 k,再使用该类簇所对应的分类器进行分类。

在一些较为复杂的数据分布中,可以尝试“先对数据进行聚类,再对各类簇单独进行分类”的策略。虽然数据整体情况复杂,但具体到某个类簇,数据的复杂度将会降低。此时,对每个类簇单独训练分类器(不限于逻辑回归),往往能取得不错的效果。

6.2 主题模型

人工智能有一个非常大的应用落地领域,就是自然语言处理。目前市面上的诸多产品,例如推荐系统、搜索系统、对话系统等,都是自然语言处理应用的主战场。

在自然语言处理领域,内容理解是一个重要的方向。内容理解常使用主题(Topic)表示一篇文档的风格和领域倾向,例如“数学”“哲学”都可以作为文档的主题。同时,一篇文档往往不止有一个主题。例如,一篇讨论机器学习的文档,有30% 的主题为“数学”,有70% 的主题为“计算机”。这种以概率形式描述文档在各主题上占比的方法称为主题分布。

文档的主题可以使用分类模型进行预测,但在预测前,需要由领域专家确定文档的主题分布,并收集一批标注了主题的训练样本来训练模型。这是一项需要耗费大量人力的工作,特别是领域专家确定主题分布,是一项见仁见智的工作,没有客观标准。

LDA(Latent Dirichlet Allocation)模型用于推测文档的主题分布,可以将一个文档集中每篇文档的主题以概率分布的形式给出。主题分布可以作为文档的特征,用于文本相似度计算或后续的分类任务。不同于文本分类,LDA是无监督模型,不需要标注数据,模型可以自动从文档集中推测文档所属的主题,且主题本身是通过模型学习得到的,不需要人工设定。

LDA是自然语言处理领域的一个成熟的模型,有严谨的数学理论作为支撑,应用广泛。下面我们来一探LDA的究竟。

6.2.1 LDA模型的原理

在处理文本时,提取文本特征最直接的方式是使用multi-hot编码。

假设词库中有a、b、c、d、e、f、g、h、i、j共10个词,每篇文档都有一个10维的特征向量。如果在一篇文档中,词a出现了两次,词b、e、f各出现了一次,那么这篇文档可以用向量 〖[2,1,0,0,1,1,0,0,0,0]〗^T 来表示。不过,这种方法有很多缺点,列举如下。

汉语的常用词有约20万个,意味着向量长度约为200000,而一篇文档中可能仅出现几百个词,multi-hot向量中会出现大量的0,非常稀疏。

没有考虑词的顺序问题。例如,“我借给你钱”和“你借给我钱”这种意思相反的句子,其multi-hot向量却是一模一样的。

中文的语义歧义问题。例如,“苹果手机”和“吃苹果”中的“苹果”是完全不同的事物,但它们所对应的特征是一样。

对同一事物,表述方法的差异可能很大。例如,“电脑”和“计算机”虽然描述的是同一事物,但对应于不同的特征,因此它们所对应的multi-hot向量的差异很大。

通过以上分析可以发现,multi-hot作为文档的特征向量,存在很多缺点。例如,有三篇文档,如表6-1所示。

表6-1

理想的特征向量应该具备如下特点。

在差异较大的文档(例如《王者荣耀攻略》和《易中天品三国》)中,向量有较大的差异。

相似的文档(例如《王者荣耀攻略》和《绝地求生指南》),向量相似。

向量维度不宜过高,以便进行后续运算。

需要注意的是,相似的文档中词的差异可能比较大,而差异较大的文档中可能有很多共现词。如表6-1所示,从内容的角度看:前两篇文档比较接近,都是关于游戏的,但它们的共现词很少;第三篇文档和前两篇文档几乎没有关系,但如果只看词,就会得到第一篇文档和第三篇文档内容相似的(错误)结论。可见,将词作为文档的特征,不仅有高维空间带来的难度,也有使用时的错误,因此,需要换一种思路,用其他特征来表示文档。

在一篇文档中,词只是“表面现象”,词的背后是一个个主题,它们代表了文档的风格、领域等。站在作者的角度,在写一篇文档前都会构思主题,例如“数学”“计算机”“文学”。主题有时未必能准确地对应到现实概念中具体的一个类。主题往往是抽象(隐式)的,例如“计算机偏数学”“计算机偏编程”这种客观存在但很难用确切的概念来描述的主题。

一篇文档可能对应于多个主题,例如《速通机器学习》70% 属于“计算机”主题,30% 和“数学”沾亲带故;每个主题都以特定的概率分布与词对应,例如在“计算机”主题中,“算法”“神经网络”之类的词会以较大的概率出现,而在“数学”主题中,“公式”“导数”等词出现的概率将高于其他词。需要注意的是,同一个词可以出现在不同的主题中,例如“梯度”可以出现在“计算机”“数学”两个主题中,只不过对应的概率有所不同。

接下来,我们讨论一下如何以主题的方式写一篇文档(这里的文档简化为词袋模型)。词袋模型忽略文档中词之间的顺序,只关心文档中有哪些词,就像把所有词一股脑装进一个袋子里一样。首先,需要确定文档的主题分布,例如《速通机器学习》分别以20% 和80% 的概率对应于主题 t_1 和 t_2。然后,根据上述主题概率选择相应的主题,例如选择 t_1,那么 t_1 就根据其所对应的词的分布生成文档中的一个词 w_1。接下来,重新选择文档主题并生成新的词。上述过程进行 N 次,就得到了一篇有 N 个词的文档。用同样的方法生成文档《算法导论》,其所对应的主题分布与文档《速通机器学习》不同。上述过程,如图6-14所示。

通过以上分析可知,所有文档共同对应于 K 个主题和 V 个词,不同文档的主题分布不同。因此,可以将写作过程类比为轮流投掷两类骰子的过程。

第一类骰子 P_doc (Topic=t|Doc=m) 表示第 m 篇文档的主题为 t 的概率。有 M 篇文档,就有 M 个骰子(m=1,2,3,⋯,M),每个骰子有 K 个面(主题数,t=1,2,3,⋯,K)。风格差异较大的文档,对应的 P_doc (Topic|Doc) 分布不同。

对每个主题 t,生成词 w 的概率为 P_topic (Word=w|Topic=t),即第二类筛子。有

K 个主题,就有 K 个骰子(k=1,2,3,⋯,K),每个骰子有 V 个面(词数,w=

1,2,3,⋯,V)。P_topic (Word|Topic=1) 和 P_topic (Word|Topic=2) 可以反映 t_1 和 t_2

之间的差异。

图6-14

假设文档 m 中有 N 个词,写作过程如下。

 投掷主题筛子 P_doc (Topic=t|Doc=m),得到一个确切的主题 t。

 根据第步得到的主题 t,投掷主题筛子 P_topic (Word=w|Topic=t),生成具体的词 w。

 重复上述过程 N 次。

在这里,需要注意以下两点。

在一篇文档中,如果某个词 w 出现的次数较多,那么可能是由不同的主题骰子(例如 P_topic (Word=w|Topic=1) 和 P_topic (Word=w|Topic=2))投出的。

以上例子使用词袋模型处理文档,忽略了词出现的顺序。尽管词袋模型和真实的写作过程有一定的差异,但它能够大大降低模型的复杂度。

在上述过程中,我们并不知道两类骰子的具体分布。下面就通过机器学习了解一下隐藏在文档后面的这两类骰子。

6.2.2 LDA模型的训练

在正式讲解LDA模型的训练之前,我们来定义一些符号。z_i=t(i=(m,n),是一个二维下标)表示第 m 篇文档的第 n 个词所对应的主题 t,它所对应的词为 w_i=w(w 是一个具体的词,例如“苹果”“算法”)。所有文档一共对应 V 个词和 K 个主题。K 是一个超参数,需要人工设置(类似于K-Means算法里的类别数)。

在语料(M 篇文档)中,w_i=w 是第 m 篇文档的第 n 个词,这是一个已知的客观事实。但是,我们并不知道该词所对应的主题 z_i。LDA模型的学习过程就是求解 z_i 的过程。

为文档中的每个词随机赋予一个主题。例如,z_((1,1))=1,z_((1,2))=3,z_((2,1))=2。在这里,主题只是一个编号,并无大小之分。我们可以得到以下两类计数。

n_m^t 表示第 m 篇文档中对应主题为 t 的词数,n_(m,¬i)^t 表示剔除词 i=(m,n) 后的词数。

n_t^w 表示所有文档中对应主题为 t 的词 w 的数量,n_(t,¬i)^w 表示剔除词 i=(m,n) 后的词数。

为了准确地得到 z_i 所对应的主题,可使用 z_(¬i) 和 w_(¬i)(除 i=(m,n) 外的所有词和对应的主题)来估计 z_i=t 的概率。

首先,不难发现

P(z_i=t|z_(¬i),w_(¬i) )∝P_doc (Topic=t|Doc=m)P_topic (Word=w|Topic=t)

这个式子不难理解,意思是 z_i=t 的概率和以下二者成正比。

主题 t 在第 m 篇文档中出现的概率,表示文档的整体风格。

词 w_i=w 在主题 t 上出现的概率,表示主题 t 的选词倾向。

直接用频率来估计概率,即

P_doc (Topic=t│Doc=m)=(n_(m,¬i)^t)/(∑_(t^'=1)^K▒n_(m,¬i)^(t^' ) )

在这里使用 n_(m,¬i)^k 而不使用 n_m^k 的原因在于,需要使用除词 i=(m,n) 外的所有词来估计 z_i

的概率分布。

为了使函数平滑一些,避免在词的数量过少时出现估计偏差,上式可以改进为

P_doc (Topic=t│Doc=m)=(n_(m,¬i)^t+α_t)/(∑_(t^'=1)^K▒〖〖(n〗_(m,¬i)^(t^' )+α_(t^' ))〗)

α_t 为先验超参数,表示第 m 篇文档在训练样本之外有 α_t 个词属于主题 t。

使用同样的方法,可以得到

P_topic (Word=w│Topic=t)=(n_(t,¬i)^w+β_w)/(∑_(w^'=1)^V▒〖〖(n〗_(t,¬i)^(w^' )+β_(w^' ))〗)

β_w 为先验超参数,表示在训练样本之外有 β_w 个词 w 所对应的主题为 t。

完成 P_doc (Topic=t│Doc=m) 和 P_topic (Word=w|Topic=t) 的估计后,我们看一下如何确定 z_i 所对应的主题。假设有3个主题(K=3),w_i=“导数”,使用上述估计方法,得到 z_i 在 t=(1,2,3) 上的概率(得分),公式如下。

{█(P_doc (Topic=1│Doc=m)=0.2 @P_topic (Word=“导数”│Topic=1)=0.1)┤⟹P(z_i=1|z_(¬i),w_(¬i) )∝0.2×0.1=0.02

{█(P_doc (Topic=2│Doc=m)=0.3 @P_topic (Word=“导数”│Topic=2)=0.3)┤⟹P(z_i=2|z_(¬i),w_(¬i) )∝0.3×0.3=0.09

{█(P_doc (Topic=2│Doc=m)=0.5 @P_topic (Word=“导数”│Topic=3)=0.2)┤⟹P(z_i=3|z_(¬i),w_(¬i) )∝0.5×0.2=0.1

那么,z_i=1、z_i=2、z_i=3 就以0.02∶0.09∶0.1的比例进行概率采样得到。采样结束后,词 i 就有了一个明确的主题,例如 z_i=2。用上述方法遍历文档中的词,每个词都会重新对应于一个主题,即 z_((1,1))=2、z_((1,2))=3、z_((2,1))=1……当所有词的主题更新完毕,就完成了一次迭代。

LDA的训练过程是就是重复上述过程,直至每个词所对应的主题不再发生变化(或者变化较小,或者完成一定的迭代次数)为止,具体如下。

 选择合适的主题数 K(超参数,通常根据经验确定),并为训练样本中的词随机分配一个主题,例如 z_i=2。

 遍历文档中的词 z_i(i=(m,n)),计算 z_i 在各个主题上的得分,然后根据得分进行主题采样,更新 z_i 所对应的主题。得分的计算公式如下。

P(z_i=t|z_(¬i),w_(¬i) )∝P_doc (Topic=t│Doc=m) P_topic (Word=w|Topic=t)

其中

P_doc (Topic=t│Doc=m)=(n_(m,¬i)^t+α_t)/(∑_(t^'=1)^K▒〖〖(n〗_(m,¬i)^(t^' )+α_(t^' ))〗)

P_topic (Word=w│Topic=t)=(n_(t,¬i)^w+β_w)/(∑_(w^'=1)^V▒〖〖(n〗_(t,¬i)^(w^' )+β_(w^' ))〗)

将 z_i 所对应的主题按下述方式进行采样。

P(z_i=1|z_(¬i),w_(¬i) ),⋯,P(z_i=K|z_(¬i),w_(¬i) )

主题采样完成后,每个词都能对应于一个具体的主题,例如 z_i=2。

 当每个词所对应的主题不再发生变化(或者变化较小,或者迭代达到一定次数)时,结束训练。否则,返回第步,重新估计每个词所对应的主题。

训练完成后,每个词都会对应于一个主题。因为进行了多次迭代运算,所以,每个词都会被赋予一个较为合理的主题(相对于一开始的随机分配),n_m^k 和 n_k^t 的值也会稳定下来。

一篇文档可以由其所在的主题分布来表示。假设有 K=3 个主题,对于第 m 篇文档

P_doc (Topic=1│Doc=m)=(n_m^1+α_1)/(∑_(t^'=1)^K▒〖〖(n〗_m^(t^' )+α_(t^' ))〗)=0.2

P_doc (Topic=2│Doc=m)=(n_m^2+α_2)/(∑_(t^'=1)^K▒〖〖(n〗_m^(t^' )+α_(t^' ))〗)=0.3

P_doc (Topic=3│Doc=m)=(n_m^3+α_3)/(∑_(t^'=1)^K▒〖〖(n〗_m^(t^' )+α_(t^' ))〗)=0.5

那么,第 m 篇文档可以由向量 [0.2,0.3,0.5]^T 来表示。

在训练LAD模型时,除了能得到每篇文档的主题,还能得到词 w 在主题 t 上的概率分布,也就是 P_topic (Word=w│Topic=t)。

P_topic (Word=w│Topic=t) 是在所有文档上的全局概率分布,即

P_topic (Word=w│Topic=t)=(n_t^w+β_w)/(∑_(w^'=1)^V▒〖〖(n〗_t^(w^' )+β_(w^' ))〗)

其中

t=1,2,⋯,V k=1,2,⋯,K

训练完成后,训练样本中的每篇文档都会有一个对应的主题。那么在推断阶段,拿到一篇新文档 m+1,应该如何得到其主题分布呢?训练完成后,P_topic (Word=w│Topic=t) 就不再变化了,我们需要推断的只是 P_doc (Topic=t│Doc=m+1),步骤如下。

 给新文档中的每个词随机分配一个主题。

 遍历新文档中的词 z_i(i=(m+1,n)),计算 z_i 在各个主题上的得分,然后使用得分比例采样得到 z_i 所对应的主题。z_i=k 的得分的计算公式如下。

P(z_i=k|z_(¬i),w_(¬i) )∝P_doc (Topic=t│Doc=m+1) P_topic (Word=w│Topic=t)

其中

P_doc (Topic=t│Doc=m+1)=(n_(m+1,¬i)^t+α_t)/(∑_(t^'=1)^K▒〖〖(n〗_(m+1,¬i)^(t^' )+α_(t^' ))〗)

P_topic (Word=w│Topic=t) 为训练过程中得到的结果,无须再次计算。

 重复第步,直至模型稳定。

模型稳定后,新文档中的每个词都会对应于一个主题。因此,可使用 n_(m+1)^t 计算新文档的主题分布,公式如下。

P_doc (Topic=1│Doc=m+1)=(n_(m+1)^1+α_1)/(∑_(t^'=1)^K▒〖〖(n〗_(m+1)^(t^' )+α_(t^' ))〗)=0.3

P_doc (Topic=2│Doc=m+1)=(n_(m+1)^2+α_2)/(∑_(t^'=1)^K▒〖〖(n〗_(m+1)^(t^' )+α_(t^' ))〗)=0.4

P_doc (Topic=3│Doc=m+1)=(n_(m+1)^3+α_3)/(∑_(t^'=1)^K▒〖〖(n〗_(m+1)^(t^' )+α_(t^' ))〗)=0.3

最终,新文档可以由向量 〖[0.3,0.4,0.3]〗^T 来表示。该向量中的每个元素都表示对应位置的主题的强度。

LDA使用主题特征对文档进行表示,具有以下优点。

文档主题是一种深层语义。对于两篇文档使用的词差异很大,但对应的主题分布类似的情况,LDA在计算文档相似度时效果更好。

在处理文本时,相比one-hot编码,主题数 K 一般不会特别大(在中文文档中一般是128~256),从而使文档的特征更加稠密且节省空间。

可以在一定程度上解决一词多义的问题。例如,文档A讲苹果种植,文档B讲苹果手机发布。在文档A中,大部分词与农业有关,P_doc (Topic=“农业”│Doc=文档A)=0.8(较大),词“苹果”会以较大的概率对应于“农业”主题。而在文档B中,词“苹果”所对应的主题是“科技”。

LDA是一个词袋模型,因此,如果场景对词出现的顺序(词序)比较敏感,那么LDA并不适用。所幸在大部分场景(例如文本分类、文本相似度计算)中,词序对结果不会有太大的影响。

LDA在企业中应用广泛,能够对文档进行深层次的语义表示,几乎成为自然语言处理工程师绕不开的技术。随着行业的发展,LDA开始应用在其他领域,举例如下。

在短视频推荐系统中,需要建立用户画像。可以把一个用户当作一篇文档,把用户看过的视频的ID当作词,使用LDA技术把一个用户的观影风格转换成一个主题向量。

一篇较强专业性的文档一般会重点阐述一个知识点,主题分布则集中在少量主题中。因此,可以通过计算主题分布的信息熵来量化文档的专业性。例如,在推荐系统中,可以在垂直频道推荐一些专业性较强的文档,而对缺乏了解的新用户,则推荐一些娱乐新闻类文档。

在推荐系统中,LDA既可用于非个性化的推荐,也可作为内容特征进行内容召回(作为新用户行为特征不足时的补充)。


第七章 集成学习

7.1 决策树

在现实生活中,我们每天都会面对各种抉择,例如根据商品的特征和价格决定是否购买。不同于逻辑回归把所有因素加权求和然后通过Sigmoid函数转换成概率进行决策,我们会依次判断各个特征是否满足预设条件,得到最终的决策结果。例如,在购物时,我们会依次判断价格、品牌、口碑等是否满足要求,从而决定是否购买。决策的流程,如图7-1所示。

图7-1

可以看到,决策过程组成了一棵树,这棵树就称为决策树。在决策树中,非叶子节点选择一个特征进行决策,这个特征称为决策点,叶子节点则表示最终的决策结果。在上例中,我们只是根据经验主观建立了一棵决策树,这棵决策树在数据量和特征维度较小且逻辑简单时是可以使用的。然而,在数据量和特征维度较大时,仅凭主观观察建立决策树显然是不可行的。在实际应用中,训练集中的样本往往有上万个,样本的特征通常有上百维,该怎么处理呢?在实际建立决策树的过程中,每次选择特征都有一套科学的方法。下面就详细讲解如何科学地建立决策树。

不难发现,建立决策树的关键在于选取决策点时使用的判断条件是否合理。每个决策点都要有区分类别的能力。例如,在电商场景中,将发货的快递公司作为决策点的选取条件就是一个很差的选择,其原因在于快递公司和购买行为没有必然联系,而将商品价格作为决策点的选取条件就是合理的,毕竟大部分消费者对商品价格比较敏感。

一个好的决策点可以把所有数据(例如商品)分为两部分(左子树和右子树),各部分数据所对应的类别应尽可能相同(例如购买或不购买),即两棵子树中的数据类别应尽可能“纯”(这种决策点有较高的区分度)。和逻辑回归类似,用已知数据(例如用户的购买记录、商品信息)求解决策树的形状和每个决策点使用的划分条件,就是决策树的训练过程。

首先看一下如何量化数据的纯度。假设在一组数据中有P和N两类样本,它们的数量分别为 n_1 个和 n_2 个。P类样本出现的概率为

P(y=P类)=n_1/(n_1+n_2 )

N类样本出现的概率为

P(y=N类)=n_2/(n_1+n_2 )

我们可以直观地发现:当数据只有一个类别(P(y=N类)=1 或 P(y=P类)=1)时,数据最纯;当两类数据“平分秋色”(P(y=N类)=P(y=P类)=0.5)时,数据最混乱。

可以使用基尼(Gini)系数来量化数据的混乱程度。基尼系数的计算公式如下。

Gini=1-〖P(y=N类)〗^2-〖P(y=P类)〗^2

可见,基尼系数越小,数据就越纯(P(y=N类)=1,Gini=0)。当数据最混乱时,P(y=N类)=P(y=P类)=0.5,也就是说,基尼系数的最大值为0.5。

基尼系数和概率 P(y=N类) 的关系,如图7-2所示。

图7-2

决策树有一些常用的构建方法,在这里我们详细讲解一下最为流行的CART树。CART树是一棵二叉树,它不仅能完成分类任务,还能完成数值预测类的回归任务。下面先介绍分类树,再介绍回归树。在构建CART树时,可以使用基尼系数来度量决策条件的合理性。

假设有 N 个训练样本,特征一共有 m 维,即 x=[■(x_1@⋮@x_m )]。和逻辑回归中特征 x_i 是连

续值不同,在这里,x_i 既可以是连续值(例如价格、好评数、销量等,x_i∈(-∞,+∞)),也可以从集合中“多选一”(例如学历,x_i∈{专科,本科,硕士,博士,其他})。决策树的构建(训练)过程是一个不断生成决策点的过程,每次生成的决策点都要尽可能把训练样本中的两类数据分开。

例如,x_1 为价格,划分条件为 x_1>500,将训练数据分成两类(如果某个样本在划分条件上有特征缺失,就随机分配该样本),如图7-3所示。

图7-3

Data1 中有 M_1 个样本,它们对应于不同的类别,基尼系数为 Gini1。Data1 中的数据越纯(类别越单一),Gini1 就越小。同理,Data2 中有 M_2 个样本,基尼系数为 Gini2。

此次划分的基尼系数为

Gini(x_1>500)=M_1/(M_1+M_2 ) Gini1+M_2/(M_1+M_2 ) Gini2

Gini(x_1>500) 为 Gini1 和 Gini2 加权求和(权重为两堆数据的数量占比)的结果,用于度量划分条件 x_1>500 的合理性。Gini(x_1>500) 越小,说明度量划分越合理。

若 x_2∈{专科,本科,硕士,博士,其他},则可将“x_2=本科”作为划分条件,将数据划分为“x_2=本科”“x_2≠本科”两部分,并计算基尼系数 Gini(x_2=本科)。

遍历所有维度(i=1,2,3,⋯,m)中可能的划分条件,对每种划分方法均可计算相应的基尼系数,例如 Gini(x_1>500)、Gini(x_1>600)、Gini(x_1>400)、Gini(x_2=本科)、Gini(x_2=博士)、Gini(x_3>5)。以最小基尼系数所对应的特征和划分条件为决策点,数据将被划分为两堆。但是,决策树是不停生长的,仅划分一次是不够的,需要再使用同样的方法对每个子堆(Data 1、Data 2)进行划分,最终生成CART树,步骤如下。算法的输入为训练集 D、基尼系数的阈值、样本数量的阈值,输出为决策树 T。算法从根节点开始,用训练集递归建立CART树。

 当前节点的数据集为 D。如果样本数量小于阈值、基尼系数小于阈值或没有特征,则返回决策子树,当前节点停止递归。

 在当前节点的数据上计算各个特征的各个划分条件对划分后的数据的基尼系数。当维度过高且每维所对应的可取值比较多时(例如,价格的值为 1~10000 的整数,将有10000种划分方式;如果为浮点数,划分方式更多),可以随机选取一些特征和划分条件,不再强制要求全部遍历。

 在计算出来的各个特征的各个特征值对数据集 D 的基尼系数中,选择基尼系数最小的特征 x_i 和对应的划分条件,例如“x_i>10”或“x_i=本科”。通过划分条件把数据集划分成 Data1 和 Data2 两部分,同时分别建立当前节点的左节点和右节点,左节点的数据集为 Data1,右节点的数据集为 Data2。

 对 Data1 和 Data2 递归调用以上步骤,生成决策树。

这就是决策树的训练过程。在第步中,判断样本数量和基尼系数是为了控制生成的决策树的深度,避免不停地递归。不停地递归会导致划分条件过细,从而造成过拟合。

决策树建立后,每个叶子节点里都有一堆数据。可以将这堆数据的类别比例作为叶子节点的输出。

决策树在复杂度上和其他模型有所不同。例如,在逻辑回归中,当特征维度不变时,模型的复杂度就确定了。但是,在决策树中,模型会根据训练数据不断分裂,决策树越深,模型就越复杂。可以看出,数据决定了决策树的复杂度,且当数据本身线性不可分时,决策树会非常深,模型会非常复杂。所以,在决策树中,需要设置终止条件,以防模型被数据带到极端复杂的情况中。在决策树中,终止条件的严格程度相当于逻辑回归中正则项的强度。

训练完成后,我们可以得到一棵决策树,如图7-4所示。

在使用决策树时,用数据 x 在决策树上找到对应的叶子节点作为分类结果。例如,当

x=[■(35@1@2)] 时,对应的分类结果为 P(P类)=0.9,P(N类)=0.1。决策树对输入 x 的预测结

果常写为 h(x),h 表示决策树的决策过程。

决策树理解起来比较简单,其本质就是以基尼系数来量化划分条件的分类效果,自动探寻最佳划分条件。

图7-4

下面我们把决策树和逻辑回归进行对比。为了方便对比,假设决策树的特征为2维且均为连续特征。决策树的分类效果图可以理解为如图7-5所示的形式。

图7-5

可见,决策树分类的几何意义和逻辑回归一样,都是在平面上画直线。相比逻辑回归的分类线是一条直线,决策树的分类线是平面上与坐标轴平行的多条直线(一个判断条件对应于一条直线,这些直线共同组成了分类线)。多条直线可以组合成非线性的形式,以处理线性不可分的情况,如图7-6所示。

虽然决策树在训练时需要遍历所有可能的类别划分方法,速度比较慢,但是在预测阶段,决策树只需进行一些逻辑判断和比较,速度非常快,故适合在对时间要求较高的场景中使用。

决策树不仅可以用在分类中,还可以用在回归中(预测连续的值而非类别概率)。用在分类中的决策树称为分类树,用在回归的中决策树称为回归树。在回归任务中,学习目标不再是分类,而是一个连续值 y_i∈(-∞,+∞)。此时,基尼系数不再适用于衡量数据的混乱程度,一般使用方差来衡量数据的混乱程度。

图7-6

例如,当 x_1>20 时,将它作为划分条件,把数据划分为 Data1 和 Data2 两部分,Data1中有 M_1 个样本,Data2 中有 M_2 个样本。

Data1 中数据的混乱程度为

σ_1^2=∑_(i∈Data1)▒〖〖(y〗_((i))-μ_1)〗^2

μ_1 为 Data1 中目标值的平均值,即

μ_1=1/M_1 ∑_(i∈Data1)▒y_((i))

如果 Data1 中所有数据的目标值 y_((i)) 都一样,那么 σ_1=0,此时 Data1 中的数据最纯。

同理,可以求出 Data1 中数据的混乱程度 σ_2^2。

对于划分条件 x_1>20,其对应的混乱程度为

σ(x_1>20)=σ_1^2+σ_2^2

回归树除了使用方差代替基尼系数来度量数据的纯度,其他均与分类树一致,叶子节点输出的值为该节点所有样本目标值的平均值。

7.2 随机森林

通过前面的学习不难发现,CART树是一个强分类器。理论上,它可以对任意数据分布进行分类(不停地划分,直至叶子节点中只有一类数据)。这种强分类器在训练集上能得到非常好的效果。

然而,令人遗憾的是,在测试集(真实场景)中,决策树非常容易发生过拟合,其原因之一就是规则太“硬”。例如,以“年龄>25岁”为条件进行划分,那么26岁和24岁所对应的类别有本质区别吗?当然没有。可见,决策树把特征绝对化了。另外,如果训练样本中有一些极端样本,例如一位75岁的老人购买了一台游戏机,那么,用决策树进行学习,就会得到“年龄>75岁会购买游戏机”的分类结果,而这种异常结果并不是我们想要的。

决策树过于在意降低经验风险,其代价是结构风险较高(决策树不停生长,模型的复杂度越来越高),这也是和奥卡姆剃刀定律相悖的。通过上述分析可以发现,决策树的泛化能力不好,容易学到一些极端特例,非常容易出现过拟合。

综上所述,决策树出现过拟合的原因在于,模型不仅容易对个别特征及其取值过于敏感,还容易被个别样本影响。

为了消除这些问题,我们可以选取部分特征及部分数据来构建决策树,从而在大概率上忽略极端数据。这是一个双重随机过程,具体如下。

第一次随机:设全量样本数为 N,有放回地随机抽取 M 条数据作为训练样本。

第二次随机:在抽取的 M 条数据中,从所有特征 x=[x_1,x_2,⋯,x_m ]^T 中随机选取特征(例如 x_1、x_3、x_5),忽略其他特征。

通过双重随机选取训练样本和特征,可以构建决策树 h_1。重复这个双重随机过程,构建决策树 h_2,h_2,h_3,⋯,h_K。这 K 棵决策树组成一个森林,称为随机森林(Random Forest)。因为在构建这 K 棵决策树时使用的特征和样本不是完全相同的,所以,不同的决策树的形状

可能不同。将这 K 棵决策树的分类结果的平均值作为最终结果,即 y^'=1/K ∑_(i=1)^K▒〖h_i (x)〗。

随机森林的分类流程,如图7-7所示。

图7-7

随机森林的分类线,如图7-8所示。

图7-8

例如,当 K=3 时,分类结果如表7-1所示。随机森林预测为P类的概率为0.6,预测为N类的概率为0.4。

表7-1

在随机森林中,每棵决策树都是一个强分类器。强分类器在训练集上的分类效果很好,但会带来过拟合问题,而过拟合问题产生的原因就是分类器学会了数据中的随机噪声。分类器在有噪声的数据中学习,等价于给各个分类器注入了噪声。因为随机森林的预测结果是多棵决策树投票决定的,而单棵决策树由于数据噪声出现导致的分类错误会通过求平均值的计算得以消除,所以,随机森林的表现一般要优于单棵决策树。

例如,有 n 个符合正态分布的噪声

Noise_i~N(0,σ^2)

噪声的平均值为0,方差为 σ^2。σ^2 越大,说明噪声的负面影响越大。如果 K 棵决策树的输入数据相互独立(Noise_i~Noise_K 相互独立),就可以对噪声进行平均,得到

Noise=1/K ∑_(i=1)^K▒Noise_i ~N(0,σ^2/K)

从上式中可以看出,通过对 K 棵决策树各自的独立噪声进行平均,方差可降至原来的 1/K,噪声的影响将按比例缩小。因此,对多分类器求平均值可以起到降低噪声、提高泛化能力的作用,这就是随机森林的理论基础。

如果噪声来源完全一致,则 Noise~N(0,σ^2),而噪声的方差不会减小。因此,我们希望各决策树相互独立。双重随机过程会尽可能使各决策树在训练时使用的样本相互独立,从而使各决策树相互独立。

要想最大限度发挥随机森林的作用,就要使各决策树相互独立,即所用特征和训练样本都是独立抽取的。做一个极端的假设:如果不使用双重随机方法去训练 K 棵决策树,那么这 K 棵决策树的训练只是简单的复制,错误会同时出现在所有决策树中,问题仍然得不到解决。随机森林的运作模式其实就是“三个臭皮匠,顶个诸葛亮”,即要求“三个臭皮匠”的能力尽可能互补,而不是整齐划一。

将一棵决策树当作一位精通某个较小领域的专家(因为每棵决策树使用的特征不同),这样在随机森林中就有了多位精通不同的较小领域的专家。这样,我们就可以从不同的角度看待一个新问题(新的输入数据),最终通过这些“专家”的“投票”得到结果了。

7.3 GBDT

在二分类决策树中,将特征输入决策树,会得到分类结果

y^'=h(x)

h(x) 决定了特征 x 将落入哪个叶子节点,并给出了对应的输出(值域为 [0,1])。叶子节点的输出只能是 [0,1],这是一个强限制。多个分类器的集成(随机森林)只能通过求平均值的方式进行,以保证最终结果的值域为 [0,1]。

参考逻辑回归,可以对叶子节点进行改造,将 h(x) 的值域扩大至 (-∞,+∞),然后通过Sigmoid函数将其转换成概率,公式如下。

y^'=1/(1+e^(-h(x)) )

此时,决策树已经不是分类树了,而是回归树,可以通过Sigmoid函数将决策结果 h(x) 转换成概率 y^'(可以类比线性回归和逻辑回归之间的关系)。在分类场景中,可以将多棵回归树集成。尽管回归树不会直接给出分类结果,但每棵回归树的叶子节点都有相应的得分 h(x),通过逻辑回归即可将得分转换成概率。

这种方法的好处在于所有决策树都不再受值域的限制,输出更加灵活。类比随机森林,若通过将 K 棵决策树进行集成来完成预测任务,则

y^'=1/(1+e^(-∑_(m=0)^K▒〖h_m (x)〗) )

这就是梯度升级决策树(Gradient Boosting Decision Tree,GBDT)。

同样是多棵决策树集成,GBDT和随机森林的主要区别如下。

在随机森林中,每棵决策树都能独立给出分类结果的概率。对这些概率求平均值,就能得到最终的分类结果。

在GBDT中,每棵决策树只提供一个得分,其集成结果就是将得分相加,然后使用Sigmoid函数将得分转换成概率。

这样做有什么好处呢?GBDT可以使每棵决策树的训练目标不再是最终分类结果,而是前面 k 棵决策树的结果和最终目标的差异(Gap)。这也决定了训练GBDT中的决策树需要

采用串行方法:训练前 k 棵决策树,计算前 k 棵决策树的分类结果 y^'=1/(1+e^(-∑_(m=0)^k▒〖h_m (X)〗) ) 和真

实目标 y 之间的误差;在训练第 k+1 棵决策树时,目标就是这个误差,而不是最终的分类结果。类比复习备考的过程,随机森林就是在每次考试前把所有习题都做一遍,而GBDT只关注在上一次考试中做错的题。

下面具体分析GBDT的学习过程。

假设已经完成前 k 棵决策树的学习(前 k 棵决策树是已知的),那么当前的学习器为

F_k (x)=∑_(m=0)^k▒〖h_m (x)〗

也就是说,对于训练样本 {x_((i)),y_((i))},预测结果为

y_((i))^'=1/(1+e^(-∑_(m=0)^k▒〖h_m (x_((i)))〗) )=1/(1+e^(-F_k (x) ) )

仍然用KL距离来度量 y_((i))^' 和目标 y_((i)) 之间的差异,有

Loss_((i))=-y_((i) ) logy_((i))^'-(1-y_((i) ) )log(1-y_((i))^')

在GBDT中,添加 h_(k+1) (x) 的目标是减小 Loss_((i)),那么 h_(k+1) (x) 取多少才合适呢?添加

h_(k+1) (x),学习器 F_k (x) 将变为 F_(k+1) (x),即 F_(k+1) (x)=F_k (x)+h_(k+1) (x),最终导致分类结

果 y_((i))^' 发生变化。通过对梯度下降法的分析可以知道,为了使 Loss_((i)) 变小,F_(k+1) (x) 应朝着

-(∂Loss_((i)))/(∂F_k (x_((i)) ) ) 的方向变化,即 h_(k+1) (x_((i))) 的学习目标的方向为 r_((i),k+1)=-(∂Loss_((i)))/(∂F_k (x_((i)) ) ),公式如下。

r_((i),k+1)=-(∂Loss_((i)))/(∂F_k (x_((i)) ) )=y_((i) )-y_((i))^'=y_((i) )-1/(1+e^(-F_k (x_((i)) ) ) )

在训练回归树 t_(k+1) (x) 时,使用的训练样本为

〖〖{x〗_((i)),r_((i),k+1)}〗_(i=1)^N

在这里,训练的回归树是 t_(k+1) (x),而不是 h_(k+1) (x),其主要原因是:r_((i),k+1) 是下一棵决策

树的目标方向,而不是真实值(类比逻辑回归,需要给梯度乘以学习因子来修正)。所以,t_(k+1) (x) 只能提供正确的决策点(树结构)。但是,叶子节点的输出值需要修正。若 t_(k+1) (x) 有 j=1,2,⋯,J_(k+1) 个叶子节点,则每个叶子节点的输出值可以修正为

c_(k+1,j)=(∑_(x_((i))∈R_(k+1,j))▒r_((i),k+1) )/(∑_(x_((i))∈R_(k+1,j))▒〖〖(y〗_((i))-r_((i),k+1))〖(1-y〗_((i) )+r_((i),k+1))〗)

R_(k+1,j) 为训练样本中被 t_(k+1) (x) 划分至叶子节点 j 的数据的集合。

因此,t_(k+1) (x) 被修正(只修正叶子节点的输出值,不改变树结构)后就成为待求的决策树 h_(k+1) (x),公式如下。

h_(k+1) (x)=∑_(j=1)^(J_(k+1))▒〖c_(k+1,j) I(x∈R_(k+1,j) ) 〗

I(x∈R_(k+1,j) )={█(1,如果 x∈R_(k+1,j)@0,如果 x∉R_(k+1,j) )┤

因为 x 最终会被划分至一个叶子节点,所以 I(x∈R_(k+1,j) ),j=1,⋯,J_(k+1) 有且仅有一

个为1。此时,学习器更新为

F_(k+1) (x)=F_k (x)+h_(k+1) (x)=∑_(m=0)^(k+1)▒〖h_m (x)〗

依此类推,可以学习 h_(k+2) (x),⋯,h_K (x)。

上述过程就是递归训练 h_k (x)。作为递归的开始,可直接令 h_0 (x)=log P/(1-P),P 表示类别为 y=1 的样本在所有样本中的占比。

综上所述,如果有 N 个训练样本,则整个训练过程如下。

 初始化 h_0 (x)=log P/(1-P)。

 依次训练 h_1,⋯,h_K,共 K 棵决策树。

GBDT的分类流程图,如图7-9所示。不同于随机森林对所有决策树的结果求平均值,GBDT对所有决策树的结果求和,然后通过Sigmoid函数将其转换成分类结果。

图7-9

GBDT是一个非常实用的分类模型。尽管GBDT和随机森林都能对多棵决策树进行集成,但GBDT中的每棵决策树都“站在前人的肩膀上”,相比随机森林的每棵决策树都从零开始更具优势。如果说随机森林多棵决策树集成的目的是防止过拟合,那么GBDT的多棵决策树集成主要用于解决欠拟合问题。在训练时,不同于随机森林,GBDT的各个基学习器 h_k 存在强关联,无法进行并行训练。

在广告、推荐、搜索等领域,点击率在过去很长的时间里是通过逻辑回归模型进行预测的。但是,逻辑回归涉及大量的特征组合,这会消耗大量的人力和算力,依赖大量相关的业务经验。为了解决这些问题,Facebook提出了一种新型算法,先使用GBDT提取数据特征,再使用逻辑回归在提取的特征上进行预测。

一个GBDT模型架构,如图7-10所示。

图7-10

将特征 x 输入GBDT。在这个GBDT中,有3棵决策树,共7个叶子节点,提取后的特征有7维。特征 x 在第一棵决策树中落入第二个叶子节点,在第二棵决策树中落入第一个叶子节点,在第三棵决策树中落入第二个叶子节点,提取的特征为 〖[0,1,0,1,0,0,1]〗^T。将这个特征输入逻辑回归模型,即可完成预测。

这种先用GBDT提取非线性组合特征,再用线性模型(逻辑回归)进行分类的算法,实现了两种模型优势互补。


第八章 深度神经网络

8.1 BP神经网络的基本原理

逻辑回归因其简单、高效、具有可解释性,在工业界得到了广泛的应用并大放异彩。但是,随着业务越来越复杂,分类任务的难度越来越高,逻辑回归渐渐力不从心。分类任务的难度主要体现在数据的线性不可分上——不同类别的数据犬牙交错,很难用一条简单的直线将数据点分开,如图8-1左图所示。为了降低数据分布的复杂性,一般会对特征进行变换和组合,使低维空间中的数据在高维空间中变成线性可分的,如图8-1右图所示。

图8-1

根据上面的思路,逻辑回归有了诸多改良。

人工组合高维特征:将特征升维至高维空间(如果不怕麻烦,可以进行任意维度和阶次的交叉),从而将低维空间中的线性不可分问题转换成高维空间中的线性可分问题。不过,这种方法会耗费较多的人力,并且需要我们对业务特征有很深的理解。在一些重要的场景中,当算法能力达到瓶颈时,人工组合高维特征往往能够出奇制胜。

自动交叉二阶特征:例如,FM(Factorization Machine)算法可自动进行所有二阶特征的交叉。不过,FM算法只能进行二阶交叉,如果需要进行更高阶的交叉(例如“女性”“年轻”“双十一”的交叉),FM算法就无能为力了。

SVM+核方法:可以将特征投影到超高维空间。由于可选的核函数种类有限,SVM升维的“花样”不多,并且伴随着巨大的运算量。

在本质上,上述经典方法都是对“原始输入特征”做文章,通过对特征的变换和组合,将线性不可分问题转换为线性可分问题。不过,上述方法都是针对特定场景精心设计的,一旦实际场景中的特征组合在设计之外,模型就无能为力了。

是否有一种方法,可以根据实际分类任务自动进行特征组合变换呢?答案是肯定的。例如,在二分类场景中,可使用线性变换对特征 x=[x_1,⋯,x_m ]^T 进行变换,形成新特征,如图8-2所示。

图8-2

在图8-2中,w_j^((1))=[w_(1,j)^((1)),⋯,w_(m,j)^((1)) ]^T,转换后的每一维特征都对原始特征 x 进行了不同

角度的线性变换,公式如下。

x_i 为输入特征的第 i 维。d_j^((1)) 表示经过第一次特征变换后第 j 维的特征。M^((1)) 表示第一次特

征变换后的特征维度,可以大于或小于原始特征维度 m(并无特定要求)。w_(i,j)^((1)) 表示进行第

一次特征变换时,第 i 维输入特征连接至第 j 维输出特征的连接权重。

特征变换通常可以简洁地写成矩阵相乘的形式,公式如下。

一般来说,可以对经过线性变换的特征 d 进行非线性转换,公式如下。

a^((1))=f(d^((1))+〖w0〗^((1)) )=[■(〖f(d〗_1^((1))+〖w0〗_1^((1)))@⋮@〖f(d〗_(M^((1)))^((1))+〖w0〗_(M^((1)))^((1))))]

其中,〖w0〗^((1))=[〖w0〗_1^((1)),⋯,〖w0〗_(M^((1)))^((1)) ]^T 称为偏置项,其作用和逻辑回归中的 w_0 类似,也是待学

习参数,用于提升模型的表达能力。非线性变换函数 f 一般称为激活函数,其中最常见的是

Sigmoid,即 f_Sigmoid (d)=1/(1+e^(-d) )。

把经过非线性变换的特征 a^((1)) 输入逻辑回归模型并进行分类,有

d^((2) )=W^((2) ) a^((1) )

y^'=f_Sigmoid (d^((2))+〖w0〗^((2)) )

整个流程图如图8-3所示(略去偏置项)。在进行二分类时,最后一层的节点的默认激活函数为Sigmoid(为了使输出具有概率意义)。需要注意的是,中间层 f(d^((1))+〖w0〗^((1))) 的激活函数 f 的作用是进行非线性变换,Sigmoid函数只是候选函数之一。如果我们要解决的不是分类问题,而是回归问题,则只需要去掉最后一层的激活函数(中间层仍然需要使用激活函数)。

图8-3

图8-2展示了转换方法(线性组合),具体的转换结果需要由参数 W^((1))、〖w0〗^((1))、W^((2))、〖w0〗^((2)) 决定。它们都是待学习参数,一般是通过训练得到的。当我们以分类为目标学习这些参数时,它们会以分类正确为目标自行调整(相当于用分类任务驱动特征组合)。在画图时,一般会将网络中的参数、激活函数等细节省略。这就是经典的BP(Back Propagation)网络,也称为多层感知器(Multi-Layer Perceptron,MLP),如图8-4所示。

图8-4

在图8-4中,每个节点都接收前一层各个节点的信号的加权和,并在对结果进行累加后激活,激活信息将传递给下一层的节点。这个过程和动物神经元细胞传递信号的过程相似。在动物神经元中,树突用于接收来自其所连接的神经元的信号,轴突尾部的神经末梢负责将经过神经元转换的信号传递给其他神经元。神经元的结构,如图8-5所示。

图8-5

BP网络中的节点(对应于图8-4中的圆形)称为神经元,BP网络也称为神经网络。严格地说,BP网络只是神经网络的一种(本书后续将介绍其他神经网络)。BP网络对输入特征进行一次特征变换,采用的方法是“线性变换 + 非线性激活函数”。有研究证明,只要变换后的特征神经元的数量(维度)足够多(高),BP网络就能解决所有分类问题。但是,“足够多”要多到何种程度并未明示,且神经元数量过多会带来过拟合和运算量过大的问题。层中的神经元数量过多,相当于该层转换后的特征维度过高(这会引发维数灾难)。

一般来说,为了使模型性能更好,通常会采用多次特征变换(不求一次到位,但每次变换得到的特征都能更好地满足任务的要求)的方式进行优化。一次特征变换形成一层神经网络,多次特征变换形成多层神经网络,不同层中的神经元数量可以不同。网络结构如图8-6所示。

图8-6

在多层神经网络中,每一层的输出都是下一层的输入,即

在使用多层神经网络时,特征交叉组合异常丰富,模型具备强大的数据处理能力。一般把每层神经元的个数称为神经网络的宽度(各层的宽度可以不同),把网络层数称为神经网络的深度,因此,多层神经网络也称为深度神经网络(Deep Neural Networks,DNN)。在DNN中,网络层数越多,模型的拟合能力就越强,相应的,模型的复杂度就越高。根据奥卡姆剃刀定律,当模型已经能够较好地完成分类任务时,盲目增加层数就是画蛇添足。

多层神经网络主要用于完成分类任务,在训练阶段仍然使用逻辑回归中的KL距离作为损失函数(这一点与逻辑回归无异)。训练样本 〖{x_((i)),y_((i))}〗_(i=1)^N 在网络上的输出为 y_((i))^',损失函数公式如下。

Loss_((i) )=-y_((i) ) logy_((i))^'-(1-y_((i) ) ) log⁡(1-y_((i))^' )

Loss=1/N ∑_(i=1)^N▒〖Loss_((i) ) 〗

在本节的最后,我们对神经网络使用激活函数的必要性进行说明。如果没有激活函数,那么神经网络各层之间的计算都为矩阵相乘。例如,对输入进行两次特征变换(两层),可以得到

可以看出,两次特征变换等价于一次特征变换,即 a^((2))=Wx+w0。因此,如果神经网络不使用非线性激活函数,那么多次特征变换将等价于一次特征变换,深度神经网络在特征提取方面就失去了意义(这也是使用激活函数存在的必要性)。

8.2 多分类与Softmax函数

在实际应用中,多分类任务也是比较常见的。在经典模型中,因为模型相对简单、参数数量较少,逻辑回归、SVM等模型使用 1 vs N-1 法,通过训练 N 个二分类模型来完成多分类任务,或者使用 1 vs 1 法,通过训练 C_N^2 个分类器来完成多分类任务。但是,在深度学习中,模型参数数量较多、单个模型训练速度较慢,使训练多个模型显得不切实际,而且,因为多分类任务的前层特征变换的目标是一致的,所以可以使用同一套特征,没有必要训练多个模型。因此,我们需要改变模型的输出,使模型能够满足多分类的应用场景。

例如,深层神经网络在处理 C 分类问题时,网络层数为 L,最后一层的宽度为 M^((L))=C,使用Softmax作为最后一层的激活函数,有

y^'=[■(y_1^'@⋮@y_C^' )]=Softmax(d^((L) )+〖w0〗^((L) ) )

=Softmax([■(d_1^((L))+〖w0〗_1^((L))@⋮@d_C^((L))+〖w0〗_C^((L)) )])=1/(∑_(m=1)^C▒e^(d_m^((L))+〖w0〗_m^((L)) ) ) [■(e^(d_1^((L))+〖w0〗_1^((L)) )@⋮@e^(d_C^((L))+〖w0〗_C^((L)) ) )]

其中

d^((L))=[■(d_1^((L))@⋮@d_C^((L)) )],〖w0〗^((L))=[■(〖w0〗_1^((L))@⋮@〖w0〗_C^((L)) )]

以上深层神经网络的结构,如图8-7所示(忽略偏置)。

图8-7

M^((L))=C;y_k^' 表示输入 x 属于类别 k 的概率;∑_(m=1)^C▒e^(d_m^((L))+〖w0〗_m^((L)) ) 用于进行归一化,使各

类别的概率之和为1。可以看出,y_k^' 的值不仅受 d_k^((L))+〖w0〗_k^((L)) 的影响,还受其他所有输出的影响(这一点与Sigmoid函数不同)。e^(d_m^((L))+〖w0〗_m^((L)) ) 也称为logit,它与对应的概率成正比,可以理解成尚未进行归一化的概率。当最后一层的激活函数为Softmax时,训练阶段的损失函数沿用KL距离,即

Softmax函数是一种相对特殊的激活函数,仅用在多分类任务的输出层(中间层一般不使用Softmax函数进行激活)。

Softmax函数和Sigmoid函数一样有饱和区。如果 d_i^((L))+〖w0〗_i^((L) ) 的值过大,Softmax函数

就会进入饱和区。此时,d_i^((L)) 的变化对 y_i 的影响非常小且 ∂L/(∂d_i^((L)) )≈0,模型将丧失学习能力。

因此,需要控制神经网络前层输出的值域,以免Softmax函数达到饱和。

值得注意的是,Softmax函数会对概率进行归一化,使各类别的输出的概率之和为1,即

∑_(j=1)^C▒y_j^' =1,因此,它适用于类别互斥且概率之和为1的场景。例如,在文章情感分类预测

场景中,文章所表达的情感为“1=正面,2=负面,3=中性”,适合使用Softmax函数。但是,预测学历的场景(例如“1=大专,2=本科,3=硕士”)就不适合使用Softmax函数,因为其中存在没有考虑到的情况(例如博士、大专以下),即各类别的概率之和不为1。对各类别的概率之和不为1的情况,可对场景略加改造,增加一个类别,例如将预测类别调整为“1=大专,2=本科,3=硕士,4=其他”,以满足Softmax函数的要求。

在考勤打卡场景中,假设公司有10个人,在进行人脸识别时,有类别“1=张三,2=李四,⋯,10=王五,11=高管,12=老板”。这种场景也不适合使用Softmax函数,因为“高管”和“老板”会与其他类别的人重复,即类别不互斥。在类别不互斥的情况下,例如判断音乐的类型(摇滚、流行、古典等)时,输出层仍然可以使用Sigmoid函数作为激活函数,

但此时不能保证 ∑_(j=1)^C▒y_j^' =1。

8.3 梯度下降法和链式法则

前面我们学习了深度神经网络的基本原理,其关键是在各层使用 W^((l)) 和激活函数进行特征变换。不同的 W^((l)) 对应于不同的特征变换方式。如同逻辑回归的参数,这里的 W^((l)) 也需要通过梯度下降法求解。为了方便讨论,我们设计一个 L 层的神经网络,并用它来完成一个多分类任务,以便了解神经网络是如何进行学习的,如图8-8所示。

图8-8

我们面对的是一个分类任务。在解决 C 分类问题时,选择KL距离作为损失函数(这一点与逻辑回归无异)。

单个训练样本 {x_((i) ),y_((i))} 在神经网络上的输出为 y_((i))^'=[y_((i),1)^',⋯,y_((i),C)^' ]^T,它是一个 C×1 维的向量;真实值为类别 y_((i))=[y_((i),1),⋯,y_((i),C) ]^T,它也是一个 C×1 维的向量,但有且仅有一个元素为1,其他元素为0。如8.2节所述,训练样本 {x_((i)),y_((i))} 的损失函数如下。

类似于逻辑回归,使用梯度下降法对参数 W^((l)) 和 〖w0〗^((l)) 进行学习,步骤如下。

 随机初始化各层的 W^((l))、〖w0〗^((l)),l=1,⋯,L,设当前学习轮数(epoch)count=1。

 计算各层的梯度 ∂Loss/(∂W^((l)) )、∂Loss/(∂〖w0〗^((l)) ),l=1,⋯,L。

 分别更新各层的参数 l=1,⋯,L,即

W^((l) )=W^((l) )-μ ∂Loss/(∂W^((l) ) )

〖W0〗^((l))=〖W0〗^((l))-μ ∂Loss/(∂〖w0〗^((l)) )

μ 为学习因子。count=count+1。当 count=epoch(学习达到指定轮数)时,学习结束,否则返回第步,进行下一轮学习。

梯度下降法的整体流程和逻辑回归一样。在理论上,梯度下降法能使 Loss 下降到较小的值,从而学习到合适的 W^((l)) 和 〖w0〗^((l))。但是,理论不等于实际,当神经网络层数较多(L 的

值较大)时,∂Loss/(∂W^((l)) ) 会存在一些问题,使梯度下降法无法顺利使用。

将异常庞大,最终导致 〖∂Loss〗_((i) )/(∂W^((l)) ) 的值过大,在学习过程中发生震荡,甚至发生数值溢出,这就是所谓“梯度爆炸”。

与此相反,如果 f^'<1,则会导致梯度消失。也就是说,〖∂Loss〗_((i) )/(∂W^((l)) ) 的值过小甚至趋近于0会导致学习速度极慢,W^((l)) 几乎得不到更新。

在深度学习中,越靠前(l 的值越小)的层,〖∂Loss〗_((i) )/(∂W^((l)) ) 的累乘项就越多,越容易发生梯度爆炸(消失)。如果 f 为Sigmoid函数,f^' ≤ 0.25,则极易发生梯度消失。因此,当神经网络较深时,中间层的激活函数一般不采用Sigmoid,而采用ReLU。

ReLU函数的表达式为

a=f(d)={█(0,如果 d<0@d,如果 d≥0)┤

ReLU函数的图像,如图8-9所示。

图8-9

当 d ≥ 0 时

f^' (d)≡1

因此,反向传播不会造成梯度消失。

当 d<0 时

f^' (d)≡0

此时,梯度彻底消失。

在实际应用中,我们不用担心梯度彻底消失,原因如下。

在多层神经网络中,d_((i))^((k)) 是一个向量,因此不太容易出现各维度同时小于0的情况,

也就不太容易出现真正的梯度消失,公式如下。

∂Loss/(∂W^((l)) )=1/N ∑_(i=1)^N▒〖∂Loss〗_((i))/(∂W^((l)) ) 用于求解 N 个样本的梯度的平均值。尽管可能会在个别样本上

发生梯度消失,但在 N 个样本上同时发生梯度消失的概率是非常低的。不过,若因激活函数选取不当而导致网络过深,则在所有数据上必然会发生梯度消失(爆炸)。

8.4 度量学习

深度学习除了用于常见的分类、回归等任务,也可用于对各类数据进行向量化。这种向量化不同于在进行特征提取时根据客观数据直接提取特征的方式,它是以任务驱动的形式来提取特征的(使提取的特征能够满足实际需求)。

度量学习(Metric Learning)是一种空间映射方法,通过神经网络将数据(文字、图片等)映射至共同的向量空间。在向量空间中,匹配样本之间的特征向量距离较近,不匹配样本之间的特征向量距离较远。数据之间的相似性由标注数据给出。不同于分类任务将数据标注为 {x_((i) ),y_((i) )},在度量学习中,x_((i) ) 为模型的输入,y_((i)) 为预测值,标注数据由样本对给出,即

{x_((i) ),x_((j) ),y_((i,j) )}

y_((i,j) )=0 或 y_((i,j) )=1 用于标注数据 x_((i) ),x_((j) ) 是否匹配——匹配的数据应该“相像”。

需要注意的是,y_((i,j) ) 仅用于标注匹配与否,不具备传递性,也就是说,下面的情况是有

可能出现的。

{x_((1) ),x_((2) ),1}

{x_((2) ),x_((3) ),1}

{x_((1) ),x_((3) ),0}

x_((1) ) 和 x_((2) ) 匹配,x_((2) ) 和 x_((3) ) 也匹配,但 x_((1) ) 和 x_((3) ) 不匹配,这可以类比为A和B是朋友,A和C也是朋友,但B和C的关系很差。

一般来说,在大批量数据中,匹配的数据往往是少数,大部分数据是不匹配的。因此,

在实际应用中,往往需要人工标注数据 {x_((i) ),x_((j) ),1},样本 {x_((i) ),x_((k) ),0} 则通过随机配对生

成和正样本等量的数据。

度量学习模型仍使用深度神经网络,但模型结构有所变化,x_((i) ) 和 x_((j) ) 分别通过两个模

型计算 〖vector〗_((i)) 和 〖vector〗_((j)) 之间的距离。需要注意的是,神经网络的最后一层的输出为一

个向量,这个向量使用的激活函数一般是Tanh(非必须),以保证值域为 (-1,1),模型结构如图8-10所示。

图8-10

如果 x_((i) ),x_((j) ) 为同一性质的数据(例如都为文字),那么Model 1和Model 2可对应于

同一个模型,即共享参数;如果需要进行图文匹配等异质数据映射,Model 1和Model 2就是

不同的模型,但它们输出的向量在同一空间内,因此具备可比性。需要注意的是,〖vector〗_((i)) 的维度不宜过高,否则容易发生维数灾难,使距离度量失去意义。

若 x_((i) ) 和 x_((j) ) 为匹配样本,即 y_((i,j))=1,则 D_((i,j)) 越小,Loss 越小。若 y_((i,k))=0,则 D_((i,k))

越大,Loss 越小。m 为阈值,用于防止 D_((i,k)) 无限变大引起的过拟合。hingle 为SVM使用

的损失函数,函数图像如图8-11所示。

图8-11

度量学习也可以用Triplet Loss作为损失函数,公式如下。

Loss=∑_█((i,j,k),@y_((i,j))=1,y_((i,k))=0)▒〖hingle(D_((i,j))-D_((i,k))+m)〗

此时,训练样本为一个三元组,即

{x_((i) ),x_((j) ),x_((k) ) }

满足 y_((i,j))=1,y_((i,k))=0。

Triplet Loss的思想是让负样本对之间的距离大于正样本对之间的距离。首先,选取锚定

样本 x_((i) )。然后,选取 x_((j) ) 和 x_((i) ),组成正样本对。同理,选取 x_((k) ) 和 x_((i) ),组成负样本对。

在训练时,同时使用由三个样本组成的两个 Loss(这就是“Triplet Loss”的由来)。训练完成后,可以将数据(文字或图像等)输入模型,得到其输出向量 vector,如图8-12所示。

图8-12

接下来,通过 vector 之间的距离度量数据之间的差异。一般来说,在使用阶段,度量所用的距离与训练阶段一致。

度量学习有什么优势呢?可以通过分类模型的预测结果来衡量两个数据“像”或“不像”。

此时,模型的输入为 x_((i) ) 和 x_((j) ) 的拼接,如图8-13所示。

图8-13

这种方法也能用 y^' 来度量输入 x_((i) ) 和 x_((j) ) 的相似度。分类模型的特征 x_((i) ) 和 x_((j) ) 在模

型工作的开始就进行特征交叉,因此特征交互更加透彻,而度量学习仅在最后计算距离时才将两个数据关联起来。因此,当复杂度接近时,分类模型的效果往往优于度量学习。不过,分类模型仍存在以下不足。

如果 x_((i) ) 和 x_((j) ) 为同质数据,则连接它们的模型参数中的大部分应该是相同的和共

享的,且调换 x_((i) ) 和 x_((j) ) 的输入顺序不会影响结果,即 f(x_((i) ),x_((j) ) )=f(x_((i) ),x_((j) ) )。

但是,分类模型对特征的输入顺序敏感,即大部分时候 f(x_((i) ),x_((j) ) )≠f(x_((i) ),x_((j) ) )。

若 x_((i) ) 和 x_((j) ) 为异质数据(例如,x_((i) ) 为图像,x_((j) ) 为文字),则一般使用与数据类

型匹配的模型来抽取特征(例如,图像对应于CNN,文字一般用LSTM进行特征提取)。很多专业领域的模型都是已经训练好的(例如迁移学习)。但是,因为DNN会忽略数据的特点,僵化地使用同一类型的模型来提取特征,所以其效果不佳,且很难与已经训练好的模型融合。

在实际应用中,神经网络一般比较深,数据量也非常大,如果直接用DNN模型进行在线预测,那么实时的计算量将是巨大的。例如,在相关推荐场景中,需要找出与视频 x_((i) ) 最为接近的10个视频推荐给用户,但候选视频有1000万个,如果每次都以在线方式通过DNN模型计算1000万次并找出得分最高的10个视频,那么机器性能显然跟不上。如果使用度量学习,就可以对这1000万个候选视频所对应的特征进行离线计算,在线上仅需实时计算距离,减轻了线上计算的压力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值