线性代数01 线性的大脑

作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁任何形式转载。

 

线性代数是一门大学课程,但也是相当“惨烈”的一门课程。在大学期间,我对这门学科就没怎么学懂。先是挣扎于各种行列式、解方程,然后又看到奇怪的正交矩阵、酉矩阵。还没来得及消化,期末考试轰然到来,成绩自然凄凄惨惨。

后来读了更多的线性代数的内容,才发现,线性代数远不是一套奇奇怪怪的规定。它的内在逻辑很明确。只可惜大学时的教材,把最重要的一些核心概念,比如线性系统,放在了最后。总结这些惨痛的经历,再加上最近的心得,我准备写一些线性代数的相关文章。

这一系列线性代数文章有三个目的:

  1. 概念直观化
  2. 为“数据科学”系列文章做准备,没有线性代数基础,没法深入统计和机器学习。
  3. 线性代数运算的代码实现。这是经典的程序员挑战。参看一天能学会的计算机技术

线性代数是现代数学、自然科学的基础工具。在计算机领域,数据挖掘、机器学习、图形处理,数值运算这几块儿都与线性代数紧密相关。如果你对这些技术感兴趣,这些线性代数的文章可以作为你的参考读物。

 

这一篇,我将引入线型代数的核心:线性系统。让人惊奇的是,这一核心概念,早就根植在我们的思维中。 

 

生活中的线性:超市结算

我们想象一个只卖两个商品的超市,销售青菜、黄豆。青菜每捆5元,黄豆每盒3元。此外,这个超市还有个积分系统,每捆青菜积分2分,每包黄豆积4分。需要一个结算系统,为客户计算总价和积分。

超市结算

 

这对程序员来说不算挑战。每个语言都可以轻松的实现,比如用Python:

# By Vamei

def bill(x1, x2):
    y1 = 5*x1 + 3*x2
    y2 = 2*x1 + 4*x2    return y1, y2

x1,x2分别为青菜和黄豆的数目。y1,y2为总价和积分。通过输入不同品种的购买数目,我们得到输出。这里的输出有两个元素:总价和积分。

 

上面的计算,还可以写成一组简单的数学方程:

$$y_1 = 5 \times x_1 + 3 \times x_2 $$

$$y_2 = 2 \times x_1 + 4 \times x_2 $$

 

我们试想这样一种情况:一对夫妻去超市买菜。丈夫买了1捆青菜,2盒黄豆,结账的时候,为11元和10个积分。妻子买了2捆绑青菜,3盒黄豆,结账的时候,为19元和16积分。

但如果妻子结账前碰到丈夫了,俩人把东西放在一起,总共3捆青菜,5盒黄豆。按照我们的结算系统,总价为[$5 \times 3 + 3 \times 5 = 30 $]元,总积分为[$2 \times 3 + 4 \times 5 = 26$]积分。

你可能会反驳我,为什么要那么麻烦呢?把刚才的两个单子加在一起不就可以了。[$11 + 19 = 30$]元,[$10 + 16 = 26$]积分。这通过结算系统的计算结果完全相同。

 

这想法没错。你已经在运用线性系统(Linear System)的思维了:

几个购物车里的东西,分开结账的几张小票的总和,和一次算总帐的结果相同。

线性系统还有更复杂的情况。把两个购物车给销售员,让销售员按相同的配比,丈夫的来3车,妻子的来2车。那么,新的总价,应该是丈夫的小票乘3,加上妻子的小票乘2。

 

线性的思维方式是如此的普遍,以致于我们要多想一下,才能想出非线性的例子。下面是一个非线性的情况:超市更改积分系统,积分超过20的话,将获得双倍积分。这个时候,如果分开结账,丈夫和妻子的积分都不到20,那么积分分别为10和16,总和为26。而合在一起结账,由于积分超过了20,积分将是52。有生活经验的夫妻们,一定是合在一起结账,而不是分开结账了。

