数学之美3 - 线代篇

线代篇

  • 向量空间模型
  • 文本检索
  • 文本聚类
  • 矩阵
  • 线性回归
  • PCA主成分分析
  • 奇异值分解

33 | 线性代数:线性代数到底都讲了些什么?

向量和向量空间

  • 标量(Scalar)。它只是一个单独的数字,而且不能表示方向。从计算机数据结构的角度来看,标量就是编程中最基本的变量。这个很好理解,你可以回想一下刚开始学习编程时接触到的标量类型的变量。
  • 向量(Vector),也可以叫作矢量。它代表一组数字,并且这些数字是有序排列的。我们用数据结构的视角来看,向量可以用数组或者链表来表达。
  • 特征向量(Feature Vector)。由于特征有很多维,因此我们可以使用向量来表示某个物体的特征。其中,向量的每个元素就代表一维特征,而元素的值代表了相应特征的值,我们称这类向量为特征向量。
  • 矩阵的特征向量(Eigenvector)是两码事。那么矩阵的特征向量是什么意思呢?矩阵的几何意义是座标的变换。如果一个矩阵存在特征向量和特征值,那么这个矩阵的特征向量就表示了它在空间中最主要的运动方向。如果你对这几个概念还不太理解,也不用担心,在介绍矩阵的时候,我会详细说说什么是矩阵的特征向量。

向量和标量最大的区别在于,向量除了拥有数值的大小,还拥有方向。向量或者矢量中的“向”和“矢”这两个字,都表明它们是有方向的。你可能会问,为什么这一串数字能表示方向呢?这是因为,如果我们把某个向量中的元素看作座标轴上的座标,那么这个向量就可以看作空间中的一个点。以原点为起点,以向量代表的点为终点,就能形成一条有向直线。而这样的处理其实已经给向量赋予了代数的含义,使得计算的过程中更加直观。

标量和向量的区别,标量只是单独的一个数,而向量是一组数。矩阵是向量的扩展,就是一个二维数组。我们可以使用哈希表的链地址法表示稀疏矩阵。

向量空间

标量和向量之间可以进行运算,比如标量和向量相加或者相乘时,我们直接把标量和向量中的每个元素相加或者相乘就行了,这个很好理解。可是,向量和向量之间的加法或乘法应该如何进行呢?我们需要先定义向量空间。向量空间理论上的定义比较繁琐,不过二维或者三维的座标空间可以很好地帮助你来理解。这些空间主要有几个特性:

  • 空间由无穷多个的位置点组成;
  • 这些点之间存在相对的关系;
  • 可以在空间中定义任意两点之间的长度,以及任意两个向量之间的角度;
  • 这个空间的点可以进行移动。

向量的运算

标量和向量或矩阵的加法、乘法比较简单,就是把这个标量和向量或矩阵中所有的元素轮流进行相加或相乘。

向量之间的加法,是把两者对应的元素相加。

向量之间的相乘分为叉乘和点乘,默认向量乘法为点乘。

点乘的作用是把相乘的两个向量转换成了标量,它有具体的几何含义。我们会用点乘来计算向量的长度以及两个向量间的夹角,所以一般情况下我们会默认向量间的乘法是点乘。至于向量之间的夹角和距离,它们在向量空间模型(Vector Space Model)中发挥了重要的作用。信息检索和机器学习等领域充分利用了向量空间模型,计算不同对象之间的相似程度。

矩阵的运算

矩阵由多个长度相等的向量组成,其中的每列或者每行就是一个向量。因此,我们把向量延伸一下就能得到矩阵(Matrix)。

从数据结构的角度看,向量是一维数组,那矩阵就是一个二维数组。如果二维数组里绝大多数元素都是 0 或者不存在的值,那么我们就称这个矩阵很稀疏(Sparse)。对于稀疏矩阵,我们可以使用哈希表的链地址法来表示。所以,矩阵中的每个元素有两个索引。

我们换个角度来看,向量其实也是一种特殊的矩阵。如果一个矩阵是 n × m 维,那么一个 n × 1 的矩阵也可以称作一个 n 维列向量;而一个 1 × m 矩阵也称为一个 m 维行向量。

同样,我们也可以定义标量和矩阵之间的加法和乘法,我们只需要把标量和矩阵中的每个元素相加或相乘就可以了。

矩阵加法比较简单,只要保证参与操作的两个矩阵具有相同的行维度和列维度,我们就可以把对应的元素两两相加。

矩阵乘法默认为左矩阵的行向量和右矩阵的列向量两两点乘。

其中,矩阵 Z 为矩阵 X 和 Y 的乘积,X 是形状为 i x k 的矩阵,而 Y 是形状为 k × j 的矩阵。X 的列数 k 必须和 Y 的行数 k 相等,两者才可以进行这样的乘法。

我们可以把这个过程看作矩阵 X 的行向量和矩阵 Y的列向量两两进行点乘,我这里画了张图,你理解了这张图就不难记住这个公式了。

两个矩阵中对应元素进行相乘,这种操作也是存在的,我们称它为元素对应乘积,或者 Hadamard 乘积。但是这种乘法咱们用得比较少,所以你只要知道有这个概念就可以了。

转置(Transposition)是指矩阵内的元素行索引和纵索引互换。相应的,矩阵的形状由转置前的 n × m 变为转置后的 m × n。从几何的角度来说,矩阵的转置就是原矩阵以对角线为轴进行翻转后的结果。下面这张图展示了矩阵 X 转置之后的矩阵 X’:

除了转置矩阵,另一个重要的概念是逆矩阵。为了理解逆矩阵或矩阵逆(Matrix Inversion),我们首先要理解单位矩阵(Identity Matrix)。单位矩阵中,所有沿主对角线的元素都是 1,而其他位置的所有元素都是 0。通常我们只考虑单位矩阵为方阵的情况,也就是行数和列数相等,我们把它记做 In,n 表示维数。

如果有矩阵 X,我们把它的逆矩阵记做,两者相乘的结果是单位矩阵,写成公式就是这种形式:

特征值奇异值的概念以及求解比较复杂了,从大体上来理解,它们可以帮助我们找到矩阵最主要的特点。通过这些操作,我们就可以在机器学习算法中降低特征向量的维度,达到特征选择和变换的目的。


34 | 向量空间模型:如何让计算机理解现实事物之间的关系?

什么是向量空间?

首先假设有一个数的集合 F,它满足“F 中任意两个数的加减乘除法(除数不为零)的结果仍然在这个 F 中”,我们就可以称 F 为一个“域”。我们处理的数据通常都是实数,所以这里我只考虑实数域。而如果域 F 里的元素都为实数,那么 F 就是实数域。

我们已经介绍过向量之间的加法,以及标量和向量的乘法。这里我们使用这两个操作来定义向量空间。

假设 V 是 Fn 的非零子集,如果对任意的向量 x、向量 y∈V,都有 (x+y)∈V,我们称为 V 对向量的加法封闭;对任意的标量 k∈V,向量 x∈V,都有 kx 属于 V,我们称 V 对标量与向量的乘法封闭。

如果 V 满足向量的加法和乘法封闭性,我们就称 V 是 F 上的向量空间。向量空间除了满足这两个封闭性,还满足基本运算法则,比如交换律、结合律、分配律等等。这里介绍的定义和法则有点多,不过你可以不用都死记硬背下来。

向量之间的距离

  • 曼哈顿距离

在美国人口稠密的曼哈顿地区,从一个十字路口开车到另外一个十字路口,驾驶距离是多少呢?

城市街区

从图中可以看出,从 A 点到 B 点有多条路径,但是无论哪条,曼哈顿距离都是一样的。

