1.1.1 描述向量
按照我们已有的认识,向量(Vector)是有大小和方向的量,比如物理学中的力、速度、加速度、角速度、动量等物理量都是向量。另外有一些量,比如温度、时间、质量、面积等,在描述它们的时候不需要方向,称之为标量(Scalar),也称“数量”或“纯量”。
以二维平面空间为例,如图1-1-3所示,显示了若干个有向线段,这些线段就直观地表示了向量,以其中的有向线段OA为例:
● 线段的长度表示向量的大小;
● 端点的顺序表示了向量的方向,即箭头所指的方向;
● 称为始点(尾部),称为终点(头部);
● 此向量记作,或者用加粗的斜体小写字母表示,如(在本书中,如果仅指某个一般意义的向量,均用如这样的形式;如果特指某个有向线段,则采用类似这样的形式)。
图1-1-3
图1-1-3中显示的几个有向线段,彼此之间大小相等,方向一致,我们称这样的有向线段所表示的向量相等。从物理学的角度看,当“万箭齐发”的时候,数量是不可或缺的——一共发射了多少支箭?但是从数学的角度看,它们既然大小、方向都一样,那么只需要用一条有向线段即可说明“箭”的特点了。
为了更“数学”地描述向量,根据已有的数学经验,需要建立一个空间坐标系,最简单的方式,就是以一个向量的始点为坐标原点,建立直角坐标系。如图1-1-4所示,以向量的始点为坐标原点,建立直角坐标系之后,就可以用一个符号(例如)表示所有与相等的向量了。
这样,我们就能准确地说明这些向量的大小(即长度)和方向(有关计算方法,请阅读1.5节):
● 向量的大小:;
● 设向量与轴的夹角为:。
图1-1-4
在图1-1-4所示的坐标系中,的终点的坐标是,这对有序数字唯一地表示了二维空间中的一个点,同样也唯一地表示了一个向量。如果另找一个点,那么以原点为始点、为终点的向量以及与它相等的其他向量,显然与向量不相等。因此,我们可以用平面空间中的点的坐标来表示与之对应的向量。
在线性代数中,用数字序列表示向量的写法有两种:
● 行向量:将有序数字写成一行,比如图1-1-4中所示向量;
● 列向量:将有序数字写成一列,比如:。
在本书中,使用列向量的方式表示空间向量,例如:
● 三维空间(用表示)中的向量:,其中是空间某点的坐标。此向量也可以写成,注意右上角的符号,表示转置(参阅2.3.2节),这样写在排版方面更方便。
● n维空间(用表示)中的向量:,或。
上述对向量的描述,有赖于所选择的那个坐标系——虽然它有点特殊,对此,本书在1.2.3节和1.3.2节会做进一步阐述。
对事物的描述,会影响我们对它的认识。当我们选择上面这种描述方式之后,向量的大门就敞开了。
在程序中,有多种表示向量的方法,比如在NumPy中用数组对象表示向量(注意:本书所有代码均是在Jupyter Notebook中编辑的)。
上面创建的一维数组u,就可以表示行向量。如果要创建列向量,则可以这样操作:
此外,Pandas的DataFrame对象的每一列(即每个特征)都可以被视为一个列向量。
在机器学习中,用数组表示的向量可谓无处不在,只要有计算,就离不开它。为何?这是因为能够提升运算速度。以如下程序为例,创建一个由随机整数组成的列表,要计算列表中每个整数的平方,一种方法是使用列表解析方式计算,另一种方法是将列表转换为数组计算。
以上程序的输出结果会因所用计算机的不同而有差别。计算结果显示了将数据“向量化”之后带来的优势。
所以,将计算对象“向量化”是机器学习中的一个重要操作,不然,计算速度慢,甚至无法计算。再比如要对一些文本进行处理——自然语言处理(Natural Language Processing,NLP)是人工智能技术的一个重要分支,就必须对组成文本的字词向量化。假设有两个文件,其内容分别是:
● 文件1(记作:):mathematics machine learn
● 文件2(记作:):learn python learn mathematics
程序无法直接对其中的单词进行计算——计算机认识的是数字,于是要将这两个对象“向量化”,分别统计每个字词在不同文件中出现的次数,最终形成表1-1-1。
表1-1-1
如果把一行看作一个向量,就得到了这样两个向量,这两个向量分别记录了不同文件中的字词出现次数,并且在记录次数的时候不考虑字词的出现顺序,像这样的对象称为词袋(Bag of Words,BOW)。
在这个示例中,文件的字词数量很少,人工数一数就能得知每个字词的出现次数,如果文件中的字词太多怎么办?例如,把《红楼梦》作为一个文件,当然不能“人工数一数”了,此时要使用更有效率的工具。
在上述代码中,使用了机器学习常用库Sklearn中的CountVectorizer模型。注释(1)创建一个模型实例;注释(2)是待分析的两个文件;注释(3)利用模型对文件的内容进行训练转换;注释(4)显示所得模型的特征,即表1-1-1中显示的所有字词。
● 第一列数字表示注释(2)中文件的索引,0表示的是文件1(即)。
● 第二列数字表示注释(4)输出结果的索引,例如“(0,2)”中的2表示词语“mathematics”的索引。
● 第三列数字表示该字词在相应文件中出现的次数,例如“(0,2)1”中的1表示字词“mathematics”在(0所表示的)中出现的次数是1。
图1-1-5
以上向量化的结果,还可以用DataFrame对象表示:
上述输出结果与表1-1-1的内容相同。
像上面那样,统计了某个字词(记作:)在某个文件(记作:)中的出现次数(记作:),在NLP中,称为字词频数(注意:在这里没有使用“词频”,主要是因为“词频”这个词中的“频”,没有明确表示出是“频数”还是“频率”,在统计学中,这是两个完全不同的概念,但是一般机器学习资料中未加区分)。一般认为,越大,则该字词在相应文件中越重要,即字词频数能够表征某字词在文件中的重要性。
然而,由于不同文件的字词总数量[记作:]不同,比如一个文件总共有100个字词,另外一个文件有1000个字词,如果“苏州”这个词在这两个文件中的字词频数都是,那么是不是意味着它在两个文件中的重要性一样呢?显然不是。为此,就要用下面的式子:
这里计算所得的称为字词频率(Term Frequency,简称tf或TF)。按照此式,“苏州”这个词在两个文件中的tf分别为:和。
但是,tf大,也并非意味着它所携带的信息量就大,比如在中文文本中常见“的、地、得”,英文文本中常见“the、a、of”等。所以,要给每个字词的tf增加一个权重,这个权重应该能体现该字词所能传递的信息量——越常见的字词,携带的信息量越小,权重值应该越低。
如果统计了包含某个字词的文件数量(记作:)和所有文件的总数量(记作:),那么,就可以用下面的指标表示该字词是否常见:
越大,即(Document Frequency)越大,表示该字词在全部文件中越常见,则该字词的信息量也越小。因此,应该用作为的权重,即逆向文件频率(Inverse Document Frequency,简称idf或IDF,单词“inverse”有“倒数”之意)。为了避免的线性增长,通常计算时取对数:
之所以在分母上加,是为了避免分母为(即所有文件都不含该词)。
这样,就可以用以表征某个字词所携带的信息量大小,用它作为的权重,即,这个指标合称为tf-idf(或TF-IDF)。所以,只要计算出了字词的tf-idf,就知道它在文件中的重要性了。
在前述已经计算了字词频数的基础上,继续使用Sklearn中的TfidfTransformer模型计算文件中每个字词的tf-idf。
经过如此操作,将原来的文本内容转换为了向量,并且向量包含了文本中每个词汇的有关信息。在此基础上,就可以通过计算,研究这些文本信息了——更多NLP的知识,请参阅专门资料。
现在知道了向量如何表示,下一个问题就是怎么计算它了。