我们创造了一个非线性的系统。把这个新的结算系统编成函数,依然用Python:

# By Vamei

def non_linear_bill(x1, x2):
    y1 = 5*x1 + 3*x2
    y2 = 2*x1 + 4*x2
    if y2 > 20:
        y2 = y2 * 2
    return y1, y2

非线性并不是人们的惯常思维方式。超市和商场常有复杂的打折、赠券、积分系统, 这些系统很多时候是非线性的。大脑需要耗费很大能量,才能处理得过来。于是,作为超级线性的男生,我通常的想法都是:去它妈的,老子不要那么麻烦的合单或拆单了。

(奇怪的是,妹纸可以超级熟练的处理各种非线性的购物系统,甚至并行处理多个。上帝拿走的那根肋骨,一定是非线型的……)

 

“一个”

我们即将要改变我们对一个单位的数据的理解。举出一个数据

做为程序员,最直接会列举出一个数据,比如一个整数,一个浮点数。

 

那一个结构体呢?C语言中的结构体可以包含有多个元素。我们知道,每个元素分开写出来,并不是结构体的完整数据。比如:

typedef struct {
    int veg;
    int bean;
} Cart;

 

再继续,一个对象的数据呢?一个对象可以有多个属性。当我们说一个对象的数据时,我们指的是这个对象的多个属性。比如:

public class Cart{
   int veg;
   int bean;
}

 

再比如,我们在说一个人的数据时,包括姓名,身高、体重、IQ多个值。这多个值可以构成这个人的“一个”数据。我们可以在SQL数据库中建立这样一个Person(name, height, weight, IQ)的表。每一行,也就是一个记录(record),算是一个数据单位。

 

即使是列表这样的数据容器,如果固定每个位置数据的意义,那么一个列表也可以算是“一个”数据。比如丈夫购物车为[1,2],妻子的购物车为[2,3]。

 

这种包含了多个元素的数据,称为向量(vector)。与之对应,一个单一的数值,称为标量(scalar)。

 一个向量

 

我们用带小箭头字母表示,来表示一个向量。比如丈夫的购物车:

$$ \vec{x} = \left[ \begin{matrix} 1 \\ 2 \end{matrix} \right]$$

 

向量可以相加减,这时只需要对应行的元素相加就可以,相当于合并或分开购物车。比如丈夫和妻子的购物车合并:

$$\begin{bmatrix} 1 \\ 2 \end{bmatrix} + \begin{bmatrix} 2 \\ 3 \end{bmatrix} = \begin{bmatrix} 3 \\ 5 \end{bmatrix}$$

向量也可以与一个标量相乘。比如[$\vec{x} \times 5$]表示5个购物车的量。这时只需将标量与向量的各行元素相乘。

$$ 5 \begin{bmatrix} 1 \\ 2 \end{bmatrix} = \begin{bmatrix} 5 \\ 10 \end{bmatrix}$$ 

 

伴随着向量,有一个简单的概念,即维度(dimension)。上面的购物车向量,包含了两个数值,即青菜的数目和黄豆的数目。我们因此说该向量是二维的。而结构体中元素的个数、对象的属性个数,都是维度。我会在以后的文章中深入维度这一概念。

 

有了对数据的深入理解,那么线性系统的特点可以总结如下: 

$$L(a\vec{D_1} + b\vec{D_2}) = aL(\vec{D_1}) + bL(\vec{D_2})$$  

[$\vec{D_1}$]和[$\vec{D_2}$]是向量,分别是丈夫和妻子的购物车。而a, b为两个标量,比如a为2,b为3,表示丈夫那样的购物车乘2,妻子的购物车乘3。L为结算系统。方程右边表示,合在一起结账。方程右边表示,丈夫和妻子分开小票,相乘再相加。方程的两边相等。

 

矩阵革命

在数学上,我们已经有一组方程表示出了一个线性系统。上面的方程组有些不方便的地方:

  • 输入的元素(黄豆数目)和系统参数(单价)混合在一起
  • 有很多字母

 