在二维空间中,两个点(实际上就是二维向量)x(x1,x2)与 y(y1,y2)间的曼哈顿距离是:

推广到 n 维空间,曼哈顿距离的计算公式为:

其中 n 表示向量维度,xi 表示第一个向量的第 i 维元素的值,yi 表示第二个向量的第 i 维元素的值。

  • 欧氏距离(Euclidean Distance)

欧氏距离,其实就是欧几里得距离。欧氏距离是一个常用的距离定义,指在 n 维空间中两个点之间的真实距离,在二维空间中,两个点 x(x1,x2)与 y(y1,y2)间的欧氏距离是:

推广到 n 维空间,欧氏距离的计算公式为:

  • 切比雪夫距离(Chebyshev Distance)

切比雪夫其实是在模拟国际象棋里国王的走法。国王可以走临近 8 个格子里的任何一个,那么国王从格子 (x1,x2) 走到格子 (y1,y2) 最少需要多少步呢?其实就是二维空间里的切比雪夫距离。

一开始,为了走尽量少的步数,国王走的一定是斜线,所以横轴和纵轴方向都会减 1,直到国王的位置和目标位置在某个轴上没有差距,这个时候就改为沿另一个轴每次减 1。所以,国王走的最少格子数是 |x1−y1| 和 |x2−y2| 这两者的较大者。所以,在二维空间中,两个点 x(x1,x2)与 y(y1,y2) 间的切比雪夫距离是:

推广到 n 维空间,切比雪夫距离的计算公式为:

闵氏距离

上述三种距离,都可以用一种通用的形式表示,那就是闵可夫斯基距离,也叫闵氏距离。在二维空间中,两个点 x(x1,x2) 与 y(y1,y2) 间的闵氏距离是:

两个 nnn 维变量 x(x1,x2,…,xn) 与 y(y1,y2,…,yn) 间的闵氏距离的定义为:

其中 p 是一个变参数,尝试不同的 p 取值,你就会发现:

  • 当 p=1 时,就是曼哈顿距离;
  • 当 p=2 时,就是欧氏距离;
  • 当 p 趋近于无穷大的时候,就是切比雪夫距离。这是因为当 p 趋近于无穷大的时候,最大的 |xi−yi| 会占到全部的权重。

距离可以描述不同向量在向量空间中的差异,所以可以用于描述向量所代表的事物之差异(或相似)程度。

向量的长度

有了向量距离的定义,向量的长度就很容易理解了。向量的长度,也叫向量的模,是向量所对应的点到空间原点的距离。通常我们使用欧氏距离来表示向量的长度。

当然,我们也可以使用其他类型的距离。说到这里,我也提一下“范数”的概念。范数满足非负性、齐次性、和三角不等式。你可以不用深究这三点的含义,不过你需要知道范数常常被用来衡量某个向量空间中向量的大小或者长度。

  • L1 范数 ||x|| ,它是为 x 向量各个元素绝对值之和,对应于向量 x 和原点之间的曼哈顿距离。
  • L2 范数 ||x||2,它是 x 向量各个元素平方和的 1/2 次方,对应于向量 x 和原点之间的欧氏距离。
  • Lp 范数 ||x||p,为 x 向量各个元素绝对值 p 次方和的 1/p 次方,对应于向量 x 和原点之间的闵氏距离。
  • L∞ 范数 ||x||∞,为 x 向量各个元素绝对值最大那个元素的绝对值,对应于向量 x 和原点之间的切比雪夫距离。

所以,在讨论向量的长度时,我们需要弄清楚是 L 几范数。

向量之间的夹角

在理解了向量间的距离和向量的长度之后,我们就可以引出向量夹角的余弦,它计算了空间中两个向量所形成夹角的余弦值,具体的计算公式我列在了下面:

从公式可以看出,分子是两个向量的点乘,而分母是两者长度(或 L2 范数)的乘积,而 L2 范数可以使用向量点乘自身的转置来实现。夹角余弦的取值范围在 [-1,1],当两个向量的方向重合时夹角余弦取最大值 1,当两个向量的方向完全相反夹角余弦取最小值 -1。值越大,说明夹角越小,两点相距就越近;值越小,说明夹角越大,两点相距就越远

向量空间模型(Vector Space Model)

向量空间模型假设所有的对象都可以转化为向量,然后使用向量间的距离(通常是欧氏距离)或者是向量间的夹角余弦来表示两个对象之间的相似程度。我使用下图来展示空间中向量之间的距离和夹角。

由于夹角余弦的取值范围已经在 -1 到 1 之间,而且越大表示越相似,所以可以直接作为相似度的取值。相对于夹角余弦,欧氏距离 ED 的取值范围可能很大,而且和相似度呈现反比关系,所以通常要进行 1/(1-ED) 这种归一化。

当 ED 为 0 的时候,变化后的值就是 1,表示相似度为 1,完全相同。当 ED 趋向于无穷大的时候,变化后的值就是 0,表示相似度为 0,完全不同。所以,这个变化后的值,取值范围是 0 到 1 之间,而且和相似度呈现正比关系。

早在上世纪的 70 年代,人们把向量空间模型运用于信息检索领域。由于向量空间可以很形象地表示数据点之间的相似程度,因此现在我们也常常把这个模型运用在基于相似度的一些机器学习算法中,例如 K 近邻(KNN)分类、K 均值(K-Means) 聚类等等。


35 | 文本检索:如何让计算机处理自然语言?

什么是信息检索?

信息检索就是让计算机根据用户信息需求,从大规模、非结构化的数据中,找出相关的资料。

这里的“非结构化”其实是针对经典的关系型数据库(Relation Database)而言的,比如 DB2、Oracle DB、MySQL 等等。

布尔模型

在信息检索中,相关性是个永恒的话题。“这篇文章是否和体育相关?”当被问及这个问题,我们要大致看一下文章的内容,才能做出正确的判断。可是,迄今为止,计算机尚无法真正懂得人类的语言,它们该如何判定呢?好在科学家们设计了很多模型,帮助计算机处理基于文本的相关性。

最简单的模型是布尔模型,它借助了逻辑(布尔)代数的基本思想。如果我想看一篇文章是否关于体育,最简单的方法莫过于看看其中是否提到和体育相关的关键词,比如“足球”“NBA”“奥运会”等等。如果有,就相当于返回值为“真”,我就认为这篇文章就是相关的。如果没有,就相当于返回值为“假”,我就认为这篇文章不相关。这就是布尔模型的核心思想。

向量空间模型

和布尔模型相比,向量空间模型更为复杂,也更为合理。如我之前介绍的,此模型的重点是将文档转换为向量,然后比较向量之间的距离或者相似程度。在转换的时候,我们通常会使用词包(Bag Of Word)的方式,忽略了单词在文章中出现的顺序,简化计算复杂度。类似地,这个模型也会把用户输入的查询转换为向量。如此一来,相关性问题就转化为计算查询向量和文档向量之间的距离或者相似度了。距离越小或者说相似度越高,那么我们就认为相关度越高。

相对于标准的布尔数学模型,向量空间模型的主要优势在于,允许文档和查询之间的部分匹配连续的相似程度以及基于这些的的排序。结果不再局限于布尔模型的“真”“假”值。此外,单词或词组的权重可以不再是二元的,而是可以使用例如 tf-idf(term frequency–inverse document frequency)的机制。

信息检索中的向量空间模型