数学家是偷懒的动物,这点和程序员很像。他们最后找到了一种省事的记述方式。利用刚才的向量。分离的表示输入、线性系统和输出的关系:

$$\begin{bmatrix} 11 \\ 10 \end{bmatrix} = \begin{bmatrix} 5 & 3 \\ 2 & 4 \end{bmatrix} \begin{bmatrix} 1 \\ 2 \end{bmatrix}$$

方程最左是个向量,最右是个向量。奇怪的是中间用括号括住的一堆数字。这被称为一个矩阵(Matrix)。可以看到,这个矩阵中有四个元素,包含了各个物品的单价和各个物品可获得的积分。这通常是结算系统所包含的数据。我们可以猜测到,这个矩阵相当于一个结算系统。左边的向量是输出,右边的向量是输入。

 

结算系统

 

这个结算系统运作时,把输入向量放横,再和结算系统的每一行元素分别相乘,即获得对应的输出元素。比如输出的第一个元素:

根据这一运算规则,一个线性系统就完全用一个矩阵表示出来了。

可以把矩阵表示成字母A,那么用代数的形式,写出输出和矩阵、输入的关系:

$$\vec{y} = A\vec{x}$$

这个代数形式,在线性代数中,有基础性的地位。方程的右边,我们说矩阵和向量进行了“乘法”运算。这一运算的规则,是按照我们上面所描述的那样运行的。这简直是对乘法符号的一次“运算符重载”(operator overload)。

 

我们可以用程序来实现上面的计算过程。编写类似的C程序并不复杂。更方便的是调用现有的库函数,比如Python中的numpy: 

# By Vamei

import numpy as np

# matrix
a = np.matrix([[5, 3],[2, 4]])

# input Vector
x = np.array([[1], [2]])

# multiplication
y = np.dot(a, x)

print(y)

矩阵这个东西把结算系统的表示方式大大缩减。更重要在于,线性系统和矩阵是互通的。矩阵表示的是一个线性系统。一个线性系统也总可以表示一个矩阵(证明从略)。

 

绕了半天,矩阵 = 线性系统。

 

总结

线性代数的核心是线性系统的概念。线性系统与矩阵的等同性,让线性代数后面的内容,转入到对矩阵的研究中。但核心要牢记。

线性系统的概念在生活中非常常见。人的思维很多时候也是线性的。思考生活中线性和非线性的例子。

广义的数据可以表示成多维的向量。

 

时间: 2024-09-27 20:17:28

线性代数01 线性的大脑的相关文章

【线性代数】线性相关性、基和维数

一.线性相关性       什么情况下,向量X1,X2,--,Xn是线性无关的?       答:当向量X1,X2,--,Xn的线性组合(线性组合时系数不能全为0)不为零向量时,它们是线性无关的.即方程 不存在非零解.        对于一个矩阵A来说,当A总各列向量是线性无关时,则Ax=0的解只有0向量,即矩阵A的零空间只有零向量. 如果各列向量是相关的,则矩阵A的零空间中还存在一些其他的向量.         当矩阵A各列是线性无关的,则矩阵A各列都有主元,自由变量的个数为0. 二.空间的基

MIT牛人解说数学体系

MIT牛人解说数学体系     在过去的一年中,我一直在数学的海洋中游荡,research进展不多,对于数学世界的阅历算是有了一些长进.   为什么要深入数学的世界 作 为计算机的学生,我没有任何企图要成为一个数学家.我学习数学的目的,是要想爬上巨人的肩膀,希望站在更高的高度,能把我自己研究的东西看得更深广一些. 说起来,我在刚来这个学校的时候,并没有预料到我将会有一个深入数学的旅程.我的导师最初希望我去做的题目,是对appearance和motion建立 一个unified的model.这个题

我的Android进阶之旅------>Android中Drawable分类汇总详解