整个方法从大体上来说,可以分为四个主要步骤。

  • 第一步,把文档集合都转换成向量的形式。
  • 第二步,把用户输入的查询转换成向量的形式,然后把这个查询的向量和所有文档的向量,进行比对,计算出基于距离或者夹角余弦的相似度。
  • 第三步,根据查询和每个文档的相似度,找出相似度最高的文档,认为它们是和指定查询最相关的。
  • 第四步,评估查询结果的相关性。

把文档转为特征向量

任何向量都有两个主要的构成要素:维度和取值。这里的维度表示向量有多少维分量、每个分量的含义是什么,而取值表示每个分量的数值是多少。而原始的文本和向量差别很大,我们需要经过若干预处理的步骤。

我们首先来看看如何为文本创建向量的维度。简单地说,我们要把文章中唯一的单词或者词组,作为向量的一个维度。

在概率统计的模块中,我说过如何基于词包(Bag of Word)的方式来预处理文本,包括针对中文等语系的分词操作、针对英文等拉丁语系的词干(Stemming)和归一化(Normalization)处理,以及所有语言都会碰到的停用词(Stopword)、同义词和扩展词处理。完成了前面这些预处理,我们就可以获得每篇文档出现的单词和词组。而通过对所有文档中的单词和词组进行去重,我们就可以构建整个文档集合的词典(Vocabulary)。向量空间模型把词典中的每个词条作为向量的一个维度。

有了向量的维度,我们再来考虑每个维度需要取什么值。最简单的方法是用“1”表示这个词条出现在文档中,“0”表示没有出现。不过这种方法没有考虑每个词的权重。有些词经常出现,它更能表达文章的主要思想,对于计算机的分析能起到更大的作用。对于这点,有两种常见的改进方法,分别是使用词频和词频 x 逆文档频率来实现的。

我们先来看基于词频的方法。假设我们有一个文档集合 c,d 表示 c 中的一个文档,t 表示一个单词,那么我们使用 tf 表示词频(Term Frequency),也就是一个词 t 在文档 d 中出现的次数。这种方法的假设是,如果某个词在文档中的 tf 越高,那么这个词对于这个文档来说就越重要。

另一种改进方法,不仅考虑了 tf,还考虑了 idf。这里 idf 表示逆文档频率(Inverse Document Frequency)。

首先,df 表示文档频率(Document Frequency),也就是文档集合 c 中出现某个词 t 的文档数量。一般的假设是,某个词 t 在文档集合 c 中,出现在越多的文档中,那么其重要性越低,反之则越高。刚开始可能感觉有点困惑,但是仔细想想不难理解。

在讨论体育的文档集合中,“体育”一词可能会出现在上万篇文章中,它的出现并不能使得某篇文档变得和“体育”这个主题更相关。相反,如果只有 3 篇文章讨论到中国足球,那么这 3 篇文章和中国足球的相关性就远远高于其他文章。“中国足球”这个词组在文档集合中就应该拥有更高的权重,用户检索“中国足球”时,这 3 篇文档应该排在更前面。所以,我们通常用 df 的反比例指标 idf 来表示这种重要程度,基本公式如下:

其中 N 是整个文档集合中文章数量,log 是为了确保 idf 分值不要远远高于 tf 而埋没 tf 的贡献。这样一来,单词 t 的 df 越低,其 idf 越高,t 的重要性越高。那么综合起来,tf-idf 的基本公式表示如下:

一旦完成了从原始文档到向量的转换,我们就可以接受用户的查询(Query)。

查询和文档的匹配

在计算查询和文档的相似度之前,我们还需要把查询转换成向量。由于用户的查询也是由自然语言组成,所以这个转换的流程和文档的转换流程是基本一致的。不过,查询也有它的特殊性,因此需要注意下面几个问题。

  • 第一,查询和文档长度不一致。人们输入的查询通常都很短,甚至都不是一个句子,而只是几个关键词。这种情况下,你可能会觉得两个向量的维度不同,无法计算它们之间的距离或夹角余弦。对于这种情况,我们可以使用文档字典中所有的词条来构建向量。如果某维分量所对应的词条出现在文档或者查询中,就取 1、tf 或 tf-idf 值,如果没有就取 0。这样,文档向量和查询向量的维度就相同了,只是查询向量更稀疏、拥有多维度的 0。
  • 第二,查询里出现了文档集合里没有的词。简单的做法是直接去除这维分量,也可以使用相对于其他维度来说极小的一个数值,这和分类中的平滑技术类似。
  • 第三,查询里词条的 idf 该如何计算。如果我们使用 tf-idf 机制来计算向量中每个维度的取值,那么就要考虑这个问题。由于查询本身并不存在文档集合的概念,所以也就不存在 df 和 idf。对于这种情况,我们可以借用文档集合里对应词条的 idf。

把查询转换成向量之后,我们就可以把这个查询的向量和所有文档的向量依次对比,看看查询和哪些文档更相似。我们可以结合上一节所说的,计算向量之间的距离或者夹角余弦。由于夹角余弦不用进行归一化,所以这种方法更为流行。需要注意的是,信息检索里,夹角余弦的取值范围通常是 [0,1],而不再是 [-1,1]。这是因为在进行文本处理的时候,我们根据单词的出现与否,设置 0、1/tf/tf-idf,因此向量每个分量的取值都是正的。

在概率统计模块中,我介绍过特征选择和特征值的转换。由于文本向量往往是非常稀疏的,我们也可能需要对转换后的文档和查询向量,进行这两项操作。

排序和评估

完成了前两步,后面的排序和评估就很直观了。我们按照和输入查询的相似程度,对所有文档进行相似度由高到低的排序,然后取出前面的若干个文档,作为相关的信息返回。当然,这里你需要注意,这里所说的“相关性”是从向量空间模型的角度出发,不代表所返回的信息一定满足用户的需求。因此,我们还需要设计各种离线或者在线的评估,来衡量向量空间模型的效果。

总结

今天我从文本的信息检索出发,介绍如何使用向量空间模型。在使用这个模型之前,很重要的处理步骤,就是要把原始数据转换成向量。这里所说的数据类型是文本,所以我们要进行分词等操作,然后构建文档的字典,并使用字典的词条来构建向量。如果是其他类型的数据,我们则需要提取相应的特征,并利用这些特征来构建向量。

如果我们把查询也转换成向量,那么就可以计算查询向量和文档向量之间的相似度。通过这种相似度,我们就能对所有的文档进行排序,找出向量空间模型认为“最相关”的文章。

假设查询的平均长度(或词条数量)远远小于文档的平均长度,我们把查询的平均长度记做 m,那么对于每次计算查询向量和文档向量的相似度,时间复杂度都是 O(m)。假设文档集中文档的数量平均是 n,那么根据时间复杂度的四则运算法则,把查询和所有文档比较的时间复杂度是 O(m*n)。

其实,在第 17 讲我曾经提到过了倒排索引的案例,我们可以把倒排索引和向量空间模型相结合。倒排索引可以快速找到包含查询词的候选文档,这样就避免了不必要的向量计算。更多具体的内容,我会在之后的实战模块为你详细讲解。


36 | 文本聚类:如何过滤冗余的新闻?

监督式学习 & 非监督学习

在概率统计模块中,我们介绍了分类(Classification/Categorization)和回归(Regression)这两种监督式学习(Supervised Learning)。监督式学习通过训练资料学习并建立一个模型,并依此模型对新的实例进行预测。

不过,在实际场景中,我们常常会遇到另一种更为复杂的情况。这时候不存在任何关于样本的先验知识,而是需要机器在没人指导的情形下,去将很多东西进行归类。由于缺乏训练样本,这种学习被称为“非监督学习”(Unsupervised Learning),也就是我们通常所说的聚类(Clustering)。在这种学习体系中,系统必须通过一种有效的方法发现样本的内在相似性,并把数据对象以群组(Cluster)的形式进行划分。

K 均值(K-Means)聚类算法

这个算法的名称是 K 均值(K-Means)聚类算法,它让我们可以在一个任意多的数据上,得到一个事先定好群组数量(K)的聚类结果。这种算法的中心思想是:尽量最大化总的群组内相似度,同时尽量最小化群组之间的相似度。群组内或群组间的相似度,是通过各个成员和群组质心相比较来确定的。想法很简单,但是在样本数量达到一定规模后,希望通过排列组合所有的群组划分,来找到最大总群组内的相似度几乎是不可能的。于是人们提出如下的求近似解的方法。

  • 从 N 个数据对象中随机选取 k 个对象作为质心,这里每个群组的质心定义是,群组内所有成员对象的平均值。因为是第一轮,所以第 i 个群组的质心就是第 i 个对象,而且这时候我们只有这一个组员。
  • 对剩余的对象,测量它和每个质心的相似度,并把它归到最近的质心所属的群组。这里我们可以说距离,也可以说相似度,只是两者呈现反比关系。
  • 重新计算已经得到的各个群组的质心。这里质心的计算是关键,如果使用特征向量来表示的数据对象,那么最基本的方法是取群组内成员的特征向量,将它们的平均值作为质心的向量表示。
  • 迭代上面的第 2 步和第 3 步,直至新的质心与原质心相等或相差之值小于指定阈值,算法结束。

我以二维空间为例子,画张图来展示一下数据对象聚类的过程。

在这张图中,( a )、( b )、( c ) 三步分别展示了质心和群组逐步调整的过程。我们一一来看。(a) 步骤是选择初始质心,质心用不同颜色的 x 表示;( b ) 步骤开始进行聚类,把点分配到最近的质心所在的组;( c ) 步骤重新计算每个群组的质心,你会发现 x 的位置发生了改变。之后就是如此重复,进入下一轮聚类。

总的来说,K 均值算法是通过不断迭代、调整 K 个聚类质心的算法。而质心或者群组的中心点,是通过求群组所包含的成员之平均值来计算的。

使用向量空间进行聚类

以文本聚类为例,讲讲如何使用向量空间模型和聚类算法,去除重复的新闻。

我们在看新闻的时候,一般都希望不断看到新的内容。可是,由于现在的报道渠道非常丰富,经常会出现热点新闻霸占版面的情况。假如我们不想总是看到重复的新闻,应该怎么办呢?有一种做法就是对新闻进行聚类,那么内容非常类似的文章就会被聚到同一个分组,然后对每个分组我们只选择 1 到 2 篇显示就够了。

基本思路确定后,我们可以把整个方法分为三个主要步骤。

第一步,把文档集合都转换成向量的形式。

第二步,使用 K 均值算法对文档集合进行聚类。这个算法的关键是如何确定数据对象和分组质心之间的相似度。针对这点,我们有两个点需要关注。

  • 使用向量空间中的距离或者夹角余弦度量,计算两个向量的相似度。
  • 计算质心的向量。K 均值里,质心是分组里成员的平均值。所以,我们需要求分组里所有文档向量的平均值。求法非常直观,就是分别为每维分量求平均值,我把具体的计算公式列在这里:

其中,xi 表示向量的第 i 个分量,xij 表示第 j 格向量的第 i 个分量,而 j=1,2,…,n 表示属于某个分组的所有向量。

第三步,在每个分类中,选出和质心最接近的几篇文章作为代表。而其他的文章作为冗余的内容过滤掉。

使用 Python 里的 sklearn 库,来展示使用欧氏距离的 K 均值算法。

Python 中的 K 均值算法

在尝试下面的代码之前,你需要看看自己的机器上是不是已经安装了 scikit-learn。Scikit-learn 是 Python 常用的机器学习库,它提供了大量的机器学习算法的实现和相关的文档,甚至还内置了一些公开数据集,是我们实践机器学习算法的好帮手。

首先,我使用 sklearn 库中的 CountVectorizer,对一个测试的文档集合构建特征,也就是词典。这个测试集合有 7 句话,2 句关于篮球,2 句关于电影,还有 3 句关于游戏。

总结

这一节,我介绍了如何在机器学习的聚类算法中,使用向量空间模型。在聚类中,数据对象之间的相似度时很关键的。如果我们把样本转换为向量,然后使用向量空间中的距离或者夹角余弦,就很自然的能获得这种相似度,所以向量空间模型和聚类算法可以很容易的结合在一起。


37 | 矩阵(上):如何使用矩阵操作进行PageRank计算?

回顾 PageRank 链接分析算法

PageRank 是基于马尔科夫链的。它假设了一个“随机冲浪者”模型,冲浪者从某张网页出发,根据 Web 图中的链接关系随机访问。在每个步骤中,冲浪者都会从当前网页的链出网页中,随机选取一张作为下一步访问的目标。此外,PageRank 还引入了随机的跳转操作,这意味着冲浪者不是按 Web 图的拓扑结构走下去,只是随机挑选了一张网页进行跳转。

基于之前的假设,PageRank 的公式定义如下:

其中,pi 表示第 i 张网页,Mi 是 pi 的入链接集合,pj 是 Mi 集合中的第 j 张网页。PR(pj) 表示网页 pj 的 PageRank 得分,L(pj)表示网页 pj 的出链接数量,1/L(pj) 就表示从网页 pj 跳转到 pi 的概率。α 是用户不进行随机跳转的概率,N 表示所有网页的数量。

PageRank 的计算是采样迭代法实现的:一开始所有网页结点的初始 PageRank 值都可以设置为某个相同的数,例如 1,然后我们通过上面这个公式,得到每个结点新的 PageRank 值。每当一张网页的 PageRank 发生了改变,它也会影响它的出链接所指向的网页,因此我们可以再次使用这个公式,循环地修正每个网页结点的值。由于这是一个马尔科夫过程,所以我们能从理论上证明,所有网页的 PageRank 最终会达到一个稳定的数值。整个证明过程很复杂,这里我们只需要知道这个迭代计算的过程就行了。

简化 PageRank 公式

那么,这个计算公式和矩阵操作又有什么联系呢?为了把问题简化,我们暂时不考虑随机跳转的情况,而只考虑用户按照网页间链接进行随机冲浪。那么 PageRank 的公式就简化为:

我们再来对比看看矩阵点乘的计算公式。

以上两个公式在形式上是基本一致的。因此,我们可以把 Σ(PR(pj)/L(pj)) 的计算,分解为两个矩阵的点乘。一个矩阵是当前每张网页的 PageRank 得分,另一个矩阵就是邻接矩阵。所谓邻接矩阵,其实就是表示图结点相邻关系的矩阵。

考虑随机跳转

我们把 Σ(PR(pj)/L(pj)) 部分用 A 表示,那么完整的 PageRank 公式就可以表示为:

于是,我们可以把上述公式分解为如下两个矩阵的点乘

我们前面提到,PageRank 算法需要迭代式计算。为了避免计算后的数值越来越大甚至溢出,我们可以进行归一化处理,保证所有结点的数值之和为 1。

接下来,我们只需要再重复之前的步骤,直到每个结点的值趋于稳定就可以了。

使用 Python 进行实现

说到这里,我已经把如何把整个 PageRank 的计算,转换成多个矩阵的点乘这个过程讲完了。这样一来,我们就可以利用 Python 等科学计算语言提供的库,来完成基于 PageRank 的链接分析。

总结

我们可以把向量看作一维数组,把矩阵看作二维数组。矩阵的点乘,是由若干个向量的点乘组成的,所以我们可以通过矩阵的点乘操作,挖掘多组向量两两之间的关系。