Android把可绘制的对象抽象为Drawable,不同的图形图像资源就代表着不同的drawable类型.Android FrameWork提供了一些具体的Drawable实现,通常在代码中都不会直接接触Drawable的实现类.         在实际的开发过程中,会把使用到的资源都放置在res/drawable目录,剩下的工作交给Android SDK 就行了,当需要使用图片资源的时候,可以使用@drawable标志在xml中引用drawable资源就行,也可以在代码中使用id引用这些dra

麻省理工(MIT)牛人解说数学体系

一.为什么要深入数学的世界 作为计算机的学生,我没有任何企图要成为一个数学家.我学习数学的目的,是要想爬上巨人的肩膀,希望站在更高的高度,能把我自己研究的东西看得更深广一些.说起来,我在刚来这个学校的时候,并没有预料到我将会有一个深入数学的旅程.我的导师最初希望我去做的题目,是对appearance和motion建立一个unified的model.这个题目在当今Computer Vision中百花齐放的世界中并没有任何特别的地方.事实上,使用各种Graphical Model把各种东西联合在一起

Maxima在线性代数应用:线性代数相关指令

这节我们正式介绍线性代数相关,也就是矩阵相关的指令. 矩阵及向量 我们先来看矩阵和向量的定义方式.前面说过,在Maxima 里,所谓设定一个变数的值,只不过是给某个数字或矩阵等等一个名称.我们这里就举应用在矩阵和向量时的情况: (%i1) A:matrix([1,2,3],[-2,8,3],[1,4,9]);&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;                              

零基础入门深度学习:感应器、线性单元和梯度下降

投稿:Intelligent Software Development 团队介绍:团队成员来自一线互联网公司,工作在架构设计与优化.工程方法研究与实践的最前线,曾参与搜索.互联网广告.共有云/私有云等大型产品的设计.开发和技术优化工作.目前主要专注在机器学习.微服务架构设计.虚拟化/容器化.持续交付/DevOps等领域,希望通过先进技术和工程方法最大化提升软件和服务的竞争力.   无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理想有追求的

线性表的类型定义

线性表简介 线性结构是一个数据元素的有序(次序)集合. 线性结构的基本特征为: 1. 集合中必存在唯一的一个"第一元素": 2.集合中必存在唯一的一个 "最后元素" : 3.除最后元素在外,均有 唯一的后继: 4.除第一元素之外,均有 唯一的前驱 线性表的类型定义 ADT(抽象数据类型)是描述逻辑结构的,它的的实现用物理存储来实现,有两种: 顺序存储结构和链式存储结构. 抽象数据类型线性表的定义如下: ADT List{ 数据对象:D={ ai | ai ∈Elem

算法速成(四)五大经典查找之线性查找

在我们的生活中,无处不存在着查找,比如找一下班里哪个mm最pl,猜一猜mm的芳龄....... 对的 这些都是查找. 在我们的算法中,有一种叫做线性查找. 分为:顺序查找. 折 半查找. 查找有两种形态: 分为:破坏性查找,   比如有一群mm,我猜她们的 年龄,第一位猜到了是23+,此时这位mm已经从我脑海里面的mmlist中remove掉了. 哥不找23+ 的,所以此种查找破坏了原来的结构. 非破坏性查找, 这种就反之了,不破坏结构. 顺序查找: 这种非常简单,就是过一下数组,一个一个的比,

简单介绍线性表以及如何实现双链表_java

线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列. 一.数组数组有上界和下界,数组的元素在上下界内是连续的. 存储10,20,30,40,50的数组的示意图如下: 数组的特点:数据是连续的:随机访问速度快. 数组中稍微复杂一点的是多维数组和动态数组.对于C语言而言,多维数组本质上也是通过一维数组实现的.至于动态数组,是指数组的容量能动态增长的数组:对于C语言而言,若要提供动态数组,需要手动实现:而对于C++而言,STL提供了Vector:对于Java而言,Collec