今天我们讲了矩阵的点乘操作在 PageRank 算法中的应用。通过表示网页的邻接二元关系,我们可以使用矩阵来计算 PageRank 的得分。在这个应用场景下,矩阵点乘体现了多个马尔科夫过程中的状态转移。

矩阵点乘和其他运算操作,还可以运用在很多其他的领域。例如,我在上一节介绍 K 均值聚类算法时,就提到了需要计算某个数据点向量、其他数据点向量之间的距离或者相似度,以及使用多个数据点向量的平均值来获得质心点的向量,这些都可以通过矩阵操作来完成。

另外,在协同过滤的推荐中,我们可以使用矩阵点乘,来实现多个用户或者物品之间的相似程度,以及聚集后的相似程度所导致的最终推荐结果。


38 | 矩阵(下):如何使用矩阵操作进行协同过滤推荐?

我这里说的推荐,是指为用户提供可靠的建议、并协助用户挑选物品的一种技术。一个好的推荐系统需要建立在海量数据挖掘基础之上,并根据用户所处的情景和兴趣特点,向用户推荐可能感兴趣的信息和商品。

协同过滤(Collaborative Filtering)是经典的推荐算法之一,它充分利用了用户和物品之间已知的关系,为用户提供新的推荐内容。我会从这种二元关系出发,给你讲讲如何使用矩阵计算,来实现协同过滤推荐算法。

用矩阵实现推荐系统的核心思想

矩阵中的二维关系,除了可以表达图的邻接关系,还可以表达推荐系统中用户和物品的关系。

简单地理解就是,推荐系统会根据用户所处的场景和个人喜好,推荐他们可能感兴趣的信息和商品。比如,你在阅读一部电影的影评时,系统给你推荐了其他“你可能也感兴趣的电影”。可以看出来,推荐系统中至少有 2 个重要的角色:用户和物品。用户是系统的使用者,物品就是将要被推荐的候选对象。

在此之前,我们先来看什么是协同过滤。你可以把它理解为最直观的“口口相传”。假设我们愿意接受他人的建议,尤其是很多人都向你建议的时候。其主要思路就是利用已有用户群过去的行为或意见,预测当前用户最可能喜欢哪些东西。根据推荐依据和传播的路径,又可以进一步细分为基于用户的过滤和基于物品的过滤。

基于用户的过滤

首先,我们来看基于用户的协同过滤。它是指给定一个用户访问(我们假设有访问就表示有兴趣)物品的数据集合,找出和当前用户历史行为有相似偏好的其他用户,将这些用户组成“近邻”,对于当前用户没有访问过的物品,利用其近邻的访问记录来预测。我画了一张图方便你理解。

根据这张图的访问关系来看,用户 A 访问了物品 A 和 C,用户 B 访问了物品 B,用户 C 访问了物品 A,C 和 D。我们计算出来,用户 C 是 A 的近邻,而 B 不是。因此系统会更多地向用户 A 推荐用户 C 访问的物品 D。

理解了这个算法的基本概念,我们来看看如何使用公式来表述它。假设有 m 个用户,n 个物品,那么我们就能使用一个 m×n 维的矩阵 X 来表示用户对物品喜好的二元关系。基于这个二元关系,我们可以列出下面这两个公式:

其中,第一个公式比较容易理解,它的核心思想是计算用户和用户之间的相似度。完成了这一步我们就能找到给定用户的“近邻”。

我们可以使用向量空间模型中的距离或者是夹角余弦来处理,在这里我使用了夹角余弦,其中 usi1,i2 表示用户 i1 和 i2 的相似度,而 Xi1 表示矩阵中第 i1 行的行向量。分子是两个表示用户的行向量之点乘,而分母是这两个行向量 L2 范数的乘积。

第二个公式利用第一个公式所计算的用户间相似度,以及用户对物品的喜好度,预测任一个用户对任一个物品的喜好度。其中 pi,j 表示第 i 用户对第 j 个物品的喜好度,usi,k 表示用户 i 和 k 之间的相似度,xk,j 表示用户 k 对物品 j 的喜好度。注意这里最终需要除以 Σusi,k,是为了进行归一化。

从这个公式可以看出,如果 usi,k 越大,xk,j 对最终 pi,j 的影响越大,反之如果 usi,k 越小,xk,j 对最终 pi,j 的影响越小,充分体现了“基于相似用户”的推荐。

上面这种基于用户的协同过滤有个问题,那就是没有考虑到用户的喜好程度是不是具有可比性。假设用户的喜好是根据对商品的评分来决定的,有些用户比较宽容,给所有的商品都打了很高的分,而有些用户比较严苛,给所有商品的打分都很低。分数没有可比性,这就会影响相似用户查找的效果,最终影响推荐结果。这个时候我们可以采用之前介绍的特征值变化,对于原始的喜好度矩阵,按照用户的维度对用户所有的喜好度进行归一化或者标准化处理,然后再进行基于用户的协同过滤。

基于物品的过滤

基于物品的协同过滤是指利用物品相似度,而不是用户间的相似度来计算预测值。我同样用图来帮助你理解。

在这张图中,物品 A 和 C 因为都被用户 A 和 B 同时访问,因此它们被认为相似度更高。当用户 C 访问过物品 A 后,系统会更多地向用户推荐物品 C,而不是其他物品。

基于物品的协同过滤同样有两个公式,你可以看一下。

第一个公式的核心思想是计算物品和物品之间的相似度,在这里我仍然使用夹角余弦。其中 isj1,j2 表示物品 j1 和 j2 的相似度,而 Xj 表示了 X 中第 j1 列的列向量,而 Xj2 表示了 X 中第 j2 列的列向量。分子是两个表示物品的列向量之点乘,而分母是这两个列向量 L2 范数的乘积。

第二个公式利用第一个公式所计算的物品间相似度,和用户对物品的喜好度,预测任一个用户对任一个物品的喜好度。其中 pi,j 表示第 i 用户对第 j 个物品的喜好度,xi,k 表示用户 i 对物品 k 的喜好度,isk,j 表示物品 k 和 j 之间的相似度,注意这里除以 Σisk,j 是为了进行归一化。从这个公式可以看出,如果 isk,j 越大,xi,k 对最终 pi,j 的影响越大,反之如果 isk,j 越小,xi,k 对最终 pi,j 的影响越小,充分体现了“基于相似物品”的推荐。

类似地,用户喜好程度的不一致性,同样会影响相似物品查找的效果,并最终影响推荐结果。我们也需要对于原始的喜好度矩阵,按照用户的维度对用户的所有喜好度,进行归一化或者标准化处理。

总结

今天我首先简要地介绍了推荐系统的概念和主要思想。为了给用户提供可靠的结果,推荐系统需要充分挖掘历史数据中,用户和物品之间的关系。协同过滤的推荐算法就很好地体现了这一点。

一旦涉及用户和物品的这种二元关系,矩阵就有用武之地了。我通过矩阵来表示用户和物品的关系,并通过矩阵计算来获得协同过滤的结果。协同过滤分为基于用户的过滤和基于物品的过滤两种,它们的核心思想都是相同的,因此矩阵操作也是类似的。在这两个应用场景下,矩阵点乘体现了多个用户或者物品之间的相似程度,以及聚集后的相似程度所导致的最终推荐结果。

当然,基于用户和物品间关系的推荐算法有很多,对矩阵的操作也远远不止点乘、按行求和、元素对应乘除法。我后面会介绍如何使用矩阵的主成分分析或奇异值分解,来进行物品的推荐。


39 | 线性回归(上):如何使用高斯消元求解线性方程组?

回归分析

机器学习中两类很重要的方法:回归分析以及线性回归。回归分析属于监督式学习算法,主要研究一个或多个随机变量 y1,y2,…,yi 与另一些变量 x1,x2,…,xi 之间的关系。其中,我们将y1,y2,…,yi 称为因变量,x1,x2,…,xi 称为自变量。按照不同的维度,我们可以把回归分为三种。

  • 按照自变量数量,当自变量 x 的个数大于 1 时就是多元回归。
  • 按照因变量数量,当因变量 y 个数大于 1 时就是多重回归。
  • 按照模型种类,如果因变量和自变量为线性关系时,就是线性回归模型;如果因变量和自变量为非线性关系时时,就是非线性回归分析模型。

高斯消元法

求解线性方程组最常见的方法之一,高斯消元法。这个方法主要包含了消元回代两个步骤。这些步骤都可以使用矩阵的操作来进行。

从矩阵的角度来说,消元就是把系数矩阵变为上三角矩阵,而回代是把这个上三角矩阵变为单位矩阵

我们可以直接把用于消元和回代的矩阵,用于由系数和因变量值组成的增广矩阵,并获得最终的方程解。

线性回归分析时,方程组的处理方式和普通的方程组求解

线性方程组的概念,也是线性回归分析的基础。在线性回归时,我们也能获得由很多观测数据值所组成的方程组。但是,在进行线性回归分析时,方程组的处理方式和普通的方程组求解有一些不同。其中有两个最主要的区别。

  • 第一个区别是,在线性回归分析中,样本数据会告诉我们自变量和因变量的值,要求的是系数。而在线性方程组中,我们已知系数和因变量的值,要求的是自变量的值。
  • 第二个区别是,在线性回归分析中,方程的数量要远远大于自变量的数量,而且我们不要求每个方程式都是完全成立。这里,不要求完全成立的意思是,拟合出来的因变量值可以和样本数据给定的因变量值存在差异,也就允许模型拟合存在误差。模型拟合的概念我在上一模块的总结篇中重点讲解了,所以你应该能理解,模型的拟合不可能 100% 完美,这和我们求解线性方程组精确解的概念是不同的。正是因为这两点差异,我们无法直接使用消元法来求解线性回归。

40 | 线性回归(中):如何使用最小二乘法进行直线拟合?

最小二乘法

最小二乘法的主要思想就是求解未知参数,使得理论值与观测值之差(即误差,或者说残差)的平方和达到最小。我们可以使用下面这个公式来描述。

其中,yi 表示来自数据样本的观测值,而 y^ 是假设的函数的理论值,ε 就是我们之前提到的误差,在机器学习中也常被称为损失函数,它是观测值和真实值之差的平方和。最小二乘法里的“二乘”就是指的平方操作。有了这个公式,我们的目标就很清楚了,就是要发现使ε最小化时候的参数。

那么最小二乘法是如何利用最小化 ε 的这个条件来求解的呢?让我们从矩阵的角度出发来理解整个过程。有了上面的定义之后,我们就可以写出最小二乘问题的矩阵形式。

其中 B 为系数矩阵,X 为自变量矩阵,Y 为因变量矩阵。换句话说,我们要在向量空间中,找到一个 B,使向量 XB 与 Y 之间欧氏距离的平方数最小的 B。

推导得:

总结

今天我们探讨了为什么简单的线性方程组无法满足线性函数拟合的需求,最主要的原因就是现实的观测数据往往不是精确的线性关系,存在一定的误差。我们所要做的就是,在允许一定范围的误差前提下,找到一种线性关系,尽量的满足观察数据,使得我们所定义的误差最小

最小二乘法通过向量空间的欧氏距离之平方,定义了预测值和真实值之间的误差。在给定自变量和因变量的观测值之后,最小二乘法可以帮助我们推导出所有自变量的系数,并最小化误差。我使用矩阵的形式,为你推导了整个过程。


41 | 线性回归(下):如何使用最小二乘法进行效果验证?

基于最小二乘法的求解

线性回归模型根据大量的训练样本,推算出系数矩阵 B,然后根据新数据的自变量 X 向量或者矩阵,计算出因变量的值,作为新数据的预测。

Python 代码实现

这一部分,我们使用 Python 的代码,来验证一下之前的推算结果是不是正确,并看看最小二乘法和 Python sklearn 库中的线性回归,这两种结果的对比。

首先,我们使用 Python numpy 库中的矩阵操作来实现最小二乘法。主要的函数操作涉及矩阵的转置、点乘和求逆。具体的代码和注释我列在了下方。

需要注意的是,使用线性回归的时候,我们都有一个前提假设,那就是数据的自变量和因变量之间现线性关系。如果不是线性关系,那么使用线性模型来拟合的效果一定不好。

总结

今天我们使用了具体的案例来推导最小二乘法的计算过程,并用 Python 代码进行了验证。通过最近 3 节的讲解,相信你对线性方程组求精确解、求近似解、以及如何在线性回归中运用这些方法,有了更加深入的理解。

实际上,从广义上来说,最小二乘法不仅可以用于线性回归,还可以用于非线性的回归。其主要思想还是要确保误差ε最小,但是由于现在的函数是非线性的,所以不能使用求多元方程求解的办法来得到参数估计值,而需要采用迭代的优化算法来求解,比如梯度下降法、随机梯度下降法和牛顿法。


42 | PCA主成分分析(上):如何利用协方差矩阵来降维?

在概率统计模块,我详细讲解了如何使用各种统计指标来进行特征的选择,降低用于监督式学习的特征之维度。接下来的几节,我会阐述两种针对数值型特征,更为通用的降维方法,它们是主成分分析 PCA(Principal Component Analysis)和奇异值分解 SVD(Singular Value Decomposition)。这两种方法是从矩阵分析的角度出发,找出数据分布之间的关系,从而达到降低维度的目的,因此并不需要监督式学习中样本标签和特征之间的关系。

PCA 分析法的主要步骤

在解释这个方法之前,我先带你快速回顾一下什么是特征的降维。在机器学习领域中,我们要进行大量的特征工程,把物品的特征转换成计算机所能处理的各种数据。通常,我们增加物品的特征,就有可能提升机器学习的效果。可是,随着特征数量不断的增加,特征向量的维度也会不断上升。这不仅会加大机器学习的难度,还会影响最终的准确度。针对这种情形,我们需要过滤掉一些不重要的特征,或者是把某些相关的特征合并起来,最终达到在减少特征维度的同时,尽量保留原始数据所包含的信息。

PCA 分析法提出了一种可行的解决方案。它包括了下面这样几个主要的步骤:

  • 标准化样本矩阵中的原始数据;
  • 获取标准化数据的协方差矩阵;
  • 计算协方差矩阵的特征值和特征向量;
  • 依照特征值的大小,挑选主要的特征向量;
  • 生成新的特征。

假设我们获得了 k 个特征值和对应的特征向量,那么我们就有:

按照所对应的λ数值的大小,对这 k 组的 v 排序。排名靠前的 v 就是最重要的特征向量。

假设我们只取前 k1 个最重要的特征,那么我们使用这 k1 个特征向量,组成一个 n×k1 维的矩阵 D。

把包含原始数据的 m×n 维矩阵 X 左乘矩阵 D,就能重新获得一个 m×k1 维的矩阵,达到了降维的目的。

有的时候,我们无法确定 k1 取多少合适。一种常见的做法是,看前 k1 个特征值的和占所有特征值总和的百分比。假设一共有 10 个特征值,总和是 100,最大的特征值是 80,那么第一大特征值占整个特征值之和的 80%,我们认为它能表示 80% 的信息量,还不够多。那我们就继续看第二大的特征值,它是 15,前两个特征值之和有 95,占比达到了 95%,如果我们认为足够了,那么就可以只选前两大特征值,把原始数据的特征维度从 10 维降到 2 维。

总结

这一节,我首先简要地重温了为什么有时候需要进行特征的降维和基于分类标签的特征选择。随后,我引出了和特征选择不同的另一种方法,基于矩阵操作的 PCA 主成分分析。这种方法的几个主要步骤包括,标准化原始数据、获得不同特征的协方差矩阵、计算协方差矩阵的特征值和特征向量、选择最重要的主成分,以及通过所选择的主成分来转换原始的数据集。

要理解 PCA 分析法是有一定难度的,主要是因为两点原因:第一,计算的步骤有些复杂。第二,这个方法的核心思路有些抽象。这两点可能会让刚刚接触 PCA 的学习者,感到无从下手。


43 | PCA主成分分析(下):为什么要计算协方差矩阵的特征值和特征向量?

为什么要使用协方差矩阵?

首先要回答的第一个问题是,为什么我们要使用样本数据中,各个维度之间的协方差,来构建一个新的协方差矩阵?要弄清楚这一点,首先要回到 PCA 最终的目标:降维。降维就是要去除那些表达信息量少,或者冗余的维度。

我们首先来看如何定义维度的信息量大小。这里我们认为样本在某个特征上的差异就越大,那么这个特征包含的信息量就越大,就越重要。相反,信息量就越小,需要被过滤掉。很自然,我们就能想到使用某维特征的方差来定义样本在这个特征维度上的差异。

另一方面,我们要看如何发现冗余的信息。如果两种特征是有很高的相关性,那我们可以从一个维度的值推算出另一个维度的值,所表达的信息就是重复的。在概率和统计模块,我介绍过多个变量间的相关性,而在实际运用中,我们可以使用皮尔森(Pearson)相关系数,来描述两个变量之间的线性相关程度。这个系数的取值范围是 [-1,1],绝对值越大,说明相关性越高,正数表示正相关,负数表示负相关。

皮尔森系数计算公式如下:

其中 n 表示向量维度,xk,i 和 xk,j 分别为两个特征维度 i 和 j 在第 k 个采样上的数值。 x¯,i 和 x¯,j 分别表示两个特征维度上所有样本的均值,σx 和 σy 分别表示两个特征维度上所有样本的标准差。

我把皮尔森系数的公式稍加变化,你来观察一下皮尔森系数和协方差之间的关系。

你看,变换后的分子不就是协方差吗?而分母类似于标准化数据中的分母。所以在本质上,皮尔森相关系数和数据标准化后的协方差是一致的。

考虑到协方差既可以衡量信息量的大小,也可以衡量不同维度之间的相关性,因此我们就使用各个维度之间的协方差所构成的矩阵,作为 PCA 分析的对象。就如前面说讲述的,这个协方差矩阵主对角线上的元素是各维度上的方差,也就体现了信息量,而其他元素是两两维度间的协方差,也就体现了相关性。

为什么要计算协方差矩阵的特征值和特征向量?

关于这点,我们可以从两个角度来理解。

第一个角度是对角矩阵。所谓对角矩阵,就是说只有矩阵主对角线之上的元素有非 0 值,而其他元素的值都为 0。我们刚刚解释了协方差矩阵的主对角线上,都是表示信息量的方差,而其他元素都是表示相关性的协方差。既然我们希望尽可能保留大信息量的维度,而去除相关的维度,那么就意味着我们希望对协方差进行对角化,尽可能地使得矩阵只有主对角线上有非 0 元素。

假如我们确实可以把矩阵尽可能的对角化,那么对角化之后的矩阵,它的主对角线上元素就是、或者接近矩阵的特征值,而特征值本身又表示了转换后的方差,也就是信息量。而此时,对应的各个特征向量之间是基本正交的,也就是相关性极低甚至没有相关性。

第二个角度是特征值和特征向量的几何意义。在向量空间中,对某个向量左乘一个矩阵,实际上是对这个向量进行了一次变换。在这个变换的过程中,被左乘的向量主要发生旋转和伸缩这两种变化。如果左乘矩阵对某一个向量或某些向量只发生伸缩变换,不对这些向量产生旋转的效果,那么这些向量就称为这个矩阵的特征向量,而伸缩的比例就是特征值。换句话来说,某个矩阵的特征向量表示了这个矩阵在空间中的变换方向,这些方向都是趋于正交的,而特征值表示每个方向上伸缩的比例

如果一个特征值很大,那么说明在对应的特征向量所表示的方向上,伸缩幅度很大。这也是为什么,我们需要使用原始的数据去左乘这个特征向量,来获取降维后的新数据。因为这样做可以帮助我们找到一个方向,让它最大程度地包含原有的信息。需要注意的是,这个新的方向,往往不代表原始的特征,而是多个原始特征的组合和缩放。

小结

这两节,我详细讲解了 PCA 主成分分析法,它是一种针对数值型特征、较为通用的降维方法。和特征选择不同,它并不需要监督式学习中的样本标签,而是从不同维度特征之间的关系出发,进行了一系列的操作和分析。主要步骤包括,标准化原始的数据矩阵、构建协方差矩阵、计算这种协方差矩阵的特征值和特征向量、挑选较大特征值所对应的特征向量、进行原始特征数据的转换。如果排名靠前的特征向量,或者说主成分,已经包括了足够的信息量,那么我们就可以通过选择较少的主成分,对原始的样本矩阵进行转换,从而达到降维的目的。

PCA 方法一开始不是很好理解,其主要的原因之一是它背后的核心思想并不是很直观。为此,我详细解释了为什么 PCA 会从标准化和协方差入手来构建协方差矩阵。对于同类的特征来说,标准化之后的协方差就是方差,表示了这一维特征所包含的信息量。而对于不同类的特征来说,标准化之后的协方差体现了这两维特征的相关性。鉴于这两个特性,我们需要求解协方差矩阵的特征值和特征向量。如果你弄清楚了这几个关键点,那么 PCA 方法也就不难理解了。


44 | 奇异值分解:如何挖掘潜在的语义关系?

SVD 奇异值分解

今天,我们来聊另一种降维的方法,SVD 奇异值分解(Singular Value Decomposition)。它的核心思路和 PCA 不同。PCA 是通过分析不同纬特征之间的协方差,找到包含最多信息量的特征向量,从而实现降维。而 SVD 这种方法试图通过样本矩阵本身的分解,找到一些“潜在的因素”,然后通过把原始的特征维度映射到较少的潜在因素之上,达到降维的目的。

方阵的特征分解

方阵(Square Matrix)是一种特殊的矩阵,它的行数和列数相等。如果一个矩阵的行数和列数都是 n,那么我们把它称作 n 阶方阵。

如果一个矩阵和其转置矩阵相乘得到的是单位矩阵,那么它就是一个酉矩阵(Unitary Matrix)。

X′X=I

其中 X’表示 X 的转置,I 表示单位矩阵。换句话说,矩阵 X 为酉矩阵的充分必要条件是 X 的转置矩阵和 X 的逆矩阵相等。

之前我们说过特征向量表示了矩阵变化的方向,而特征值表示了变化的幅度。实际上,通过特征值和特征矩阵,我们还可以把矩阵 X 进行特征分解(Eigendecomposition)。这里矩阵的特征分解,是指把矩阵分解为由其特征值和特征向量表示的矩阵之积的方法。如果我们求出了矩阵 X 的 k 个特征值 λ1,λ2,…,λn 以及这 n 个特征值所对应的特征向量 v1,v2,…,vn,那么就有 XV=VΣ。

其中,V 是这 n 个特征向量所张成的 n×n 维矩阵,而 Σ 为这 n 个特征值为主对角线的 n×n 维矩阵。进一步推导,我们可以得到:

矩阵的奇异值分解

SVD 分解和特征分解相比,在形式上是类似的。假设矩阵 X 是一个 m×n 维的矩阵,那么 X 的 SVD 为 X=UΣV′。

转化为方阵

左奇异向量:矩阵 XX’ 的 m 个特征值和对应的 m 个特征向量 u。通过 XX’的所有特征向量构造一个 m×m 的矩阵 U。

右奇异向量:矩阵 X′X 的 n 个特征值和对应的 n 个特征向量 v。通过 X’X 的所有特征向量构造一个 n×n 维的矩阵 V。

现在,包含左右奇异向量的 U 和 V 都求解出来了,只剩下奇异值矩阵 Σ 了。之前我提到,Σ 除了对角线上是奇异值之外,其他位置的元素都是 0,所以我们只需要求出每个奇异值 σ 就可以了。这个解可以通过下面的公式推导求得:

其中 vi 和 ui 都是列向量。一旦我们求出了每个奇异值 σ,那么就能得到奇异值矩阵 Σ。

潜在语义分析和 SVD

潜在语义分析 LSA(Latent Semantic Analysis)或者叫潜在语义索引 LSI(Latent Semantic Index)。

和一般的向量空间模型有所不同,LSA 通过词条和文档所组成的矩阵,发掘词和词之间的语义关系,并过滤掉原始向量空间中存在的一些“噪音”,最终提高信息检索和机器学习算法的精确度。LSA 主要包括以下这些步骤。

  • 第一步,分析文档集合,建立表示文档和词条关系的矩阵。
  • 第二步,对文档 - 词条矩阵进行 SVD 奇异值分解。在 LSA 的应用场景下,分解之后所得到的奇异值σ对应了一个语义上的“概念”,而 σ 值的大小表示这个概念在整个文档集合中的重要程度。U 中的左奇异值向量表示了每个文档和这些语义“概念”的关系强弱,V 中的右奇异值向量表示每个词条和这些语义“概念”的关系强弱。所以说,SVD 分解把原来的词条 - 文档关系,转换成了词条 - 语义概念 - 文档关系。

我画了一张图帮助你理解这个过程。

在这种图中,我们有一个 7×5 维的矩阵 X,表示 7 个文档和 5 个单词。经过 SVD 分解之后,我们得到了两个主要的语义概念,一个概念描述了计算机领域,另一个概念描述了医学领域。矩阵 U 描述文档和这两个概念之间的关系,而矩阵 V’ 描述了各个词语和这两个概念之间的关系。如果要对文档进行检索,我们可以使用 U 这个降维之后的矩阵,找到哪些文档和计算机领域相关。同样,对于聚类算法,我们也可以使用 U 来判断哪些文档属于同一个类。

  • 第三步,对 SVD 分解后的矩阵进行降维,这个操作和 PCA 主成分分析的降维操作是类似的。
  • 第四步,使用降维后的矩阵重新构建概念 - 文档矩阵,新矩阵中的元素不再表示词条是不是出现在文档中,而是表示某个概念是不是出现在文档中。

总的来说,LSA 的分解,不仅可以帮助我们找到词条之间的语义关系,还可以降低向量空间的维度。在这个基础之上在运行其他的信息检索或者机器学习算法,就更加有效。

总结

之前介绍的 PCA 主成分分析,要求矩阵必须是对称的方阵,因此只适用于刻画特征之间关系的协方差矩阵。但是,有的时候我们需要挖掘的是样本和特征之间的关系,例如文档和词条。这个时候矩阵并不是对称的方阵,因此无法直接使用 PCA 分析。

为此,SVD 奇异值分解提供了一种可行的方案。它巧妙的运用了矩阵 X 和自己的转置相乘,生成了两种对称的方阵,并通过这两者的特征分解,获得了 SVD 中的左奇异向量所组成的矩阵 U 和右奇异向量所组成的矩阵 V,并最终推导出奇异值矩阵Σ。这样,SVD 就可以对原始的数据矩阵进行分解,并运用最终的奇异向量进行降维。

我们可以把 SVD 运用在很多场合中,在不同的应用场景下,U,V 和 Σ 代表了不同的含义。例如,在 LSA 分析中,通过对词条和文档矩阵的 SVD 分解,我们可以利用 Σ 获得代表潜在语义的一些概念。而矩阵 U 表示了这些概念和文档之间的关系,矩阵 V 表示了这些概念和单个词语之间的关系。


45 | 线性代数篇答疑和总结:矩阵乘法的几何意义是什么?

矩阵乘法的几何意义

在阐述 PCA 主成分分析的时候,我们聊过为什么这个方法要研究协方差矩阵的特征值和特征向量。其中,我提到对某个向量左乘一个矩阵,实际上是对这个向量进行了一次变换。某个矩阵的特征向量表示了这个矩阵在空间中的变换方向,这些方向都是正交或者趋于正交的,而特征值表示每个方向上伸缩的比例。

弄清楚了矩阵左乘向量的几何意义,那么矩阵左乘矩阵的几何意义也就不难理解了。假设我们让矩阵 X 左乘矩阵 Y,那么可以把右矩阵 Y 看作一堆列向量的集合,而左乘矩阵 X 就是对每个 Y 中的列向量进行变换。另外,如果二维空间理解了,那么三维、四维直到 n 维空间就可以以此类推了。

SVD 分解中的 U 和 V 矩阵

证明 U 中的向量就是 XX′ 的特征向量。

极客时间版权所有: https://time.geekbang.org/column/article/88078

从这个证明的过程,我们也发现了,XX’或者 X’X 特征值矩阵等于奇异值矩阵的平方,也就是说我们可以通过求出 X’X 特征值的平方根来求奇异值。

总结

线性代数最基本的概念包括了向量、矩阵以及对应的操作。向量表示了一组数的概念,非常适合表示一个对象的多维特征,因此被广泛的运用在信息检索和机器学习的领域中。而矩阵又包含了多个向量,所以适合表示多个数据对象的集合。同时,矩阵也可以用于表达二维关系,例如网页的邻接矩阵,用户对物品的喜好程度,关键词在文档中的 tf-idf 等等。

由于向量和矩阵的特性,我们可以把它们运用在很多算法和模型之中。向量空间模型定义了向量之间的距离或者余弦夹角,我们可以利用这些指标来衡量数据对象之间的相似程度,并把这种相似程度用于定义查询和文档之间的相关性,或者是文档聚类时的归属关系。矩阵的运算体现了对多个向量同时进行的操作,比如最常见的左乘,就可以用在计算 PageRank 值,协同过滤中的用户或者物品相似度等等。

当然,矩阵的运用还不止计算数据对象之间的关系。最小二乘法的实现、PCA 主成分的分析、SVD 奇异值的分解也可以基于矩阵的运算。这些都可以帮助我们发现不同维度特征之间的关系,并利用这些关系找到哪些特征更为重要,选择或者创建更为重要的特征。

有的时候,线性代数涉及的公式和推导比较繁琐。在思考的过程中,我们可以把矩阵的操作简化为向量之间的操作,而把向量之间的操作简化为多个变量之间的运算。另外,我们可以多结合实际的案例,结合几何空间、动手推算,甚至可以编程实现某些关键的模块,这些都有利于理解和记忆。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章