This commit is contained in:
louzefeng
2024-07-09 18:38:56 +00:00
parent 8bafaef34d
commit bf99793fd0
6071 changed files with 1017944 additions and 0 deletions

View File

@@ -0,0 +1,276 @@
<audio id="audio" title="01 | 导读:如何在机器学习中运用线性代数工具?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ee/25/eefb64294a1d314517eb5bb2160edc25.mp3"></audio>
你好,我是朱维刚。欢迎你跟我一起重学线性代数!
在开篇词中我和你大致讲过我自己的经历从2006年开始到现在14年的时间里我都专注于机器学习领域。对于**线性代数**在机器学习中的应用,我非常了解。而这也是线性代数最主要的应用场景之一。因此,今天第一节课,我想先和你聊一聊,如何在机器学习中运用线性代数工具,在我们开始自下而上的学习之前,先从上层来看一看。
我们都知道,“数据”是机器学习的前提,机器学习的第一步就是要进行**数据**的收集、预处理和特征提取;而**模型**就是通过数据来学习的算法;**学习**则是一个循环过程,一个自动在数据中寻找模式,并不停调优模型参数的过程。那我们就从机器学习的三个核心概念:数据、模型和学习说起。
<img src="https://static001.geekbang.org/resource/image/3a/32/3a2a7433d5d13b676abe05041a1bcd32.png" alt="">
你看,不论是模型,还是学习,都涉及数据,而数据加上模型和学习,就是数学的一般过程了,也就是:观察、实验、推理和抽象。所以,我认为学好数学,不仅有利于理解复杂的机器学习系统,还能调优算法参数,甚至能帮助你创建新的机器学习解决方案。
## 从机器学习到线性代数
那机器学习和线性代数之间到底有着怎样的关系呢我想用一个实际的机器学习算法的例子来解释你可能更容易搞清楚。接下来我使用KNNK-Nearest NeighborK最近邻分类算法来让你简单了解一下机器学习以及它和线性代数之间的关系。
之所以选KNN分类算法因为它是一个理论上比较成熟的方法也是最简单的机器学习算法之一。这个方法的思路是如果一个样本在特征空间中的K个最相似即特征空间中最邻近的样本中的大多数属于某一个类别则该样本也属于这个类别。
这里有个前提KNN算法中所选择的“邻居”都是已经正确分类的对象。KNN分类算法在分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。我们通过图来理解的话或许更容易一些。
<img src="https://static001.geekbang.org/resource/image/43/aa/439cefee464eb01ed110e70515f94eaa.png" alt="">
假设图片中那个绿色圆就要是我们要决策的对象那么根据KNN算法它属于哪一类是红色三角形还是蓝色四方形
如果K=3实线圆也就是包含离绿色圆最近的3个由于红色三角形所占比例为2/3绿色圆就属于红色三角形那个类。但如果K=5虚线圆就是包含离绿色圆最近的5个由于蓝色四方形比例为3/5绿色圆就属于蓝色四方形那个类。
## 鸢尾花分类问题中的线性代数
通过前面这个小例子你应该已经理解了KNN算法的概念。那么接下来我们就试着使用KNN在给定鸢尾花特征值的情况下给鸢尾花做花种分类带你来实际看一下线性代数在这里起到的作用。
特别说明一下,**鸢尾花分类问题**是一个国际上通用的案例,一般都被作为机器学习入门来使用,所以它的数据集也是公开的。
### 1.数据集的收集、加载和分析
首先,我们要做的是数据集的收集、加载和分析,你也可以点击[这里](https://www.kaggle.com/notlir/iriscsv)下载原始数据集来看看原始数据长什么样下面是获取和加载数据的代码sklearn数据集已经包含了样本数据你可以直接用。
```
import pandas as pd
from sklearn import datasets
iris = datasets.load_iris()
species = [iris.target_names[x] for x in iris.target]
iris = pd.DataFrame(iris['data'], columns = ['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width'])
iris['Species'] = species
```
从显示的结果,我们能够看出鸢尾花有四个特征:花萼的长、宽和花瓣的长、宽。我们来看下这四个特征的数据类型:
```
iris.dtypes
Sepal_Length float64
Sepal_Width float64
Petal_Length float64
Petal_Width float64
Species object
dtype: object
```
这些特征都是数值型而且标签Species表示的是花种是一个字符串类型的变量。我们继续看一下鸢尾花的分类统计
```
iris['count'] = 1
iris[['Species', 'count']].groupby('Species').count()
```
<img src="https://static001.geekbang.org/resource/image/a7/ce/a7ff740c15de327cfd8c1c9a4b681cce.png" alt="">
这里我们直接能够看到鸢尾花有三个花种每个种类有50个实例或者说50条数据我们再用图来更直观地显示这三种鸢尾花。
```
%matplotlib inline
def plot_iris(iris, col1, col2):
import seaborn as sns
import matplotlib.pyplot as plt
sns.lmplot(x = col1, y = col2,
data = iris,
hue = &quot;Species&quot;,
fit_reg = False)
plt.xlabel(col1)
plt.ylabel(col2)
plt.title('Iris species shown by color')
plt.show()
plot_iris(iris, 'Petal_Width', 'Sepal_Length')
plot_iris(iris, 'Sepal_Width', 'Sepal_Length')
```
<img src="https://static001.geekbang.org/resource/image/c2/93/c216f676f59e00cae4b52481fdf88293.png" alt=""><img src="https://static001.geekbang.org/resource/image/a8/0a/a8337b9d13c23ef18e3bd8a4dbb91b0a.png" alt="">
蓝、黄、绿,这三种颜色分别代表了三种鸢尾花,显示还是很清楚的。
### 2.数据集的准备
接下来的第二步就是数据集的准备了。在训练任何机器学习模型前,数据准备都相当重要,这里也要涉及两步准备。
第一步特征数值标准化。如果我们不做标准化后果就是大数值特征会主宰模型训练这会导致更有意义的小数值特征被忽略。这里我们用Z Score标准化使每一类特征平均值为0方差为1.0,我们可以通过代码实现来看下效果。
```
from sklearn.preprocessing import scale
import pandas as pd
num_cols = ['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width']
iris_scaled = scale(iris[num_cols])
iris_scaled = pd.DataFrame(iris_scaled, columns = num_cols)
print(iris_scaled.describe().round(3))
```
<img src="https://static001.geekbang.org/resource/image/1f/da/1f7bbea1c93dcdbbcd9c1ba4e32178da.png" alt="">
你可以看到每一列平均值为0标准差大约是1.0。为了分类需要,我们用字典把花种从字符串类型转换成数字表示。
```
levels = {'setosa':0, 'versicolor':1, 'virginica':2}
iris_scaled['Species'] = [levels[x] for x in iris['Species']]
iris_scaled.head()
```
<img src="https://static001.geekbang.org/resource/image/bc/5e/bc14b245ab9076d3a8911dyy2da8895e.png" alt="">
第二步把数据集随机分割成样本训练集和评估数据集训练集用来训练KNN模型评估集用来测试和评估KNN的分类结果。
```
from sklearn.model_selection import train_test_split
import numpy as np
np.random.seed(3456)
iris_split = train_test_split(np.asmatrix(iris_scaled), test_size = 75)
iris_train_features = iris_split[0][:, :4]
iris_train_labels = np.ravel(iris_split[0][:, 4])
iris_test_features = iris_split[1][:, :4]
iris_test_labels = np.ravel(iris_split[1][:, 4])
print(iris_train_features.shape)
print(iris_train_labels.shape)
print(iris_test_features.shape)
print(iris_test_labels.shape)
```
通过代码,我们得到了下面这样的结果。
```
(75, 4)
(75,)
(75, 4)
(75,)
```
### 3.训练模型
数据准备好后就是第三步训练模型了。这里我们使用K=3来训练KNN模型当然你也可以调整这个参数来进行观察和调优。
```
from sklearn.neighbors import KNeighborsClassifier
KNN_mod = KNeighborsClassifier(n_neighbors = 3)
KNN_mod.fit(iris_train_features, iris_train_labels)
```
### 4.模型测试
执行KNN训练后我们来到了最后一步模型测试这里我们使用测试集来测试模型。
```
iris_test = pd.DataFrame(iris_test_features, columns = num_cols)
iris_test['predicted'] = KNN_mod.predict(iris_test_features)
iris_test['correct'] = [1 if x == z else 0 for x, z in zip(iris_test['predicted'], iris_test_labels)]
accuracy = 100.0 * float(sum(iris_test['correct'])) / float(iris_test.shape[0])
print(accuracy)
```
```
96.0
```
最终我们得到的准确率是96.0说明了KNN的训练模型不错适用这类场景。我们通过代码把其中的两个分类setosa和versicolor打印出来看看。
```
levels = {0:'setosa', 1:'versicolor', 2:'virginica'}
iris_test['Species'] = [levels[x] for x in iris_test['predicted']]
markers = {1:'^', 0:'o'}
colors = {'setosa':'blue', 'versicolor':'green',}
def plot_shapes(df, col1,col2, markers, colors):
import matplotlib.pyplot as plt
import seaborn as sns
ax = plt.figure(figsize=(6, 6)).gca() # define plot axis
for m in markers: # iterate over marker dictioary keys
for c in colors: # iterate over color dictionary keys
df_temp = df[(df['correct'] == m) &amp; (df['Species'] == c)]
sns.regplot(x = col1, y = col2,
data = df_temp,
fit_reg = False,
scatter_kws={'color': colors[c]},
marker = markers[m],
ax = ax)
plt.xlabel(col1)
plt.ylabel(col2)
plt.title('Iris species by color')
return 'Done'
plot_shapes(iris_test, 'Petal_Width', 'Sepal_Length', markers, colors)
plot_shapes(iris_test, 'Sepal_Width', 'Sepal_Length', markers, colors)
```
<img src="https://static001.geekbang.org/resource/image/9e/7f/9e2c398552558a970ff1644905f6347f.png" alt=""><img src="https://static001.geekbang.org/resource/image/10/47/1057ba92123f1b3faa7d98b3162a4c47.png" alt="">
从显示的效果来说分类还是挺明显的熟悉了最基础的机器学习过程后你可能会问讲了半天线性代数到底在哪里呢关键就在KNeighborsClassifier模块上这个模型算法的实现背后其实用到了线性代数的核心原理。
首先,因为每种鸢尾花都有四个特征:花萼的长、宽和花瓣的长、宽,所以每条数据都是四维向量。
接着,量化样本之间的相似度,也就是计算向量之间的距离。而向量之间距离的运算有很多方式,比如:曼哈顿距离、欧式距离、切比雪夫距离、闵可夫斯基距离等等。其中,欧式距离你应该很熟悉了,因为我们初中都学过,在二维平面上计算两点之间的距离公式:
$$d=\sqrt{\left(x_{1}-x_{2}\right)^{2}+\left(y_{1}-y_{2}\right)^{2}}$$
扩展到我们实例中的四维向量,也是同样的算法。
你看这就是线性代数在机器学习中的一种应用场景。KNN是一种监督学习算法因为在样本集中有分类信息通过计算距离来衡量样本之间相似度算法简单易于理解和实现。还有另一种机器学习算法是无监督学习底层的数学原理其实也是差不多的总的思想就是“物以类聚”。
现在,你是不是有一种豁然开朗的感觉?终于看到了线性代数原来那么有意义,而且再简单的公式也是美的。
## 本节小结
好了,到这里导读这一讲就结束了,最后我再总结一下前面讲解的内容。
这一讲我使用机器学习的监督学习算法KNN在给定鸢尾花特征值的情况下给鸢尾花做花种分类让你了解机器学习最基本的过程外能够真正了解其背后的线性代数真相为你进入后面课程的学习提供一个感性的认知。
机器学习中用到的线性代数知识点比比皆是,而且往往软件架构上看上去复杂的事情,在数学上反而很简单,希望你在学习了这门课程后,能够多从数学角度出发去构思解决问题的方案。
同时,欢迎你在留言区说说自己对机器学习的理解,也可以分享一下自己的线性代数学习经历,如果你有所收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,262 @@
<audio id="audio" title="02 | 基本概念:线性代数研究的到底是什么问题?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/d0/b0/d06d30f778810c3960bf1afb0b6ac7b0.mp3"></audio>
你好,我是朱维刚。欢迎你跟我学习线性代数。今天我们要讲的是“线性代数这门课的基本概念”。
线性代数可以运用在很多领域,比如:工程学、计算机科学、经济学、信号处理等等。我们来看一个在经济学中常见的例子:消费矩阵。
假设有n个行业比如化学、食品和石油。制造一单位的某化学品需要0.2单位的另一类化学品0.3单位的食品以及0.4单位的石油,而制造一单位的某食品和某石油也同样分别需要这三类产品的输入,于是,我们就能构造这样一个消费矩阵:
$$\left|\begin{array}{l}<br>
化学输出 \\\<br>
食品输出 \\\<br>
石油输出<br>
\end{array}\right|=\left[\begin{array}{lll}<br>
0.2 &amp; 0.3 &amp; 0.4 \\\<br>
0.4 &amp; 0.4 &amp; 0.1 \\\<br>
0.5 &amp; 0.1 &amp; 0.3<br>
\end{array}\right]\left|\begin{array}{l}<br>
化学输入 \\\<br>
食品输入 \\\<br>
石油输入<br>
\end{array}\right|$$
当然,我们也可以用一般的线性方程组$Ax=b$的形式来表达:
$$\left\{\begin{array}{l}<br>
0.2 x_{1}+0.3 x_{2}+0.4 x_{3}=b_{1} \\\<br>
0.4 x_{1}+0.4 x_{2}+0.1 x_{3}=b_{2} \\\<br>
0.5 x_{1}+0.1 x_{2}+0.3 x_{3}=b_{3}<br>
\end{array}\right.$$
从本质上来说,消费矩阵解决的是输入和输出之间的关系。不仅如此,线性代数在现实生活中的运用还有很多,比如,我们可以借用特征值和特征向量,预测若干年后的污水水平;在密码学中,可以使用矩阵及其逆矩阵对需发送的消息加密;在机器学习中,可以使用线性方程组的共轭迭代法来训练神经网络,等等。
刚才我分别用矩阵和线性方程组的形式给出了消费矩阵,当然,在实际生活中,你可以灵活选择最有效的方式来解决问题。
我们可以看到,线性方程组可以表示成一般形式,也就是你初中学到的$A x=b$的形式,也可以表示成矩阵形式。矩阵是由向量组合而成的,比如刚才例子中的系数矩阵的每一行都是一个**行向量**,每一列都是一个**列向量**。
$$\begin{array}{l}<br>
\end{array}\left[\begin{array}{lll}<br>
0.2 &amp; 0.3 &amp; 0.4 \\\<br>
0.4 &amp; 0.4 &amp; 0.1 \\\<br>
0.5 &amp; 0.1 &amp; 0.3<br>
\end{array}\right] \begin{array}{l}<br>
\end{array}$$
从这里我们能看出,**向量**其实就会是线性代数最基础的核心。数学对抽象思维要求很高,简单来说,抽象思维就是抽取同类事物的共性。所以,在进入具体的线性方程组的主题前,我要先从数学抽象的角度说一说代数和线性代数,这也是深入理解后面内容的前提。
## 代数和线性代数的基本概念
那什么是代数呢?百度百科的解释是这样的:
>
代数是研究数、数量、关系、结构与代数方程(组)的通用解法及其性质的数学分支。
但我觉得这个解释其实没有说出**代数**这个概念的重点。我的理解是这样的:**代数是构造一系列对象和一系列操作这些对象的规则。**
所以你看,代数这个概念的核心就两点,**对象**和**操作对象的规则**,这样就很好理解了吧?那有了代数的定义,线性代数就很好定义了。我们类比来看,线性代数其实就是向量,以及操作这些向量的规则。这里,向量映射到对象,向量的规则映射到对象的规则,因此线性代数是代数的具像化表达。
<img src="https://static001.geekbang.org/resource/image/b5/64/b51a25b2810340472a4yy5701a057764.png" alt="">
## 向量的基本概念
那什么是**向量**呢?从样子来看,向量其实就是由字母加上它上面的箭头来表示的,比如我们一版会写成$\vec{x}$。我估计你在高中或大学里已经接触过“几何向量”。那么,下面我用更抽象的数学观点来给你解释一下。
**向量**也叫欧几里得向量Euclidean Vector其实就是能够互相相加、被标量乘的特殊对象。而标量也叫“无向量”它只有数值大小没有方向。怎么理解呢我们来看一些向量的例子通过这些例子来深入理解向量的概念。
**几何向量**是有向线段,在二维空间(也就是平面)中,两个几何向量能够相加,比如,向量$x$加上向量$y$等于向量$z$$\vec{x}+\vec{y}=\vec{z}$ $x$向量也能被一个标量乘。再比如,标量$\lambda$乘向量$x$结果也是向量,$\lambda \vec{x}, \lambda \in R$。几何向量通过大小和方向来简化向量的表达,所以,一般数学课程一开始都会拿几何向量来进行举例。
<img src="https://static001.geekbang.org/resource/image/bb/5c/bbc1e0e2cd7eac341f91cd0e40b5f35c.png" alt="">
**多项式其实也是向量**。两个多项式能够相加,它也能够被标量乘,结果也是多项式。
**矩阵的一行或一列也是向量。**就比如下面这样形式的向量。
$$x \in R^{3}: x=\left[\begin{array}{l}<br>
1 \\\<br>
2 \\\<br>
3<br>
\end{array}\right]$$
两个向量能够相加,它也能够被标量乘,结果也是向量。它和现代大部分的编程语言中的数组一致,而且数组的运算简化了向量操作的算法实施。
**矢量图、音频信号也是向量**。它们都能被一系列数字表示,比如,在音频信号处理中,常用到数据增强的方法,通过向量的操作就能到达目标。
看了这些向量例子,不知道你现在有点感觉了吗?其实,线性代数的本质就是**寻找向量之间的相似性**比如在做分类时我们常常需要估算不同样本之间的相似性度量Similarity Measurement这时通常采用的方法就是计算样本间的“距离”Distance
可以看出来,向量非常重要,我们后面很多内容都是从向量延伸而来的,比如矩阵和求解线性方程组。
下面我用一张图来表达和向量有关的所有概念,也就是线性代数所有的核心内容,其中大部分内容你都会学到,希望通过这个图,你对线性代数有个大概的认知。相信学习完所有课程后,你再回过头来看时,肯定会有一些新的认知。
<img src="https://static001.geekbang.org/resource/image/27/a6/271d9b2f46af71fc70b55863556a0ba6.png" alt="">
从图中最左侧这一列,我们可以看出,向量组合成矩阵,矩阵可以表示成线性方程组,而线性方程组可以通过高斯消元法求解,也可以求逆矩阵。
同时,向量又可以组合成向量空间,向量空间和矩阵都可以做线性映射或者线性变换,线性映射在实践中可以用在解析几何和分类问题中。
而且向量和线性独立是强相关的也就是说线性独立指的是向量的线性独立而线性独立又可以引出能够生成整个空间的基Basis基在实践中可以用在分类和降维中。
这里,我再额外提一个非常重要的、在数学中经常用到的概念——**封闭性**,或者俗称**闭包**Closure。封闭性的定义是如果我们要对某个集合的成员进行一种运算生成的仍然是这个集合的成员那这个集合就可以称为在这个运算下闭合。
我为什么要提这个概念呢?这是因为,向量的线性运算是封闭的,也就是说向量的加法、数乘结果仍属于向量空间,即**向量的任意线性组合仍属于向量空间**。
## 线性方程组的应用
到这里,相信你已经对线性代数、向量这些基本概念有了一个应试教育之外的、新的认识,接下来我就切入本篇的最重点的内容了,那就是线性方程组。
线性方程组在线性代数中有着举足轻重的地位,许多现实生活中的问题都可以表达成线性方程组。关于线性方程组的概念,我想不用我多说了,这是初中的内容,你应该已经非常了解了。现在我举几个例子来说一说,线性方程组在现实生活中的运用,让你从应用的角度再理解下线性方程组。
第一个例子是计算旅游团人数。假设一个旅游团由孩子和大人组成去程时他们一起坐大巴每个孩子的票价3元大人票价3.2元总共花费118.4元。回程时一起坐火车每个孩子的票价3.5元大人票价3.6元总共花费135.2元。请问这个旅游团中有多少孩子和大人?
假设小孩人数为$x_{1}$,大人人数为$x_{2}$,于是我们得到了一个方程组:
$$\left\{\begin{array}{c}<br>
3 x_{1}+3.2 x_{2}=118.4 \\\<br>
3.5 x_{1}+3.6 x_{2}=135.2<br>
\end{array}\right.$$
使用初中的解二元一次方程组的知识,我们可以得出这个方程组的解是:
$$\left\{\begin{array}{c}<br>
x_{1}=16 \\\<br>
x_{2}=22<br>
\end{array}\right.$$
这个就是典型的线性方程组的现实例子。当然,我们也可以用矩阵来解这个方程组。你可能会说,这问题很简单啊,为什么还要用矩阵来解呢?整这么复杂有必要吗?别着急,这里我先卖个关子,具体我会在下一讲“矩阵篇”中进行讲解。
第二个例子是找出公司的最优生产计划。我们从公司的角度来看一看假设生产苹果的几大主流产品iPhone、Macbook、iMac以及iWatch四款产品需要用到芯片、摄像头模组、电池、IPS屏幕四大类资源产品分别用 $N_{1}N_{2}N_{3}N_{4}$来表示,资源分别用$R_{1}R_{2}R_{3}R_{4}$来表示。
生产一单位的产品 $N_{1}$也就是iPhone需要$a_{11}a_{21}a_{31}a_{41}$的资源也就是芯片、摄像头模组、电池和IPS屏幕资源其他产品也是一样。
我们的目标是在资源有限的情况下,找到一个最优生产计划,使每个产品的产出数量最大化。也就是说,在总共有$b_{i}$个单位资源$R_{i}$可用情况下,每个产品$N_{i}$ 有多少单元 $x_{i}$应该被生产。因此,我们可以得到一个下面这样的线性方程组:
$$\left\{\begin{array}{l}<br>
a_{11} x_{1}+a_{12} x_{2}+a_{13} x_{3}+a_{14} x_{4}=b_{1} \\\<br>
a_{21} x_{1}+a_{22} x_{2}+a_{23} x_{3}+a_{24} x_{4}=b_{2} \\\<br>
a_{31} x_{1}+a_{32} x_{2}+a_{33} x_{3}+a_{34} x_{4}=b_{3} \\\<br>
a_{41} x_{1}+a_{42} x_{2}+a_{43} x_{3}+a_{44} x_{4}=b_{4}<br>
\end{array}\right.$$
于是,我们得到线性方程组的通用表达方式,$x_{1}\cdots x_{n}$ 是未知变量每个满足方程组表达式的n元组$(x_{1}\cdots x_{n})$都是它的解。
$$\left\{\begin{array}{l}<br>
a_{11} x_{1}+a_{12} x_{2}+\cdots+a_{1 n} x_{n}=b_{1} \\\<br>
a_{21} x_{1}+a_{22} x_{2}+\cdots+a_{2 n} x_{n}=b_{2} \\\<br>
\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \\\<br>
a_{m 1} x_{1}+a_{m 2} x_{2}+\cdots+a_{m n} x_{n}=b_{m}<br>
\end{array}\right.$$
线性方程组的解是有几何意义的,从几何角度出发,有利于你理解和记忆线性方程组解的条件,接下来我们先来看看线性方程组解的几种情况,之后我再具体讲解线性方程组的几何表达。
首先我们来看**无解**的情况。假设有下面这样一个线性方程组:
$$\left\{\begin{array}{c}<br>
x_{1}+x_{2}+x_{3}=3 \\\<br>
x_{1}-x_{2}+2 x_{3}=2 \\\<br>
2 x_{1}+3 x_{3}=1<br>
\end{array}\right.$$
第一行和第二行相加后,我们可以得到$2 x_{1}+3 x_{3}=5$,很明显,这个方程和第三行是矛盾的,所以,这个线性方程组无解。
其次是**只有一个解**的情况。假设有下面这样一个线性方程组:
$$\left\{\begin{array}{c}<br>
x_{1}+x_{2}+x_{3}=3 \\\<br>
x_{1}-x_{2}+2 x_{3}=2 \\\<br>
x_{2}+x_{3}=2<br>
\end{array}\right.$$
这个方程组求解很简单,第一行乘以$-1$和第二行相加得到$-2x_{2}+x_{3}=-1$,再乘以$-1$后和第三行相加得到$x_{1}=1$,第一行和第二行相加,得到$2 x_{1}+3 x_{3}=5$ ,代入$x_{1}$后,得到$x_{3}=1$,最后,我们可以得到$(1,1,1)$是这个线性方程组的唯一解。
最后是**无穷解**的情况。我们有下面这样一个线性方程组:
$$\left\{\begin{array}{c}<br>
x_{1}+x_{2}+x_{3}=3 \\\<br>
x_{1}-x_{2}+2 x_{3}=2 \\\<br>
2 x_{1}+3 x_{3}=5<br>
\end{array}\right.$$
方程组第一行和第二行相加等于第三行,从这个角度来说,我们就可以定义一个自由变量$x_{3}=a$ $a$属于实数,那方程组的解就是:
$$\left(\frac{5}{2}-\frac{3}{2} a, \frac{1}{2}+\frac{1}{2} a, a\right)$$
其中$a$属于实数,所以,这就包含了无穷多个解。
## 线性方程组的几何表达
好了,了解了线性方程组解的三种情况,现在我们是时候从几何的角度来看一看线性方程组和它的解了,从几何意义出发有利于你更直观地理解线性方程组。
在一个只有两个变量$x_{1},x_{2}$的线性方程组中,我们定义一个$x_{1},x_{2}$平面。在这个平面中,每个线性方程都表达了一条直线。由于线性方程组的唯一解必须同时满足所有的等式,所以,线性方程组的唯一解其实就是线段的相交点,无穷解就是两线重合,而无解的情况,也就是两条线平行。
我拿一个例子来说明,设线性方程组:
$$\left\{\begin{array}{l}<br>
4 x_{1}+4 x_{2}=5 \\\<br>
2 x_{1}-4 x_{2}=1<br>
\end{array}\right.$$
把其中的两个线性方程在$x_{1},x_{2}$平面中画出来后,我们可以得到两线段的交点$\left(1, \frac{1}{4}\right)$,也就是这个线性方程组的解。
<img src="https://static001.geekbang.org/resource/image/79/a3/798e5098989a4b4e3de1604108ca98a3.png" alt="">
我再把这个概念延伸一下,当遇到三个变量的情况时,每个线性方程在三维空间中表达了一个平面,由于线性方程组的一个解必须同时满足所有的等式,所以,**线性方程组的解其实就是平面,也可以是线、点或者空,空也就是没有共同的平面相交**。
其实还有一个更好的方法来表达和解线性方程组,这个方法就是下一篇要讲的矩阵,在这里我先简单提一下。我们把系数组合成向量,把向量组合成矩阵,也就是说,我们可以把线性方程组写成这样的形式:
$$x_{1}\left|\begin{array}{c}<br>
a_{11} \\\<br>
\vdots \\\<br>
a_{m 1}<br>
\end{array}\right|+x_{2}\left|\begin{array}{c}<br>
a_{12} \\\<br>
\vdots \\\<br>
c_{m 2}<br>
\end{array}\right|+\cdots+x_{n}\left|\begin{array}{c}<br>
a_{1 n} \\\<br>
\vdots \\\<br>
a_{m n}<br>
\end{array}\right|=\left|\begin{array}{c}<br>
b_{1} \\\<br>
\vdots \\\<br>
b_{m}<br>
\end{array}\right|$$
再进一步最终可以写成矩阵的形式:<br>
$$\left[\begin{array}{cccc}<br>
a_{11} &amp; a_{12} &amp; \ldots &amp; a_{1 n} \\\<br>
a_{21} &amp; a_{22} &amp; \ldots &amp; a_{2 n} \\\<br>
\ldots &amp; \ldots &amp; \ldots &amp; \ldots \\\<br>
a_{m 1} &amp; a_{m 2} &amp; \ldots &amp; a_{m n}<br>
\end{array}\right]\left|\begin{array}{c}<br>
x_{1} \\\<br>
\vdots \\\<br>
. \\\<br>
x_{n}<br>
\end{array}\right|=\left|\begin{array}{c}<br>
b_{1} \\\<br>
\vdots \\\<br>
. \\\<br>
b_{m}<br>
\end{array}\right|$$
## 本节小结
好了,到这里这一讲就结束了,我带你总结一下前面讲解的内容。
这节课我带你重新认识了代数和线性代数的概念。代数是构造一系列对象和一系列操作这些对象的规则,线性代数是向量,以及操作这些向量的规则,所以,线性代数是代数的具像化表达。从线性代数,我们引出了向量的基本概念,我带你看了一个和向量有关的所有概念,即线性代数所有核心内容的图。
可以说,线性代数的一切皆从**向量**而来。
最后,我带你从二维平面几何角度,更直观地观察线性方程组和它几种解的情况,**而二维空间的线性方程组的解其实就是线、点或者空,也就是没有共同的线段相交**。你也可以自己试着把它扩展到三维空间几何中来观察,或许会更有趣哦!
<img src="https://static001.geekbang.org/resource/image/b3/b7/b3685e09f961f3c7e51702bbd56d7cb7.png" alt="">
## 线性代数练习场
我们一起来看一个练习题。这是一道极其简单的初中线性方程组题,你可以回顾一下,也为下一节课做好铺垫。
李大叔去年承包了10亩地种植甲、乙两种蔬菜共获利18000元。其中甲蔬菜每亩获利2000元乙蔬菜每亩获利1500元。
请问,李大叔去年甲、乙两种蔬菜各种植了多少亩?
欢迎在留言区晒出你的运算过程和结果。如果有收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,420 @@
<audio id="audio" title="03 | 矩阵:为什么说矩阵是线性方程组的另一种表达?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/75/07/75633f4e649fdb6948292a4bde991c07.mp3"></audio>
你好,我是朱维刚。欢迎你继续跟我学习线性代数,今天我们要讲的内容是“矩阵”。
在开始学习之前,我想先问你个问题,你觉得,学习矩阵有什么用呢?你可以先自己想一想。之后我们讲任何一个知识的时候,你都可以从这个角度出发,自己先思考一下,这样有助于你对所学内容理解得更深刻。
对于刚才那个问题,我的答案很简单,就一句话,从我们程序员的角度去理解的话,**矩阵可以极大地提高计算机的运算效率**。怎么说呢?我给你举一个例子。在机器学习中(特别是深度学习,或者更具体一点,神经网络),并行计算是非常昂贵的。
<img src="https://static001.geekbang.org/resource/image/a6/0d/a66474802f395e8e1a78147c7949150d.png" alt="">
上图是一个典型的神经网络架构,在这时候,矩阵就能发挥用武之地了,计算$H$隐藏层输出的公式是:$H = f( W.x + b )$,其中$W$是权重矩阵,$f$是激活函数,$b$是偏差,$x$是输入层矩阵。而这个计算过程就叫做**向量化**Vectorization这也是GPU在深度学习中非常重要的原因因为GPU非常擅长做类似矩阵乘之类的运算。
$$<br>
X=\left|\begin{array}{l}<br>
x_{1} \\\<br>
x_{2}<br>
\end{array}\right|<br>
$$
$$<br>
W=\left|\begin{array}{ll}<br>
w_{1} &amp; w_{2} \\\<br>
w_{4} &amp; w_{5} \\\<br>
x_{3} &amp; w_{6}<br>
\end{array}\right|<br>
$$
$$<br>
H=f\left(\left|\begin{array}{ll}<br>
w_{1} &amp; w_{2} \\\<br>
w_{4} &amp; w_{5} \\\<br>
x_{3} &amp; w_{6}<br>
\end{array}\right|\left|\begin{array}{l}<br>
x_{1} \\\<br>
x_{2}<br>
\end{array}\right|+b\right)<br>
$$
不过,矩阵也不仅仅局限于神经网络的应用,同时它也可以用在计算机图形图像的应用中,比如,三维物体从取景到屏幕的显示,就需要经历一系列的空间变换,才能生成二维图像显示在显示器上。在这个计算过程中,我们都需要用到矩阵。
矩阵是非常实用的,但它正式作为数学中的研究对象出现,其实是在行列式的研究发展起来之后。英国数学家 Arthur Cayley 被公认为矩阵论的创立人,他提出的矩阵概念可能来自于行列式。但我相信另一种说法,提出矩阵是为了更简单地表达线性方程组,也就是说,矩阵是线性方程组的另一种表达。
## 矩阵的基本概念
线性方程组的概念很简单,上节我们已经简单提过。你在小学或中学肯定也学过二元一次方程和二元一次方程组。
$$ax+by=c$$
$$<br>
\left\{\begin{array}{l}<br>
a_{1} x+b_{1} y+C_{1}=0 \\\<br>
a_{2} x+b_{2} y+C_{2}=0<br>
\end{array}\right.<br>
$$
在这样一个方程组中,$a1$、$a2$、$b1$、$b2$不能同时为0。当我们把二元一次方程组再扩展一下变成多元一次方程组时我们就能得到线性方程组的一般表达即$AX=B$。
$$<br>
\left\{\begin{array}{l}<br>
a_{11} x_{1}+a_{12} x_{2}+\cdots+a_{1 n} x_{n}=b_{1} \\\<br>
a_{21} x_{1}+a_{22} x_{2}+\cdots+a_{2 n} x_{n}=b_{2} \\\<br>
\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \\\<br>
a_{m 1} x_{1}+a_{m 2} x_{2}+\cdots+a_{m n} x_{n}=b_{m}<br>
\end{array}\right.<br>
$$
于是,这个线性方程组的所有系数就构成了一个$m×n$的$m$行$n$列矩阵:
$$<br>
A=\left[\begin{array}{cccc}<br>
a_{11} &amp; a_{12} &amp; \ldots &amp; a_{1 n} \\\<br>
a_{21} &amp; a_{22} &amp; \ldots &amp; a_{2 n} \\\<br>
\ldots &amp; \ldots &amp; \ldots &amp; \ldots \\\<br>
a_{m 1} &amp; a_{m 2} &amp; \ldots &amp; a_{m n}<br>
\end{array}\right]<br>
$$
我们把$A$称为该方程组的系数矩阵,而当我们把等式右边的常数$b$放入矩阵后,就是下面这样:
$$<br>
\widetilde{A}=\left[\begin{array}{ccccc}<br>
a_{11} &amp; a_{12} &amp; \ldots &amp; a_{1 n} &amp; b_{1} \\\<br>
a_{21} &amp; a_{22} &amp; \ldots &amp; a_{2 n} &amp; b_{2} \\\<br>
\ldots &amp; \ldots &amp; \ldots &amp; \ldots &amp; \ldots \\\<br>
a_{m 1} &amp; a_{m 2} &amp; \ldots &amp; a_{m n} &amp; b_{m}<br>
\end{array}\right]<br>
$$
这样我们就得到了$A$矩阵的增广矩阵$\widetilde{A}$ ,可以表示为$(A, B)$,这里的$B$表示的是方程组常数项所构成的列向量,也就是$m×1$的$m$行$1$列矩阵:
$$<br>
B=\left|\begin{array}{l}<br>
b_{1} \\\<br>
b_{2} \\\<br>
\cdots \\\<br>
b_{m}<br>
\end{array}\right|<br>
$$
如果设$X$为$n×1$的$n$行$1$列矩阵:
$$<br>
X=\left|\begin{array}{c}<br>
x_{1} \\\<br>
x_{2} \\\<br>
\cdots \\\<br>
x_{n}<br>
\end{array}\right|<br>
$$
那么线性方程组$A$,就可以表示为$AX=B$的矩阵形式。如果我们再换一种表示形式,设:$a_{1} ,a_{2},\ldots, a_{n},\beta$表示增广矩阵$\widetilde{A}$ 的列向量,则线性方程组$A$又可表示为$a_{1} x_{1}+a_{2} x_{2}+\cdots+a_{n} x_{n}=β$。
线性方程组的矩阵和向量形式都是线性方程组的其他表达形式。在工作中,你可以用它们来简化求解,甚至可以提升计算效率,就如之前提到的神经网络的隐藏层的输出计算、图形图像的三维空间变换。在数学中也是同样的,你可以经常运用它们来简化求解。具体线性方程组求解的内容比较多,我们下一节课再来详细讲解求解过程。
通过前面的讲解,我相信你对矩阵有了一定的了解,现在我们再回头来看看矩阵的定义吧。
矩阵的定义是:一个$(m, n)$矩阵$A$,是由$m×n$个元素组成,$m$和$n$是实数,其中元素$a_{i j}, \mathrm{i}=1, \ldots, \mathrm{m}, \mathrm{j}=1, \ldots, \mathrm{n}$按$m$行$n$列的矩形排布方式后可以形成矩阵$A$
$$<br>
A=\left[\begin{array}{cccc}<br>
a_{11} &amp; a_{12} &amp; \ldots &amp; a_{1 n} \\\<br>
a_{21} &amp; a_{22} &amp; \ldots &amp; a_{2 n} \\\<br>
\ldots &amp; \ldots &amp; \ldots &amp; \ldots \\\<br>
a_{m 1} &amp; a_{m 2} &amp; \ldots &amp; a_{m n}<br>
\end{array}\right]<br>
$$
其中$a_{i j}$属于实数或复数,在我们的场景中是实数$R$,按通常的惯例,$(1, n)$矩阵叫做行,$(m, 1)$矩阵叫做列,这些特殊的矩阵叫做行或列向量。
定义完矩阵后我接着讲一个比较有趣的概念矩阵转换Matrix transformation。矩阵转换经常被用在计算机图形图像的转换中比如一张彩色图片从RGB角度来说是三维的如果要转换成灰度图片也就是一维图片那就要做矩阵转换。
我们来看一下矩阵转换的过程。设$\mathrm{R}^{m \times n}$是实数矩阵$(m, n)$的集合,$A \in \mathrm{R}^{m \times n}$可以表示成另一种形式 $a \in \mathrm{R}^{mn}$ 。我们把矩阵的$n$列堆叠成一个长向量后完成转换。这个转换也叫做reshape其实就是重新调整原矩阵的行数、列数和维数但是元素个数不变。
<img src="https://static001.geekbang.org/resource/image/a5/4a/a59fefec5c22effacb862e61e87c034a.png" alt="">
## 矩阵的运算
了解了矩阵的基本定义后,我们才能进入矩阵的运算环节,就是矩阵的加和乘。
加运算很简单,两个矩阵$A \in \mathrm{R}^{m \times n}$$B \in \mathrm{R}^{m \times n}$的加运算其实就是矩阵各自元素的加。
$$<br>
A+B=\left[\begin{array}{ccc}<br>
a_{11}+b_{11} &amp; \ldots &amp; a_{1 n}+b_{1 n} \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
a_{m 1}+b_{m 1} &amp; \ldots &amp; a_{m n}+b_{m n}<br>
\end{array}\right] \in R^{m \times n}<br>
$$
我推荐你使用NumPy的einsum来高效地做这类运算因为它在速度和内存效率方面通常可以超越我们常见的array函数。
```
C= np.einsum('il, lj', A, B)
```
接下来,我们一起来看看矩阵的乘。这里你需要注意,矩阵的乘和通常意义上“数之间的乘”不同,矩阵的乘有多种类型,这里我讲三种最普遍,也是在各领域里用得最多的矩阵乘。
### 1.普通矩阵乘
普通矩阵乘是应用最广泛的矩阵乘,两个矩阵$A \in \mathrm{R}^{m \times n}$$B \in \mathrm{R}^{n \times k}$,普通矩阵则乘可以表示为$C=A B \in R^{m \times k}$$C$中元素的计算规则是矩阵$A$、$B$对应两两元素乘积之和。
$$<br>
c_{i j}=\sum_{k=1}^{n} a_{i k} b_{k j}, i=1, \ldots, m, j=1, \ldots, l<br>
$$
我们举例来说明。$C$的第一个元素$c_{11}=a_{11} \times b_{11}+a_{12} \times b_{21}+a_{13} \times b_{31}=1 \times 1+2 \times 2+3 \times 3$。
$$<br>
C=A B=\left[\begin{array}{lll}<br>
1 &amp; 2 &amp; 3 \\\<br>
4 &amp; 5 &amp; 6<br>
\end{array}\right]\left[\begin{array}{ll}<br>
1 &amp; 4 \\\<br>
2 &amp; 5 \\\<br>
3 &amp; 6<br>
\end{array}\right]=\left[\begin{array}{lll}<br>
1 \times 1+2 \times 2+3 \times 3 &amp; 1 \times 4+2 \times 5+3 \times 6 \\\<br>
4 \times 1+5 \times 2+6 \times 3 &amp; 4 \times 4+5 \times 5+6 \times 6<br>
\end{array}\right]=\left[\begin{array}{cc}<br>
14 &amp; 32 \\\<br>
32 &amp; 77<br>
\end{array}\right]<br>
$$
这里需要特别注意的是,只有相邻阶数匹配的矩阵才能相乘,例如,一个$n×k$矩阵$A$和一个$k×m$矩阵$B$相乘,最后得出$n×m$矩阵$C$,而这里的$k$就是相邻阶数。
$$AB=C$$
但反过来B和A相乘就不行了因为相邻阶数$m$不等于$n$。
### 2.哈达玛积
哈达玛积理解起来就很简单了,就是矩阵各对应元素的乘积,$c_{i j}=a_{i j} × b_{i j}$ 。举个例子:
$$<br>
C=A^{*} B=\left[\begin{array}{ll}<br>
1 &amp; 2 \\\<br>
4 &amp; 5<br>
\end{array}\right]\left[\begin{array}{ll}<br>
1 &amp; 4 \\\<br>
2 &amp; 5<br>
\end{array}\right]=\left[\begin{array}{cc}<br>
1 * 1 &amp; 2 * 4 \\\<br>
4 * 2 &amp; 5 * 5<br>
\end{array}\right]=\left[\begin{array}{cc}<br>
1 &amp; 8 \\\<br>
8 &amp; 25<br>
\end{array}\right]<br>
$$
哈达玛积其实在数学中不常看到,不过,在编程中哈达玛积非常有用,因为它可以用来同时计算多组数据的乘积,计算效率很高。
### 3.克罗内克积
克罗内克积是以德国数学家利奥波德·克罗内克Leopold Kronecker的名字命名的。它可以应用在解线性矩阵方程和图像处理方面当然从更时髦的角度说它还能用在量子信息领域我们也称之为直积或张量积。
和普通矩阵乘和哈达玛积不同的是,克罗内克积是两个任意大小矩阵间的运算,表示为$A×B$,如果$A$是一个$m × n$的矩阵,而$B$是一个$p×q$的矩阵,克罗内克积则是一个$mp×nq$的矩阵。
接下来我们需要定义一个**在矩阵的乘法中起着特殊作用**的矩阵,它就是**单位矩阵**。高等代数中,在求解相应的矩阵时,若添加单位矩阵,通过初等变换进行求解,往往可以使问题变得简单。按照百度百科的解释,单位矩阵如同数的乘法中的$1$,这种矩阵就被称为单位矩阵。它是个方阵,从左上角到右下角的对角线,也就是主对角线上的元素均为$1$,除此以外全都为$0$。
在线性代数中,大小为$n$的单位矩阵就是在主对角线上均为1而其他地方都是$0$的$n×n$的方阵,它用$\mathrm{I}_{n}$表示,表达时为了方便可以忽略阶数,直接用$\mathrm{I}$来表示:
$$<br>
I_{1}=[1], I_{2}=\left[\begin{array}{ll}<br>
1 &amp; 0 \\\<br>
0 &amp; 1<br>
\end{array}\right], I_{3}=\left[\begin{array}{lll}<br>
1 &amp; 0 &amp; 0 \\\<br>
0 &amp; 1 &amp; 0 \\\<br>
0 &amp; 0 &amp; 1<br>
\end{array}\right], …, I_{n}=\left[\begin{array}{cccc}<br>
1 &amp; 0 &amp;&amp; 0 \\\<br>
0 &amp; 1 &amp;&amp; 0 \\\<br>
. &amp; . &amp;&amp; . \\\<br>
. &amp; . &amp; . &amp; . \\\<br>
0 &amp; 0 &amp;&amp; 1<br>
\end{array}\right]<br>
$$
## 矩阵的性质
在了解了矩阵加和乘,以及单位矩阵后,我们是时候来看一看矩阵的性质了。了解矩阵的性质是进行矩阵计算的前提,就像我们小时候学加减乘除四则运算法则时那样。所以,这块内容对你来说应该不难,你作为了解就好,重点是之后的运算。
### 1.结合律
任意实数$m×n$矩阵$A$$n×p$矩阵$B$$p×q$矩阵$C$之间相乘,满足结合律$(AB)C=A(BC)$。这个很好理解,我就不多说了。
$$\forall A \in R^{m \times n}, B \in R^{n \times p}, C \in R^{p \times q}:(A B) C=A(B C)$$
### 2.分配律
任意实数$m×n$矩阵$A$和$B$$n×p$矩阵$C$和$D$之间相乘满足分配律$(A+B)C=AC+BC$$A(C+D)=AC+AD$。
$$<br>
\forall \mathrm{A}, B \in \mathrm{R}^{m \times n}, C, D \in \mathrm{R}^{n \times p}:(A+B) C=A C+B C, A(C+D)=A C+A D<br>
$$
### 3.单位矩阵乘
任意实数$m×n$矩阵A和单位矩阵之间的乘等于它本身$A$。
$$<br>
\forall A \in R^{m \times n}: I_{m} A=A I_{n}=A<br>
$$
注意,这里的行和列不同,$m \neq n$意味着,根据矩阵乘,左乘和右乘单位矩阵也不同,也就是$I_{m} \neq I_{n}$。
## 逆矩阵与转置矩阵
了解矩阵基本概念、运算,以及性质后,我来讲一讲矩阵应用中的两个核心内容——逆矩阵和转置矩阵。逆矩阵和转置矩阵在实际应用中大有用处,比如:坐标系中的图形变换运算。我们先来看下什么是逆矩阵。
### 逆矩阵
下面这个图你应该非常熟悉了,图中表现的是数字的倒数,$2$的倒数是$\frac{1}{2}$$\frac{1}{2}$的倒数是$2$。
<img src="https://static001.geekbang.org/resource/image/8d/d0/8db06d8746f6e615a1b2a110b9ef68d0.png" alt="">
其实逆矩阵也有着类似的概念,只不过是写法不一样,我们会把逆矩阵写成$A^{-1}$。那为什么不是$\frac{1}{A}$呢那是因为数字1无法被矩阵除。
<img src="https://static001.geekbang.org/resource/image/24/b7/245c9964790b8dyy4888ebdb87b5d5b7.png" alt="">
我们知道,$2$乘以它的倒数$\frac{1}{2}$等于$1$。同样的道理,$A$乘以它的逆矩阵$A^{-1}$就等于单位矩阵,即$\mathrm{A} \times A^{-1}=\mathrm{I}$$I$即单位矩阵),反过来也一样,$\mathrm{A}^{-1} \times A=\mathrm{I}$。
为方便你理解,我用一个$2 \times 2$矩阵$A$来解释一下逆矩阵的算法。首先,我们交换$a_{11}$和$a_{22}$的位置,然后在$a_{12}$和$a_{21}$前加上负号,最后除以行列式$a_{11} a_{22}-a_{12} a_{21}$。
$$<br>
A^{-1}=\left[\begin{array}{ll}<br>
a_{11} &amp; a_{12} \\\<br>
a_{21} &amp; a_{22}<br>
\end{array}\right]^{-1}=\frac{1}{a_{11} a_{22}-a_{12} a_{21}}\left[\begin{array}{cc}<br>
a_{22} &amp; -a_{12} \\\<br>
-a_{21} &amp; a_{11}<br>
\end{array}\right]<br>
$$
那我们该如何验证这是不是正解呢?
方法其实很简单,记得刚才的公式就行,$\mathrm{A} \times A^{-1}=\mathrm{I}$。现在我们就代入公式来验证一下,$A$和它的逆矩阵相乘,通过刚才的算法最终得出的结果是单位矩阵。
$$<br>
A \times A^{-1}=\left[\begin{array}{llll}<br>
a_{11} &amp; a_{12} \\\<br>
a_{21} &amp; a_{22}<br>
\end{array}\right]\left[\begin{array}{ll}<br>
a_{11} &amp; a_{12} \\\<br>
a_{21} &amp; a_{22}<br>
\end{array}\right]^{-1}=\left[\begin{array}{ll}<br>
a_{11} &amp; a_{12} \\\<br>
a_{21} &amp; a_{22}<br>
\end{array}\right]\left[\begin{array}{lll}<br>
\frac{a_{22}}{a_{11} a_{22}-a_{12} a_{21}} &amp; \frac{-a_{12}}{a_{11} a_{22}-a_{12} a_{21}} \\\<br>
\frac{-a_{21}}{a_{11} a_{22}-a_{12} a_{21}} &amp; \frac{a_{11}}{a_{11} a_{22}-a_{12} a_{21}}<br>
\end{array}\right]=\left[\begin{array}{ll}<br>
\frac{a_{11} \times a_{22}}{a_{11} a_{22}-a_{12} a_{21}}+\frac{a_{12} ×(-a_{21})}{a_{11} a_{22}-a_{12} a_{21}} &amp; \frac{a_{11} ×(-a_{12})}{a_{11} a_{22}-a_{12} a_{21}}+\frac{a_{12} \times a_{11}}{a_{11} a_{22}-a_{12} a_{21}} \\\<br>
\frac{a_{21} \times a_{22}}{a_{11} a_{22}-a_{12} a_{21}}+\frac{a_{22} ×(-a_{21})}{a_{11} a_{22}-a_{12} a_{21}} &amp; \frac{a_{21} ×(-a_{12})}{a_{11} a_{22}-a_{12} a_{21}}+\frac{a_{22} × a_{11}}{a_{11} a_{22}-a_{12} a_{21}}<br>
\end{array}\right]=\left[\begin{array}{lll}<br>
1 &amp; 0 \\\<br>
0 &amp; 1<br>
\end{array}\right]<br>
$$
这里有一点需要特别说明,不是每一个矩阵都是可逆的。如果一个矩阵是可逆的,那这个矩阵我们叫做**非奇异矩阵**,如果一个矩阵是不可逆的,那这个矩阵我们就叫做**奇异矩阵**,而且如果一个矩阵可逆,那它的逆矩阵必然是唯一的。
还记得行列式$a_{11} a_{22}-a_{12} a_{21}$吗?如果我们要证明矩阵是可逆的,只要证明行列式不等于零就行。更高阶的逆矩阵的算法也是一样的原理。
最后,我想通过一个现实生活中的案例来让你更多地了解逆矩阵。
一个旅游团由孩子和大人组成,去程他们一起做大巴,每个孩子的票价$3$元,大人票价$3.2$元,总共花费$118.4$元。回程一起做火车,每个孩子的票价$3.5$元,大人票价$3.6$元,总共花费$135.2$元。请问旅游团里有多少小孩和大人?
首先,我们设置一些矩阵,组成线性方程$XA=B$。
<img src="https://static001.geekbang.org/resource/image/e2/96/e291f7bd766d923f1b2a09a7c5765296.png" alt="">
要解$X$,我们就要先计算$A$的逆矩阵$A^{-1}$
$$<br>
A^{-1}=\left[\begin{array}{cc}<br>
3 &amp; 3.5 \\\<br>
3.2 &amp; 3.6<br>
\end{array}\right]^{-1}=\frac{1}{3 \times 3.6-3.5 \times 3.2}\left[\begin{array}{cc}<br>
3.6 &amp; -3.5 \\\<br>
-3.2 &amp; 3<br>
\end{array}\right]=\left[\begin{array}{cc}<br>
-9 &amp; 8.75 \\\<br>
8 &amp; -7.5<br>
\end{array}\right]<br>
$$
接下来再计算$X=B A^{-1}$
$$<br>
\left[\begin{array}{ll}<br>
x_{1} &amp; x_{2}<br>
\end{array}\right]=\left[\begin{array}{ll}<br>
118.4 &amp; 135.2<br>
\end{array}\right]\left[\begin{array}{cc}<br>
-9 &amp; 8.75 \\\<br>
8 &amp; -7.5<br>
\end{array}\right]=\left[\begin{array}{ll}<br>
16 &amp; 22<br>
\end{array}\right]<br>
$$
最终我们得出这个旅游团有16个小孩和22个大人。
这也是解线性方程组的一种方法类似这样的计算被广泛应用在各领域中比如建筑工程、游戏和动画的3D效果上。虽然现在有很多程序包封装了这类数学计算的底层实现但如果你能很好地理解这些概念就可以为编程或算法调优打下坚实的基础。
Last but not least方程次序很重要也就是说$AX=B$和$XA=B$的结果是不同的,这个一定要牢记哦!
### 转置矩阵
一般伴随逆矩阵之后出现的就是转置矩阵。在计算机图形图像处理中,如果要对一个物体进行旋转、平移、缩放等操作,就要对描述这个物体的所有矩阵进行运算,矩阵转置就是这类运算之一,而矩阵的转置在三维空间中的解释就相当于“得到关于某个点对称的三维立体”。所以,转置矩阵的定义很简单。
将矩阵的行列互换得到的新矩阵就叫做转置矩阵transpose。转置矩阵的行列式不变。我们把$m×n$矩阵$A$的行列互换,得到转置矩阵$A^{T}$。
$$<br>
A=\left[\begin{array}{cccc}<br>
a_{11} &amp; a_{12} &amp; \ldots &amp; a_{1 n} \\\<br>
a_{21} &amp; a_{22} &amp; \ldots &amp; a_{2 n} \\\<br>
\ldots &amp; \ldots &amp; \ldots &amp; \ldots \\\<br>
a_{m 1} &amp; a_{m 2} &amp; \ldots &amp; a_{m n}<br>
\end{array}\right]<br>
$$
$$<br>
A^{T}=\left[\begin{array}{cccc}<br>
a_{11} &amp; a_{21} &amp; \ldots &amp; a_{m 1} \\\<br>
a_{12} &amp; a_{22} &amp; \ldots &amp; a_{m 2} \\\<br>
\ldots &amp; \ldots &amp; \ldots &amp; \ldots \\\<br>
a_{1 n} &amp; a_{2 n} &amp; \ldots &amp; a_{m n}<br>
\end{array}\right]<br>
$$
最后,为了方便你理解,我们再总结一下逆矩阵和转置矩阵的性质。你不用死记硬背,重在理解。
1. 矩阵和自身逆矩阵相乘得道单位矩阵,$A A^{-1}=I=A^{-1} A$
1. $A$$B$两矩阵相乘的逆,等于逆矩阵$B$和逆矩阵$A$相乘,这里强调一下乘的顺序很重要,$(A B)^{-1}=B^{-1} A^{-1}$
1. $AB$两矩阵相加后的逆矩阵,不等于各自逆矩阵的相加, $(A+B)^{-1} \neq A^{-1}+B^{-1}$
1. 矩阵转置的转置还是它本身,$\left(A^{T}\right)^{\mathrm{T}}=A$
1. $AB$两矩阵相加后的转置矩阵,等于各自转置矩阵的相加,$(A+B)^{T}=A^{T}+B^{T}$
1. $AB$两矩阵相乘后的转置矩阵等于转置矩阵B和转置矩阵A的相乘这里再次强调乘的顺序很重要$(A B)^{T}=B^{T} A^{T}$。
## 本节小结
好了,到这里矩阵这一讲就结束了,最后我再带你总结一下前面讲解的内容。
今天的知识,你只需要知道矩阵是线性方程组的另一种表达,了解和掌握矩阵的定义和性质就足够了。当然,矩阵还有很多内容,但我认为掌握了我讲的这些内容后,就为以后的一些矩阵应用场景打下了坚实的数学基础,也是下一讲的解线性方程组的前置知识。
<img src="https://static001.geekbang.org/resource/image/0f/87/0f7f18bcde1b8e61a8658d390be91f87.png" alt="">
## 线性代数练习场
对于10维列向量$x=\left(x_{1}, \ldots, x_{10}\right)^{T}$ $v=\left(v_{1}, \ldots, v_{10}\right)^{T}$,如果要计算$y=x x^{T}\left(I+v v^{T}\right) x$,其中$I$是10阶单位矩阵。你会怎么做
友情提醒,这里有多种方式解题。你能不能找到一个最简单的方法来解这道题?虽然结果很重要,但我想说的是过程更重要,而且往往解题过程不同,从计算机角度来说,运算的效率会有极大的不同。
欢迎你在留言区晒出你的运算过程和结果。如果有收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,471 @@
<audio id="audio" title="04 | 解线性方程组:为什么用矩阵求解的效率这么高?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/48/0d/48218014a2915037528e1c6c18718c0d.mp3"></audio>
你好,我是朱维刚。欢迎你跟我一起重学线性代数!
在上一节课中,我讲解了线性方程组的另一种表达——矩阵。那么今天,我们就来讲解一下如何使用矩阵来解线性方程组,也就是如何求线性方程组的特殊解和通用解。
简单的线性方程组我们当然可以运用初中学过的知识来求解那复杂的呢硬来几乎是不可能的了一方面是因为人工计算的错误率很高另一方面即使我们使用计算机用类似for或while循环来实现算法它的计算效率也是极低的。你需要用更科学的方式、方法从另一个角度来看待和求解线性方程组。
而矩阵就是为我们打开高效之门的钥匙,从计算机科学的角度来说,使用矩阵的运算效率实在是高太多了,因为它可以利用计算机的并行能力,甚至在一些迭代法中,还能实现分布式并行计算(迭代法会在后面“应用篇”中讲解)。
## 线性方程组解的寻找
现在,就让我们开始去寻找线性方程组的解。在之前的课程中,我们已经引入了线性方程组的一般表达,你可以看看下面的例子。
$$<br>
\left\{\begin{array}{l}<br>
a_{11} x_{1}+a_{12} x_{2}+\cdots+a_{1 n} x_{n}=b_{1} \\\<br>
a_{21} x_{1}+a_{22} x_{2}+\cdots+a_{2 n} x_{n}=b_{2} \\\<br>
\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \\\<br>
a_{m 1} x_{1}+a_{m 2} x_{2}+\cdots+a_{m n} x_{n}=b_{m}<br>
\end{array}\right.<br>
$$
其中,$a_{ij}$和 $b_{i}$ 属于实数,而且是已知常数,而$x_{j}$是未知变量,$i$和$j$的取值范围分别是:$i=1,…,m$$j=1,…,n$ 。如果我们用矩阵的简单表达方式来看的话,就是$Ax=B$。
要搞清楚概念,我们还是要多看具体的例子。让我们先来看一个实例,来加深一下理解。
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 0 &amp; 8 &amp; -4 \\\<br>
0 &amp; 1 &amp; 2 &amp; 12<br>
\end{array}\right]\left[\begin{array}{c}<br>
x_{1} \\\<br>
x_{2} \\\<br>
x_{3} \\\<br>
x_{4}<br>
\end{array}\right]=\left[\begin{array}{c}<br>
42 \\\<br>
8<br>
\end{array}\right]<br>
$$
很明显,这是一个矩阵表达方式。它的一般线性方程组表达方式是中学的基础知识,你应该很熟悉了。
$$<br>
\left\{\begin{array}{l}<br>
1 \times x_{1}+0 \times x_{2}+8 \times x_{3}+(-4) \times x_{4}=42 \\\<br>
0 \times x_{1}+1 \times x_{2}+2 \times x_{3}+12 \times x_{4}=8<br>
\end{array}\right.<br>
$$
在这个一般线性方程组中有四个未知变量但只有两个等式这就意味着这个线性方程组有无穷多个解这个是中学数学的范畴。通过细心观察我们可以发现第一列和第二列都是由0和1组成的因此你很容易就能发现其中一个解。
$$<br>
42\left[\begin{array}{l}<br>
1 \\\<br>
0<br>
\end{array}\right]+8\left[\begin{array}{l}<br>
0 \\\<br>
1<br>
\end{array}\right]=\left[\begin{array}{c}<br>
42 \\\<br>
8<br>
\end{array}\right]<br>
$$
这个解就是$\left[\begin{array}{llll}42 &amp; 8 &amp; 0 &amp; 0\end{array}\right]^{T}$,也就是说四个未知变量分别为$42$、$8$、$0$、$0$。
$$<br>
\left\{\begin{array}{l}<br>
x_{1}=42 \\\<br>
x_{2}=8 \\\<br>
x_{3}=0 \\\<br>
x_{4}=0<br>
\end{array}\right.<br>
$$
这个解也叫做特殊解。我们刚才已经说过这个线性方程组有无穷多个解那我们确实需要一个聪明的方式来找到其他的解最直观的方式就是通过矩阵的列来构造0。例如对于第三列来说我们可以使用第一和第二列的组合形式来表达。
$$<br>
8\left[\begin{array}{l}<br>
1 \\\<br>
0<br>
\end{array}\right]+2\left[\begin{array}{l}<br>
0 \\\<br>
1<br>
\end{array}\right]=\left[\begin{array}{l}<br>
8 \\\<br>
2<br>
\end{array}\right]<br>
$$
通过计算$Ax=0$,我们得出解$\left[\begin{array}{llll}8 &amp; 2 &amp; -1 &amp; 0\end{array}\right]^{T}$。而事实上,这个解可以乘以任何实数$λ_{1}$,使得$Ax=0$成立。
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 0 &amp; 8 &amp; -4 \\\<br>
0 &amp; 1 &amp; 2 &amp; 12<br>
\end{array}\right]<br>
\left(\begin{array}{l}<br>
\lambda_{1}\left[\begin{array}{l}<br>
8 \\\<br>
2 \\\<br>
-1 \\\<br>
0<br>
\end{array}\right]<br>
\end{array}\right)=0<br>
$$
同理,对于第四列来说,我们可以使用第一和第二列的组合形式来表达,得出另一套解,使得$Ax=0$。
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 0 &amp; 8 &amp; -4 \\\<br>
0 &amp; 1 &amp; 2 &amp; 12<br>
\end{array}\right]<br>
\left(\begin{array}{l}<br>
\lambda_{2}\left[\begin{array}{l}<br>
-4 \\\<br>
12 \\\<br>
0 \\\<br>
-1<br>
\end{array}\right]<br>
\end{array}\right)=0<br>
$$
现在,我们可以把之前的特殊解与刚得出的两套解相组合,得出最终解,这个解也就是我们所说的通用解了。
$$<br>
x \in R^{4}: x=\left[\begin{array}{c}<br>
42 \\\<br>
8 \\\<br>
0 \\\<br>
0<br>
\end{array}\right]+\lambda_{1}\left[\begin{array}{c}<br>
8 \\\<br>
2 \\\<br>
-1 \\\<br>
0<br>
\end{array}\right]+\lambda_{2}\left[\begin{array}{c}<br>
-4 \\\<br>
12 \\\<br>
0 \\\<br>
-1<br>
\end{array}\right], \lambda_{1}, \lambda_{2} \in R<br>
$$
我来总结一下寻找通用解的过程,这个过程分为三步:
1. 我们要寻找一个特殊解,使得$Ax=b$
1. 找到$Ax=0$的所有解;
1. 组合第一和第二步的解形成通用解。
看到了这里你有没有发现有些奇怪呢或者说有没有觉得哪里有点别扭是的好像有点太顺利了。那是因为这个线性方程组比较特别第一列和第二列是由1和0组成的。所以我们只通过观察就能得出特殊解和通用解。
然而,你不可能每次都行大运,就像我们在现实中碰到的这类线性方程组,一般都比这个复杂得多。不过不要慌,有一个算法可以来帮助我们转换任意线性方程组,形成类似的特殊形式,这个算法叫做**高斯消元法**。
高斯消元法的核心就是**线性方程组的初等变换**,于是,我们可以通过高斯消元法,得到围绕初等变换形成的简单矩阵表达形式,接下来我们就可以运用之前的三个步骤来寻找通用解了。
## 初等变换的一般形式
既然高斯消元法的核心就是线性方程组的初等变换,那为了方便你使用高斯消元法,我就有必要来讲一讲初等变换的一般形式有哪些:
1. 两个等式的交换,也就是矩阵行交换;
1. 一个等式,或者说矩阵行乘以一个实数常量;
1. 两个等式相加,或者说矩阵的两行相加。
道理是这样的道理那我们通过一个例子来看看究竟该怎么做线性方程组的初等变换。假设a属于实数现在我们试着来寻找下面这个线性方程组的所有解。我把这个过程细细地拆解为11个步骤建议你仔细看过并理解后再进入下一阶段的学习。
$$<br>
\left\{\begin{array}{c}<br>
-2 x_{1}+4 x_{2}-2 x_{3}-x_{4}+4 x_{5}=-3 \\\<br>
4 x_{1}-8 x_{2}+3 x_{3}-3 x_{4}+x_{5}=2 \\\<br>
x_{1}-2 x_{2}+x_{3}-x_{4}+x_{5}=0 \\\<br>
x_{1}-2 x_{2}-3 x_{4}+4 x_{5}=a<br>
\end{array}\right.<br>
$$
1.我们要把这个线性方程组转换成矩阵的表达形式,$Ax=b$。
$$<br>
\left[\begin{array}{ccccccc}<br>
-2 &amp; 4 &amp; -2 &amp; -1 &amp; 4 &amp; \mid &amp; -3 \\\<br>
4 &amp; -8 &amp; 3 &amp; -3 &amp; 1 &amp; \mid &amp; 2 \\\<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
1 &amp; -2 &amp; 0 &amp; -3 &amp; 4 &amp; \mid &amp; a<br>
\end{array}\right]<br>
$$
2.接着我们来交换第一和第三行。
$$<br>
\left[\begin{array}{ccccccc}<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
4 &amp; -8 &amp; 3 &amp; -3 &amp; 1 &amp; \mid &amp; 2 \\\<br>
-2 &amp; 4 &amp; -2 &amp; -1 &amp; 4 &amp; \mid &amp; -3 \\\<br>
1 &amp; -2 &amp; 0 &amp; -3 &amp; 4 &amp; \mid &amp; a<br>
\end{array}\right]<br>
$$
注意你知道我们为什么选择第一行和第三行交换吗其实这是为了便于计算。而具体交换哪一行是有个小技巧的如果某行的第一个元素有1我们就可以把这一行移到第一行。
3.我们以第一行为基础,开始执行乘和加变换,将第一行乘以-4的结果和第二行相加从而获得了下面这样的结果。
$$<br>
\left[\begin{array}{ccccccc}<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
0 &amp; 0 &amp; -1 &amp; 1 &amp; -3 &amp; \mid &amp; 2 \\\<br>
-2 &amp; 4 &amp; -2 &amp; -1 &amp; 4 &amp; \mid &amp; -3 \\\<br>
1 &amp; -2 &amp; 0 &amp; -3 &amp; 4 &amp; \mid &amp; a<br>
\end{array}\right]<br>
$$
4.然后我们用同样的方法将第一行乘以2的结果再和第三行相加得到了下面这样的结果。
$$<br>
\left[\begin{array}{ccccccc}<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
0 &amp; 0 &amp; -1 &amp; 1 &amp; -3 &amp; \mid &amp; 2 \\\<br>
0 &amp; 0 &amp; 0 &amp; -3 &amp; 6 &amp; \mid &amp; -3 \\\<br>
1 &amp; -2 &amp; 0 &amp; -3 &amp; 4 &amp; \mid &amp; a<br>
\end{array}\right]<br>
$$
5.以此类推,我们将第一行乘以-1的结果和第四行相加继续获得新矩阵。
$$<br>
\left[\begin{array}{ccccccc}<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
0 &amp; 0 &amp; -1 &amp; 1 &amp; -3 &amp; \mid &amp; 2 \\\<br>
0 &amp; 0 &amp; 0 &amp; -3 &amp; 6 &amp; \mid &amp; -3 \\\<br>
0 &amp; 0 &amp; -1 &amp; -2 &amp; 3 &amp; \mid &amp; a<br>
\end{array}\right]<br>
$$
6.将第二行乘以-1的结果和第四行相加得到下面这样的结果。
$$<br>
\left[\begin{array}{ccccccc}<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
0 &amp; 0 &amp; -1 &amp; 1 &amp; -3 &amp; \mid &amp; 2 \\\<br>
0 &amp; 0 &amp; 0 &amp; -3 &amp; 6 &amp; \mid &amp; -3 \\\<br>
0 &amp; 0 &amp; 0 &amp; -3 &amp; 6 &amp; \mid &amp; a-2<br>
\end{array}\right]<br>
$$
7.将第三行乘以-1的结果和第四行相加。<br>
$$<br>
\left[\begin{array}{ccccccc}<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
0 &amp; 0 &amp; -1 &amp; 1 &amp; -3 &amp; \mid &amp; 2 \\\<br>
0 &amp; 0 &amp; 0 &amp; -3 &amp; 6 &amp; \mid &amp; -3 \\\<br>
0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; \mid &amp; a+1<br>
\end{array}\right]<br>
$$
8.第二行乘以-1第三行乘以$-\frac{1}{3}$。<br>
$$<br>
\left[\begin{array}{ccccccc}<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 &amp; \mid &amp; 0 \\\<br>
0 &amp; 0 &amp; 1 &amp; -1 &amp; 3 &amp; \mid &amp; -2 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1 &amp; -2 &amp; \mid &amp; 1 \\\<br>
0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; \mid &amp; a+1<br>
\end{array}\right]<br>
$$
9.现在,这个矩阵就是一个简单形式的矩阵,也叫做**行阶梯形矩阵**Row-Echelon FormREF
$$<br>
\left\{\begin{array}{r}<br>
x_{1}-2 x_{2}+x_{3}-x_{4}+x_{5}=0 \\\<br>
x_{3}-x_{4}+3 x_{5}=-2 \\\<br>
x_{4}-2 x_{5}=1 \\\<br>
0=a+1<br>
\end{array}\right.<br>
$$
一个矩阵成为行阶梯形矩阵需满足两个条件:
- 如果它既有零行,又有非零行,则零行在下,非零行在上;
- 如果它有非零行则每个非零行的第一个非零元素所在列号自上而下严格单调上升正如之前的这个矩阵列号自上而下是1、3、4是严格单调上升的。
10.你可以看出,只有在$a=-1$的情况下,这个线性方程组才有解,特殊解是$\left[\begin{array}{lllll}2 &amp; 0 &amp; -1 &amp; 1 &amp; 0\end{array}\right]^{\mathrm{T}}$。
11.最后,我们得出这个线性方程组的通用解,如下图所示。
$$<br>
x \in R^{5}: x=\left[\begin{array}{c}<br>
2 \\\<br>
0 \\\<br>
-1 \\\<br>
1 \\\<br>
0<br>
\end{array}\right]+\lambda_{1}\left[\begin{array}{l}<br>
2 \\\<br>
1 \\\<br>
0 \\\<br>
0 \\\<br>
0<br>
\end{array}\right]+\lambda_{2}\left[\begin{array}{c}<br>
2 \\\<br>
0 \\\<br>
-1 \\\<br>
2 \\\<br>
1<br>
\end{array}\right], \lambda_{1}, \lambda_{2} \in R<br>
$$
注意,这里有一个概念很重要,那就是**主元**。主元就是在矩阵消元过程中,每列要保留的非零元素,我们可以用它把该列其他元素消去。在阶梯型矩阵中,每个非零行第一个非零元素就是主元。
拿之前的第8步计算后的结果来举例第一行的第一个元素1就是主元第二行第三个元素1是主元第三行的第四个元素1也是主元。
<img src="https://static001.geekbang.org/resource/image/8f/1f/8f1cfb8cf55a5226f00979e2cfbab11f.png" alt="">
对应行阶梯形矩阵主元的变量叫做基本变量,而其他的变量叫做自由变量,这个例子中,$x_{1}$、$x_{3}$、$x_{4}$就是基本变量,$x_{2}$、$x_{5}$则是自由变量。使用行阶梯形矩阵能更简单地得出特殊解,所以我们可以使用主元列来表达线性方程组:
$$<br>
b=\sum_{i=1}^{P} \lambda_{i} \mathrm{p}_{i}, i=1, \ldots, P<br>
$$
在之前的例子中,我们使用主元列来表达成下面这样的矩阵形式:
$$<br>
\lambda_{1}\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
0 \\\<br>
0<br>
\end{array}\right]+\lambda_{2}\left[\begin{array}{l}<br>
1 \\\<br>
1 \\\<br>
0 \\\<br>
0<br>
\end{array}\right]+\lambda_{3}\left[\begin{array}{c}<br>
-1 \\\<br>
-1 \\\<br>
1 \\\<br>
0<br>
\end{array}\right]=\left[\begin{array}{c}<br>
0 \\\<br>
-2 \\\<br>
1 \\\<br>
0<br>
\end{array}\right]<br>
$$
于是,我们最终得出 $λ_{3}=1$$λ_{2}=-1$$λ_{1}=2$ ,分别对应于$x_{4}$、$x_{3}$、$x_{1}$。不要忘了,对于非主元列,我们已经隐式地把系数设置成了$0$,所以这个线性方程组的特殊解是$x=\left[\begin{array}{lllll}2 &amp; 0 &amp; -1 &amp; 1 &amp; 0\end{array}\right]^{\mathrm{T}}$。
## 简化行阶梯形矩阵
这里我们再引入一个概念,简化行阶梯形矩阵,因为引入简化行阶梯形矩阵对于线性方程组的求解来说会更简单。其实,高斯消元法的核心就是通过初等变换,把线性方程组转换成简化行阶梯形矩阵。那么一个方程组是简化行阶梯形矩阵,必须满足哪几个条件呢?
1. 这个方程组必须是行阶梯形矩阵;
1. 方程组的每一个主元都是1
1. 主元在它的列中是唯一的非0元素。
现在,我们再通过一个实例,看看该如何通过高斯消元法计算一个矩阵的逆矩阵。设矩阵$A$如下图:
$$<br>
A=\left[\begin{array}{llll}<br>
1 &amp; 0 &amp; 2 &amp; 0 \\\<br>
1 &amp; 1 &amp; 0 &amp; 0 \\\<br>
1 &amp; 2 &amp; 0 &amp; 1 \\\<br>
1 &amp; 1 &amp; 1 &amp; 1<br>
\end{array}\right]<br>
$$
首先,我们形成$A$的增广矩阵(具体方法参见上一节)。<br>
$$<br>
\left[\begin{array}{lllllllll}<br>
1 &amp; 0 &amp; 2 &amp; 0 &amp; \mid &amp; 1 &amp; 0 &amp; 0 &amp; 0 \\\<br>
1 &amp; 1 &amp; 0 &amp; 0 &amp; \mid &amp; 0 &amp; 1 &amp; 0 &amp; 0 \\\<br>
1 &amp; 2 &amp; 0 &amp; 1 &amp; \mid &amp; 0 &amp; 0 &amp; 1 &amp; 0 \\\<br>
1 &amp; 1 &amp; 1 &amp; 1 &amp; \mid &amp; 0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
其次,使用我们前面刚刚讲过的高斯消元法计算出简化行阶梯形矩阵。
$$<br>
\left[\begin{array}{ccccccccc}<br>
1 &amp; 0 &amp; 0 &amp; 0 &amp; \mid &amp; -1 &amp; 2 &amp; -2 &amp; 2 \\\<br>
0 &amp; 1 &amp; 0 &amp; 0 &amp; \mid &amp; 1 &amp; -1 &amp; 2 &amp; -2 \\\<br>
0 &amp; 0 &amp; 1 &amp; 0 &amp; \mid &amp; 1 &amp; -1 &amp; 1 &amp; -1 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1 &amp; \mid &amp; -1 &amp; 0 &amp; -1 &amp; 2<br>
\end{array}\right]<br>
$$
最后,我们就得到$A$的逆矩阵,如下图所示。
$$<br>
A^{-1}=\left[\begin{array}{cccc}<br>
-1 &amp; 2 &amp; -2 &amp; 2 \\\<br>
1 &amp; -1 &amp; 2 &amp; -2 \\\<br>
1 &amp; -1 &amp; 1 &amp; -1 \\\<br>
-1 &amp; 0 &amp; -1 &amp; 2<br>
\end{array}\right]<br>
$$
接下来,我们只要使用公式$A A^{-1}=I$ 就可以对结果进行验证了。
## 更多解线性方程组的方法
到目前为止,相信你已经了解了如何解线性方程组,包括特殊解和通用解,以及如何使用高斯消元法来解线性方程组。最后,我再总结一些解方法来作为你的知识扩展。
第一个方法假设一个矩阵A是方阵行数与列数相等的矩阵并且可逆$Ax=B$ ,那$x$解就可以写成$x=A^{-1}B$,但如果$A$矩阵不可逆,也不是方阵,那我们就只能使用下面这个变换来求$x$解了。
$$Ax=B⇔A^{T}Ax=A^{T}B⇔x=(A^{T}A)^{-1}A^{T}B$$
其中矩阵A的转置矩阵和A相乘的逆矩阵再和A的转置矩阵相乘我们把它叫做穆尔彭罗斯伪逆矩阵Moore-Penrose pseudo inverse简称伪逆。
$$(A^{T}A)^{-1}A^{T}$$
这个方法有两个弊端:第一,矩阵乘和逆矩阵的计算太复杂;第二,数值精确度不高。因此,从实践角度来说,我一般不推荐使用。
第二个方法是高斯消元法。高斯消元法是非常直观的,它在很多计算中都起到了关键的作用,比如:
1. 计算行列式;
1. 检查向量是否是线性独立的;
1. 计算矩阵的逆矩阵;
1. 计算矩阵的秩;
1. 决定向量空间的基。
但当高斯消元法面对百万、千万级别的变量时,就捉襟见肘了。而这类级别的计算才是我们在实践中经常会遇到的,因此从实践角度来说,我也一般不推荐使用。因为高斯消元法属于直接法,直接法是经历有限次的运算得到方程组精确解的方法。但是,学习直接法是有意义的,虽然直接法在实际工作中不常用,但是它也能处理一些日常小问题,更重要的是,它稳固了我们进一步学习其它方法的基础。
我要讲的第三种方法,就是与直接法对应的间接法了。在实践中,线性方程组的求解都是间接的,也就是运用迭代法。
迭代法是采用极限过程用线性方程组的近似解逐步逼近精确解的方法。所以迭代法的关键在于每次迭代残余错误的减少以及如何能够收敛到解。常见的迭代法有两类定常迭代法Stationary iterative method和Krylov子空间方法我会在应用篇中讲解
>
<p>定常迭代法理查德森迭代法Richardson method、雅可比方法Jacobi method、Gauß-Seidel方法、逐次超松弛法Successive over-relaxation method简称SOR<br>
Krylov子空间方法共轭梯度法Conjugate gradient、 广义极小残余算法Generalized minimal residual、双共轭梯度法Biconjugate gradient</p>
这里提到的几种迭代法都是在实践中比较常用的,也是计算机编程中经常实现的算法,但由于迭代法更多属于微分和极限领域,所以这里就不详细介绍了,我会在线性代数应用篇的“数值线性代数”那节课中再做讲解。
如果在课程内容结束后你还有余力学习更多的内容这里我先推荐两本书给你作参考一本是《Introduction to Numerical Analysis》另一本是《Linear Algebra》。这两本书里面都有进一步地讲解了线性方程组的迭代法求解的内容。
>
<p>1.《Introduction to Numerical Analysis》<br>
作者Stoer, Josef, Bulirsch, R.<br>
2002年出版<br>
2.《Linear Algebra》<br>
作者Liesen, Jörg, Mehrmann, Volker<br>
2015年出版</p>
## 本节小结
好了,到这里解线性方程组这一讲就结束了,最后我再总结一下前面讲解的内容。
首先,我用一个简单的线性方程组,通过直接观察的方法来计算这个方程组的特殊解和通用解,接着通过实例详细地介绍了高斯消元法,最后我给出了一些在实践中常用的线性方程组解方法。只有弄清楚这些基础知识的本质,你才能更进一步,去了解其他计算方法。
线性方程组的求解已经成为了世界上最快计算机的测试标准,因为通过矩阵运算,计算机的并行计算能力暴露无遗。希望你能够在这些基础之上,阅读我推荐的两本书,并且把这些方法运用到实践中,特别是机器学习,因为机器学习也用到了很多迭代方法。
<img src="https://static001.geekbang.org/resource/image/24/8b/24dbdb71282f2685353b63bd4ec8ee8b.png" alt="">
## 线性代数练习场
练习时刻到了,今天的练习题比较简单,请你用高斯消元法求下面的线性方程组。
$$<br>
\left\{\begin{array}{c}<br>
x_{1}+x_{2}-2 x_{3}-x_{4}=-1 \\\<br>
x_{1}+5 x_{2}-3 x_{3}-2 x_{4}=0 \\\<br>
3 x_{1}-x_{2}+x_{3}+4 x_{4}=2 \\\<br>
-2 x_{1}+2 x_{2}+x_{3}-x_{4}=1<br>
\end{array}\right.<br>
$$
欢迎在留言区和[部落](https://horde.geekbang.org/channel/list/39)里晒出你的运算过程和结果,留下你的学习痕迹。如果你有所收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,198 @@
<audio id="audio" title="05 | 线性空间:如何通过向量的结构化空间在机器学习中做降维处理?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/48/89/48a7931d7c06e5ce710f6ec502825489.mp3"></audio>
你好,我是朱维刚。欢迎你跟我一起重学线性代数!
今天我们来聊一聊“线性空间”。在“[基本概念](https://time.geekbang.org/column/article/265296)”那一节课中,我讲到了向量,你也看到了,线性方程组是能够通过矩阵或向量来表达的。那为什么我们还要学习线性空间呢?
说到线性空间,其实你可以通过“空间”这个词把线性空间和我们的生活做个类比。就像我们生活在三维世界中,在这个空间中,一切物质都是运动的,而运动也是有一定规律的。这么来看的话,空间其实就是一个具有实际意义的集合,其中包含了**对象**和**运动**。
把这个理解平移到线性空间也是一样的,向量就是对象,如果把**向量**看成是**线性空间中的点**,那**向量的变换**就是**点在空间中的运动**。所以,线性空间也是一个集合,它的意义在于,赋予了向量生命和活力,只有掌握了线性空间,我们才能真正在实际运用中有的放矢。因为所有的活动都要在这个空间中发生,比如:线性空间中用到的傅立叶变换。
## 组(群)
还是老样子,我们要先从学习线性空间会用到的基础知识开始讲起。
我们先来讲一下“组”,组也可以叫成大家习惯的“群”(以下均以“组”称呼)。说到“组”,它其实是一个通用的概念,和线性空间没有什么关系,但我之所以要先说组,是因为组(群)和空间是类似的,也是集合,性质也差不多,如果你了解了组,就更容易理解线性空间了。而且,组在计算机科学中是得到了广泛应用的,特别是在计算机密码学和图形图像处理中。
说了这么多,“组”到底是什么呢?组,其实就是包含一系列元素的集合,在对这些集合元素实施某类运算后,这个集合仍然保持着封闭性。可能这么说你会有些疑惑,我还是通过数学方法来定义组,可能会让你的思路更加清晰一些。
我们先来定义一个集合$G$和集合上的某一类运算,比如:乘$\otimes$,使得 $G \otimes G$ 的结果还是属于$G$,如果我们要$G:=(G, \otimes)$是一个组,则需要满足以下这些条件:
1.$G$在$\otimes$运算中是封闭的,也就是:$\forall x, y \in G: x \otimes y \in G$。<br>
2. 满足结合律,也就是:$\forall x, y, z \in G:(x \otimes y) \otimes z=x \otimes(y \otimes z)$。<br>
3. 恒等元素(或者叫做中性元素)$e$,满足:$\exists \mathrm{e} \in G, \forall x \in G: x \otimes e=x, e \otimes x=x$这里的恒等元素e在一般数字中你可以认为是$1$,而在矩阵中就可以认为是单位矩阵。<br>
4. 有$x$的逆元素$y$,使得:$\forall \mathrm{e} \in G, \exists x \in G: x \otimes y=e, y \otimes x=e$,其中$e$是恒等元素。
再补充一点,如果满足$\forall x, y \in G: x \otimes y=y \otimes x$,则$G:=(G, \otimes)$就叫作交换组。
现在我们来做个测试,看看你是否理解了组的定义。
一个$n×n$的实数矩阵$A$和它的乘法运算是一个组吗?通过符号表达就是:$\left(A^{n \times n}, \quad \cdot\right)$。
想要知道这个问题的答案,我们就需要用前面满足组的这几个条件来分析一下。
首先,是封闭性和结合律,从矩阵乘的定义就能直接看出来,它们是满足的;其次,我们来看恒等元素,单位矩阵就是矩阵元素,也满足组条件;最后,我们看看逆元素,假设$A$矩阵的逆矩阵$A^{-1}$存在,那很明显,满足$AA^{-1}=I$,这里$I$就是恒等元素。
于是,我们可以说$\left(A^{n \times n}, \quad \cdot\right)$是一个组,而矩阵乘不符合交换律,所以这个组并不是交换组。
## 向量空间
如果我们在“组”的基础上再扩展一下,就能够很顺利地来到“线性空间”。说起线性空间,它也叫作向量空间,它在一些书本和网络上的解释都是比较晦涩难懂的,但如果我们在“组”的基础上来解释它,你应该会比较容易理解了。
刚才我们说的组只包含了某一类运算,这类运算是在集合元素上的内部运算,我们把它定义为加$+$运算,现在再引入一类外部运算,标量乘$(·)$。于是,你可以想象一下,我们可以把内部运算看成是加法,把外部运算看成是“缩放”,因为标量乘就是一个标量和向量相乘。如果从二维坐标系的角度来看一下,点$(1, 1)$和标量$2$相乘就是$(2, 2)$,这个就是放大效果。
<img src="https://static001.geekbang.org/resource/image/e5/cd/e53c4738bee584b913365ce21f64f9cd.png" alt="">
在通过“组”来认识向量空间后,再从数学角度去看向量空间的定义,你应该就能完全理解了。
一个实数向量空间$V$是一个集合,它包含了两类运算,一类是加,一类是标量乘,而且运算都满足$V$的封闭性,也就是说,$V$中元素的运算结果还是属于$V$。
$$<br>
\begin{array}{l}<br>
+: V+V \rightarrow V \\\<br>
\cdot : \lambda \cdot V \rightarrow V<br>
\end{array}<br>
$$
这个向量空间可以表示成$V:=(V,+,\cdot)$,其中:
1.向量空间$V$的$(V,+)$是一个交换组。<br>
2.V满足分配律$\forall \lambda \in R, x, y \in V: \lambda \cdot(x+y)=\lambda \cdot x+\lambda \cdot y$;以及$\forall \lambda, \varphi \in R, x \in V:(\lambda+\varphi) \cdot x=\lambda \cdot x+\varphi \cdot x$。<br>
3.V外部运算满足结合律$\forall \lambda, \varphi \in R, x \in V: \lambda \cdot(\varphi \cdot x)=(\lambda \cdot \varphi) \cdot x$。<br>
4.V外部运算的恒等元素满足$\forall x \in V: 1 \cdot x=x$。
在向量空间$V$中的元素$x$是向量,向量空间加运算$(V,+)$的恒等元素是零向量$0=\left[\begin{array}{lll}0, &amp; \ldots &amp; , 0\end{array}\right]^{T}$。这里的加运算是内部运算,也叫做向量加,元素$λ$属于实数,叫做标量,外部运算乘$·$是标量乘。
好了,我给出了向量空间的一般描述和数学定义,如果你还是有一些不理解,也没有关系,我再举两个例子来加深你对向量空间的理解。
### 例1进一步理解向量加和标量乘
对于向量空间的向量加和标量乘:我们定义一个实数向量空间$R^{n}$$n$表示向量元素:
<li>
“加”定义为向量之间的加:$x+y=\left(x_{1}, \ldots, x_{n}\right)+\left(y_{1}, \ldots, y_{n}\right)=\left(x_{1}+y_{1}, \ldots, x_{n}+y_{n}\right)$。 加的结果还是属于向量空间$R^{n}$。
</li>
<li>
<p>标量乘就是向量乘标量:$\lambda x=\lambda\left(x_{1}, \ldots, x_{n}\right)=\left(\lambda x_{1}, \ldots, \lambda x_{n}\right)$。<br>
标量乘的结果还是属于向量空间$R^{n}$。</p>
</li>
### 例2进一步理解矩阵加和标量乘
对于向量空间的矩阵加和标量乘:我们定义一个实数向量空间$R^{m×n}$,用$m×n$表示$m$行$n$列矩阵元素:
我们把“加”定义为矩阵之间的加。加的结果还是属于向量空间$R^{m×n}$。
$$<br>
A+B=\left[\begin{array}{ccc}<br>
a_{11}+b_{11} &amp; \ldots &amp; a_{1 n}+b_{1 n} \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
a_{m 1}+b_{m 1} &amp; \ldots &amp; a_{m n}+b_{m n}<br>
\end{array}\right]<br>
$$
而标量乘就是矩阵乘标量。标量乘的结果还是属于向量空间$R^{m×n}$。
$$<br>
\lambda A=\left[\begin{array}{ccc}<br>
\lambda a_{11} &amp; \ldots &amp; \lambda a_{1 n} \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
\cdot &amp; &amp; \cdot \\\<br>
\lambda_{m 1} &amp; \ldots &amp; \lambda \dot{a}_{m n}<br>
\end{array}\right]<br>
$$
到这里,相信你应该了解了向量空间的基本概念,接下来这一讲的重头戏就要来了,它就是向量子空间。
## 向量子空间
为什么说向量子空间是重头戏?那是因为它在机器学习中的地位相当重要,被用在了**降维算法**中。这里我会分两步来讲解,先讲向量子空间的基本概念,再通过一个机器学习的例子,能让你更了解它,并灵活运用在工作实践中。
### 什么是向量子空间?
从“子”这个字,我们可以很直观地想到,它是被包含在向量空间中的,事实也确实如此。
已知$V:=(V,+,\cdot)$是一个向量空间,如果$U \subseteq V, U \neq 0$,那么$U:=(U,+,\cdot)$就是$V$的向量子空间,或者叫做线性子空间。向量子空间$U$自然继承$V$的许多属性,其中包括:交换组的属性、分配律、结合律和中性元素。除此以外,要判断$U$是不是向量子空间,我们还需要这两个条件:
1.$U \neq 0$,但$0 \in U$。<br>
2. U的封闭性满足外部运算$\forall \lambda \in R, \forall x \in U: \lambda x \in U$,同时满足内部运算:$\forall x, y \in U: x+y \in U$。
介绍完向量子空间基本概念后,我们一起来通过一个例子来巩固一下所学的知识,看看你是否已经掌握了向量子空间。
请你观察下面列举的A、B、C三张图像里面有 $R^{2}$的向量子空间吗?
<img src="https://static001.geekbang.org/resource/image/50/bd/50853abef85246b1f93d502eaf31a1bd.png" alt="">
这里我不会给出答案你可以自己思考一下友情提醒A、B、C中只有一个是向量子空间。
### 机器学习中的向量子空间
结合实践来看向量子空间的时候到了。在机器学习中,直接计算高维数据困难重重,一方面是数据处理和分析困难,使得数据可视化几乎不可能;另一方面是因为数据存储量太大,计算要付出的代价太高。
所以,我们要从向量空间中去除冗余数据,形成向量子空间。这样数据存储量就被极大地压缩了,处理和分析数据也简单了很多。因为高维数据中其实有很多维是冗余的,它们可以被其它维组合表示,也就是“降维”。
**降维**就是利用结构化和相关性在尽量保证信息不损失的情况下转换数据表现形式让数据更“紧凑”。换句话说你可以把降维看成是数据压缩技术类似图像的jpeg和音频的MP3压缩算法。或者简单地说降维就是将数据投射到一个低维子空间比如三维数据集可以降成二维也就是把数据映射到平面上。
机器学习中运用最多的降维算法就是主成分分析简称PCAPrincipal Component Analysis也叫做卡尔胡宁-勒夫变换Karhunen-Loeve Transform。它是一种用于探索高维数据结构的技术已经存在超过100年了但至今仍然广泛被使用在数据压缩和可视化中。
我们来看一个例子假设你负责的是机器学习算法而你的应用场景是车辆的牌照识别也就是OCROptical Character Recognition光学字符识别。在这个场景中大街上的摄像头必须实时捕捉运动车辆的牌照一旦发现问题车辆就需要快速识别牌照并移交交警监管部门来做进一步处理。你会怎么处理呢
牌照被拍下后就是图片为了减小图像原始数据量减少后续处理时的计算量这些图片首先需要进行经过灰度处理牌照只需要数字不需要对彩色图像的RGB三个分量都进行处理处理后就会变成类似这样的形式
<img src="https://static001.geekbang.org/resource/image/50/88/504b5468d473f66868f2f45e8ced5188.png" alt="">
假定每个数字是一个$28*28$尺寸的灰度图片包含784个像素那每张灰度数字图片就是一个向量这个向量就有784个维度可以表示成$x \in R^{784}$而你的样本库少说也有几十万个样本数据如果按一般的方法是不可能做到实时识别的。所以这样的场景就需要使用PCA来压缩数据进行大幅度降维。
这里我们简单一些从二维的角度来看看PCA。在PCA中最关键的就是寻找数据点$x_{n}$的相似低维投影$y_{n}$,而$y_{n}$就是子向量空间。
考虑$R^{2}$和它的两个基,$e_{1}=[1,0]^{T}$、$e_{2}=[0,1]^{T}$$x \in R^{2}$能够表示成这两个基的线性组合“基”会在第7节课中详细介绍
$$<br>
\left[\begin{array}{l}<br>
5 \\\<br>
3<br>
\end{array}\right]=5 e_{1}+3 e_{2}<br>
$$
于是,相似低维投影$y_{n}$就可以表示成下面这种形式。
$$<br>
y_{n}=\left[\begin{array}{l}<br>
0 \\\<br>
z<br>
\end{array}\right] \in R^{2}, z \in R<br>
$$
同时,$y_{n}$也可以写成这样的形式:$y_{n}=0 e_{1}+z e_{2}$。
这里的$z$就是我们要找的值,而$y_{n}$就是一个向量子空间$U$它的维度是一维。最后我们再通过下图来更直观地说明一下PCA的过程。
<img src="https://static001.geekbang.org/resource/image/24/c4/245a9f1c10c859d2c6094e101fbf62c4.png" alt="">
图的左边是原始向量空间$x$,经过压缩后,我们找到了子向量空间$z$$z$经过重构后,形成了最终的向量空间$y$$y$还是属于原来的向量空间,但$y$却拥有比$x$更低的维度表现。
从数学的角度看,我们其实就是在寻找$x$和$z$之间的线性关系,使得$z=B^{T}x$,以及$y=Bz$,其中$B$是矩阵。如果我们从数据压缩技术方向来看就更容易理解了图中的左边箭头是编码过程也就是压缩右边的箭头是解码过程也就是映射而矩阵B就是把属于$R^{M}$向量空间的低维的$z$,映射回原来的向量空间$R^{D}$。同理,矩阵$B^{T}$就是把属于原来$R^{D}$向量空间的高维$x$压缩成低维的$z$。
## 本节小结
好了,到这里线性空间这一讲就结束了,最后我再总结一下前面讲解的内容。
今天的知识很重要,实践中都是围绕向量空间展开的,也就是说向量空间是实践的基本单位,你也一定要掌握子向量空间,因为现实中数据都是高维度的,从向量空间降维后找到子向量空间,这样就能大大提高数据运算和分析的效率。
再次特别提醒:这一讲非常重要,因为后面几讲都是围绕向量空间展开的,如果你哪里没看懂,一定要多看几次,确保完全明白了。有任何问题,你也可以随时在留言区向我提问。
## 线性代数练习场
之前我讲了一个现实的向量空间降维场景:车辆的牌照识别,这里,我们通过另一个现实场景,来练习一下向量空间降维的思维。
目前市场上语音识别的应用有很多比如天猫精灵、苹果Siri、小爱等等而语音识别涉及的技术有很多有语言建模、声学建模、语音信号处理等等。在语音信号处理中语音声波通过空气传播并被麦克风捕获麦克风将压力波转换为可捕获的电活动。我们对电活动进行采样用以创建描述信号的一系列波形采样。
采样是数据收集的过程,数据收集后需要做数据预处理,而预处理的关键一步就是特征提取,现在请你从“特征提取”的方向上思考下,有哪些和目前所学到的数学知识有关?
>
友情提醒:特征提取就是数字化过程,也是向量化后形成向量空间的过程。
欢迎在留言区写出你的思考,我会及时回复。如果有收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,206 @@
<audio id="audio" title="06 | 线性无关如何理解向量在N维空间的几何意义" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/9d/d9/9d8067102a45336aa31056dbdb3232d9.mp3"></audio>
你好,我是朱维刚。欢迎你继续跟我学习线性代数,今天我们要讲的内容是“线性无关”。
上一节课中,我讲的是线性空间的基本概念,是立足于宏观角度来讲的。那么今天,我们就要深入线性空间,从微观角度,再来看看线性空间中元素之间的关系,也就是**线性组合**。
线性组合有**线性相关**和**线性无关**,而线性无关是线性代数中最重要的概念之一,为什么这么说呢?因为线性相关的向量组中存在多余的向量,去掉它们不影响我们所考虑的问题。而线性无关向量集合是没有任何冗余的,也就是说,失去集合中任意一个向量,我们都会失去一些东西。接下来我们就开始把这个“直观上的理解”固化成实实在在的知识体系。
在正式开始讲解前,我还是一样,先通过一个例子,让你对线性组合有个大致的了解。
假设,有一家物流运输公司$Y$$Y$主要靠车辆的货物运输来赚钱,而且$Y$拥有很多直营的运输车辆,设共有$n$辆车,$x_{1}, x_{2}, \ldots, x_{n}$,那么,$Y$公司的收入可以表示成:$Y_{i}=a_{0}+a_{1} x_{1}+a_{2} x_{2}+\cdots+a_{n} x_{n}$。
这是个线性方程,它的系数$a$表示了各辆车对收入的贡献率,$a_{0}$表示企业的日常总支出。这时企业内,任何一辆车对收入的贡献大小和这个企业其他的车都没有关系,所以各车之间就是**线性无关**的。如果这时,我们再聚焦到每辆车本身的利润上,比如我们都知道的这个公式:利润=收入-成本,那每辆车的利润、成本和收入之间就是**线性相关**的。
## 线性组合
在例子中,我们已经知道了线性组合中的线性相关、线性无关的意思。那么接下来,我们来看线性组合的确切定义:一个向量空间$V$和属于这个向量空间的有限数量的向量$x_{1}, x_{2}, \ldots, x_{k}$,对于属于向量空间$V$的每个向量$v$,都有这样的表达形式:$v=\lambda_{1} x_{1}+\lambda_{2} x_{2}+\cdots+\lambda_{k} x_{k}=\sum_{i=1}^{k} \lambda_{i} x_{i}$。
那么,$v$就是向量$x_{1}, x_{2}, \ldots, x_{k}$的线性组合。
我们继续看线性相关和线性无关的定义,一个向量空间$V$和属于这个向量空间的有限数量的向量$x_{1}, x_{2}, \ldots, x_{k}$,有一个非平凡线性组合:$0=\lambda_{1} x_{1}+\lambda_{2} x_{2}+\cdots+\lambda_{k} x_{k}=\sum_{i=1}^{k} \lambda_{i} x_{i}$。如果其中至少有一个$λ$不等于0这时向量$x_{1}, x_{2}, \ldots, x_{k}$是**线性相关**的。而如果有平凡解存在,例如:$λ_{1}= \ldots=λ_{k}=0$,则向量$x_{1}, x_{2}, \ldots, x_{k}$是**线性无关**的。
>
注意:这里有个数学用语“平凡解”,术语“平凡”经常用于结构非常简单的对象,一般来说,$Ax=0$中的零解,即$x=0$,就叫做平凡解。
现在,我们通过一个实际的例子来加深一下理解。
假如你想从上海去杭州,有两条路线可以供你选择:一条是从上海出发,行驶$84.9$公里后到苏州,再从苏州出发行驶$120.14$公里后到达杭州;另一条是从上海出发行驶$164.7$公里后直接到达杭州。
<img src="https://static001.geekbang.org/resource/image/1d/3b/1dc1a7aa6c762519eff1c6d9cb00343b.png" alt="">
我们可以把地理位置坐标系看成是一个二维的向量空间,上海到苏州可以表示成向量$v1$,苏州到杭州可以表示成向量$v2$,上海到杭州可以表示成向量$v3$,这样很明显可以看出,向量$v1$和$v2$是线性无关的,而上海到杭州$v3$却可以被另两个向量$v1$和$v2$表达,于是我们可以说$v1$$v2$和$v3$之间是线性相关的。
## 线性无关的判断方式
线性无关的判断,对于实践中数据冗余的判断非常有用,那有没有一些方法来判断向量之间是线性无关的呢?我们来看一些有用的方法吧:
1. k向量要么线性无关要么线性相关没有第三个选择。
1. 已知向量集合 $x_{1}, x_{2}, \ldots, x_{k}$ 中至少有一个是$0$向量,则它们是线性相关的。
1. 已知有向量集合 $x_{1}, x_{2}, \ldots, x_{k}$ ,其中$x_{k}≠0$ ,如果一个向量等于另一向量和一个标量的乘,$x_{i}=λx_{j}$ ,那么,向量集合 $x_{1}, x_{2}, \ldots, x_{k}$ 是线性相关的。
之前的方式方法都是偏理论的,而更加实践的方法,就是用高斯消元法来判断向量集合$x_{1}, x_{2}, \ldots, x_{k}$是否是线性无关的。将所有向量组合成矩阵的列,做高斯消元,一直到形成行阶梯型矩阵为止。如果所有的列都是主元列,那矩阵所有列向量是线性无关的,反之,如果有至少一个非主元列,那矩阵所有列向量是线性相关的。
现在我们来做个小练习就用高斯消元法来看一下这3个向量是否是线性无关的。
$$x_{1}=\left[\begin{array}{c}<br>
1 \\\<br>
2 \\\<br>
-3 \\\<br>
4<br>
\end{array}\right], x_{2}=\left[\begin{array}{l}<br>
1 \\\<br>
1 \\\<br>
0 \\\<br>
2<br>
\end{array}\right], x_{3}=\left[\begin{array}{c}<br>
-1 \\\<br>
-2 \\\<br>
1 \\\<br>
1<br>
\end{array}\right]$$
首先,我们把它表示成一般线性方程形式,或者一个非平凡线性组合。
$$\lambda_{1} x_{1}+\lambda_{2} x_{2}+\lambda_{3} x_{3}=\lambda_{1}\left[\begin{array}{c}<br>
1 \\\<br>
2 \\\<br>
-3 \\\<br>
4<br>
\end{array}\right]+\lambda_{2}\left[\begin{array}{c}<br>
1 \\\<br>
1 \\\<br>
0 \\\<br>
2<br>
\end{array}\right]+\lambda_{3}\left[\begin{array}{c}<br>
-1 \\\<br>
-2 \\\<br>
1 \\\<br>
1<br>
\end{array}\right]=0$$
接着,把向量组合成矩阵的列,运用行运算,一直到能够识别出主元列为止。
$$\left[\begin{array}{ccc}<br>
1 &amp; 1 &amp; -1 \\\<br>
2 &amp; 1 &amp; -2 \\\<br>
-3 &amp; 0 &amp; 1 \\\<br>
4 &amp; 2 &amp; 1<br>
\end{array}\right] \cdots\left[\begin{array}{ccc}<br>
1 &amp; 1 &amp; -1 \\\<br>
0 &amp; 1 &amp; 0 \\\<br>
0 &amp; 0 &amp; 1 \\\<br>
0 &amp; 0 &amp; 0<br>
\end{array}\right]$$
这里,矩阵每一列都是主元列,所以,它没有非平凡解,只有在$λ_{1}=0$$λ_{2}=0$$λ_{3}=0$的情况下,方程才有解。因此,我们能说向量$x_{1}, x_{2}, x_{k}$ 是线性无关的。
## 更普遍和复杂的线性无关判断
理论是这样的,接下来我们再扩展一下学到的知识,把它用到更普遍和复杂的情况中,也就是有$k$个线性无关的向量$b_{1}, b_{2}, \ldots, b_{k}$,以及$m$个线性组合的情况:
$$<br>
\begin{aligned}<br>
x_{1} &amp;=\sum_{i=1}^{k} \lambda_{i 1} b_{i} \\\<br>
x_{2} &amp;=\sum_{i=1}^{k} \lambda_{i 2} b_{i} \\\<br>
\cdot &amp; \\\<br>
\cdot &amp; \\\<br>
\cdot &amp; \\\<br>
x_{m} &amp;=\sum_{i=1}^{k} \lambda_{i m} b_{i}<br>
\end{aligned}<br>
$$
如果把这$k$个线性无关的向量组合成矩阵$B$$B=\left[\begin{array}{lll}b_{1} &amp; \ldots &amp; b_{k}\end{array}\right]$ ,我们就能用更紧凑的形式来表达:
$$x_{j}=B \lambda_{i}, \lambda_{j}=\left[\begin{array}{c}<br>
\lambda_{1 j} \\\<br>
\cdot \\\<br>
\cdot \\\<br>
\cdot \\\<br>
\lambda_{kj}<br>
\end{array}\right], j=1, \ldots, m$$
这时,如何判断$x_{1}, x_{2}, \ldots, x_{m}$ 是否是线性无关的呢?首先,我们用一个非平凡线性组合来测试,就和之前的方法一样,把它表示成这样的形式:$\sum_{i=1}^{m} \varphi_{j} x_{j}=\sum_{i=1}^{m} \varphi_{j} B \lambda_{j}=B \sum_{i=1}^{m} \varphi_{j} \lambda_{j}=0$。
接着,从这样的等式可以很容易看出,只有向量$λ_{1}, λ_{2}, \ldots, λ_{m}$线性无关,$x_{1}, x_{2}, \ldots, x_{m}$ 才是线性无关的。
还是老样子,我们通过一个例子来看下。假设,有一组线性无关的向量 $b_{1}, b_{2}, b_{3}, b_{4}$和4个线性组合。
$$\left\{\begin{aligned}<br>
x_{1} &amp;=b_{1}-2 b_{2}+b_{3}-b_{4} \\\<br>
x_{2} &amp;=-4 b_{1}-2 b_{2}+4 b_{4} \\\<br>
x_{3} &amp;=2 b_{1}+3 b_{2}-b_{3}-3 b_{4} \\\<br>
x_{4} &amp;=17 b_{1}-10 b_{2}+11 b_{3}+b_{4}<br>
\end{aligned}\right.$$
接下来我们该怎么判断$x_{1}, x_{2}, x_{3}, x_{4}$是否是线性无关的呢?按刚才说的方法,我们需要首先找到$λ$向量,通过$λ$向量组合成这样的矩阵:
$$\left[\begin{array}{cccc}<br>
1 &amp; -4 &amp; 2 &amp; 17 \\\<br>
-2 &amp; -2 &amp; 3 &amp; -10 \\\<br>
1 &amp; 0 &amp; -1 &amp; 11 \\\<br>
-1 &amp; 4 &amp; -3 &amp; 1<br>
\end{array}\right]$$
接着,使用高斯消元法,一直到形成行阶梯型矩阵为止。高斯消元法的用法已经在[第四节课](https://time.geekbang.org/column/article/269448)中详细说了,如果你有些记不清,可以回去复习一下。这里我们直接得到了行阶梯型矩阵:
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 0 &amp; 0 &amp; -7 \\\<br>
0 &amp; 1 &amp; 0 &amp; -15 \\\<br>
0 &amp; 0 &amp; 1 &amp; -18 \\\<br>
0 &amp; 0 &amp; 0 &amp; 0<br>
\end{array}\right]<br>
$$
矩阵的最后一列不是主元列,而且你可以很直观地发现 $x_{4}=-7 x_{1}-15 x_{2}-18 x_{3}$,所以,我们可以判断 $x_{1}, x_{2}, x_{3}, x_{4}$是线性相关的,$x_{4}$ 能由 $x_{1}, x_{2}, x_{3}$ 的线性组合来表达。
友情提醒:已知在一个向量空间$V$中,有$k$个向量 $x_{1}, x_{2}, \ldots, x_{k}$和$m$个线性组合,如果$m&gt;k$,那么我们可以说,这$k$个向量 $x_{1}, x_{2}, \ldots, x_{k}$ 的$m$个线性组合是线性相关的。所以,在这样的情况下,就为你省去了计算的时间。
## 线性组合在机器学习中的应用
在了解了线性组合的概念,以及线性组合中的线性相关,特别是线性无关的判断后,我们来看一个机器学习中的实践例子,来了解一下线性组合是怎么体现在机器学习中的。
机器学习中,最经典,也是最简单的线性组合应用莫过于**线性回归**了。线性回归是比较常见,也是简单实用的机器学习算法,它是利用数理统计中的回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。
线性回归假设目标值与特征之间线性相关也就是说满足一个多元一次方程。它可以通过构建“损失loss”函数来求解损失函数最小时的参数$w$和$b$,也就是说,整个机器学习的过程就是通过样本数据,得到最后的参数$w$和$b$。
我们通过一个例子来看看线性回归。
<img src="https://static001.geekbang.org/resource/image/c2/00/c2a1d35f4175d0ff599eeedd5df2e200.png" alt="">
这是一个典型的一元线性回归模型。图中的空心圆点是真实数据点,而红线是一元线性回归模型,是用来做数据预测的,也就是$y=\omega^{T} x+b$。我们可以根据给定的$x$值通过方程式来计算$y$值。从分布在红色线周围的真实数据点来看,其实我们可以直观的得出结论:这个一元线性回归模型可以被用来很好的做预测。
线性回归在现实生活中的一个典型的应用场景是健身卡路里的燃烧预测,比如输入数据是年龄、性别、身高、体重、健身心跳、健身持久时间,而输出则是燃烧掉的卡路里。
怎么样?机器学习是不是很简单?
其实,机器学习的本质就是用数学来解决现实的问题。而很多看起来简单的数学公式可以解决很多问题,比如这里说的线性组合应用——线性回归。
我最近发现,有不少同学遇到问题,都想着怎么用复杂的机器学习算法去解决问题,特别是高大上的深度学习、神经网络之类的。但其实对于机器学习来说,算法不是越复杂越好,而是越适用越好。你可以先从简单的算法模型入手,先验证效果后,再做进一步的判断,是否需要用更复杂的算法模型。
## 本节小结
好了,到这里线性无关这一讲就结束了,最后我再总结一下前面讲解的内容。
向量空间是实践的基本单位,之前都是从宏观角度出发的,而今天的知识的重点在于,我从微观角度,深入讲解了线性空间中元素之间的关系,也就是线性组合,线性组合有线性相关和线性无关,而线性无关是线性代数中最重要的概念之一。所以,你一定要掌握线性组合的概念,以及它包含的线性相关,特别是线性无关的判断方式,希望你能多练习线性组合中的线性无关的判断,为实践打好坚实的基础。
## 线性代数练习场
练习时刻到了,今天的练习题简单一些,和之前举过的例子相似,假设我们有一组线性无关的向量$b_{1}, b_{2}, b_{3}, b_{4}$和4个线性组合。
$$\left\{\begin{aligned}<br>
x_{1} &amp;=b_{1}+b_{2}-2 b_{3}-b_{4} \\\<br>
x_{2} &amp;=b_{1}+5 b_{2}-3 b_{3}-2 b_{4} \\\<br>
x_{3} &amp;=3 b_{1}-b_{2}+b_{3}+4 b_{4} \\\<br>
x_{4} &amp;=-2 b_{1}+2 b_{2}+b_{3}-b_{4}<br>
\end{aligned}\right.$$
请你判断$x_{1}, x_{2}, x_{3}, x_{4}$是线性无关的吗?
>
友情提示:通过高斯消元法,我们能得到行阶梯型矩阵,通过行阶梯型矩阵,就可以判断$x_{1}, x_{2}, x_{3}, x_{4}$是否是线性无关的。
欢迎你在留言区或[部落](https://horde.geekbang.org/channel/list/39)里晒出你的运算过程和结果。如果有收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,265 @@
<audio id="audio" title="07 | 基和秩:为什么说它表达了向量空间中“有用”的向量个数?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/a0/10/a0588560b7087bf65884049ed12d9410.mp3"></audio>
你好,我是朱维刚。欢迎你继续跟我学习线性代数,今天我们要讲的内容是“基和秩”。
了解向量空间和线性组合后,我们必然会推进到**基**和**秩**的学习,为什么这么说呢?因为秩表达了向量空间中“有用”的向量个数。
这里“有用”两个字就限定了范围,也就是说,在一个向量空间$V$中,我们是只对某些特殊的向量集合$A$感兴趣的。对于$A$来说,任意属于向量空间$V$的向量,都能够被$A$中的一个向量的线性组合来表示。这里“感兴趣的向量集合”就和秩的应用场景有关了,我们来举几个秩的应用场景:
- 秩可以帮助我们研究向量组的线性相关问题,从图形图像应用角度来说,就是处理冗余数据的表达,可以被用来恢复数据,或者降噪;
- 我们可以通过秩来快速判断线性方程组解的情况,有时快速判断线性方程组有解、无解、无穷解几种情况,比“解”本身更重要,因为它能初步得出线性方程组的大致轮廓,让你不用纠结于纯粹的求解;
- 在解析几何方面,秩可以判断两条直线的位置关系,用在图形的形状和夹角判断上;
- 秩还可以把解决线性空间的维数问题,简化成分析向量个数问题,化繁为简。
## 生成集合与基
刚才简单介绍了“有用”的向量,接下来,我来详细刻画一下我们感兴趣的“特殊的向量集合”。
在重点介绍基之前,我们得先来了解“生成集合”的定义:一个向量空间$V$,和一个向量集合$A=x_{1}, x_{2}, … , x_{k}$,向量空间$V$包含$A$,如果$V$的每一个向量都可以被$x_{1}, x_{2}, … , x_{k}$的一个线性组合表示,那么$A$就是$V$的一个生成集合。$A$的向量的所有线性组合的集合就是$A$的生成空间,我们可以写成这样的形式:$V=span[A]$或者$V=span[x_{1}, x_{2}, … , x_{k}]$。
我们再进一步来看看最小生成集合。最小生成集合顾名思义就是小得不能再小的生成集合向量空间V的每个线性无关的生成集合都是最小生成集合也叫做**基basis**。基是刻画向量空间的基本工具,掌握了线性映射作用在向量空间的一组基上的效果,就等于掌握了线性映射对向量空间中任意元素的效果,所以它非常重要,我想这也是它叫“基”或“基底”的原因吧。
有了生成集合的铺垫我们就能得出这样3个结论假设$B$是$V$的一个基,那么我们就可以得到三个结论:
1. $B$是一个最小生成集合;
1. $B$是$V$中的一个最大向量线性无关集合,因为增加任何一个向量到集合中,就会导致它线性相关;
1. 任意属于向量空间$V$的向量,都能够被$B$中的一个向量的线性组合来表示,而且每一个线性组合都是唯一的。
但只了解理论是不够的,我们还需要一些练习。现在请你来思考一下,下面这些集合是不是基?
1.在实数三维向量空间中,下面这个集合是基吗?
$$A=\left\{\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
1 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
0 \\\<br>
1<br>
\end{array}\right]\right\}$$
2.在实数三维向量空间中,下面这两个集合都是基吗?
$$A_{1}=\left\{\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
1 \\\<br>
1 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
1 \\\<br>
1 \\\<br>
1<br>
\end{array}\right]\right\}$$
$$A_{2}=\left\{\left[\begin{array}{l}<br>
0.5 \\\<br>
0.8 \\\<br>
0.4<br>
\end{array}\right],\left[\begin{array}{c}<br>
1.8 \\\<br>
0.3 \\\<br>
0.3<br>
\end{array}\right],\left[\begin{array}{c}<br>
-2.2 \\\<br>
-1.3 \\\<br>
3.5<br>
\end{array}\right]\right\}$$
3.在实数四维向量空间中,下面这个集合是基吗?
$$A=\left\{\left[\begin{array}{l}<br>
1 \\\<br>
2 \\\<br>
3 \\\<br>
4<br>
\end{array}\right],\left[\begin{array}{c}<br>
2 \\\<br>
-1 \\\<br>
0 \\\<br>
2<br>
\end{array}\right],\left[\begin{array}{c}<br>
1 \\\<br>
1 \\\<br>
0 \\\<br>
-4<br>
\end{array}\right]\right\}$$
>
小提示你可以先判断它们是否线性相关。每个向量空间V都有一个基也可能有多个基。
这里你需要注意的是,一个向量空间的维度和它的基向量数是一致的,而它的维度不是一定和向量元素的数量相等的,就比如下面这个向量空间。
$$<br>
V=\operatorname{span}\left[\left[\begin{array}{l}<br>
0 \\\<br>
1<br>
\end{array}\right]\right]<br>
$$
这个向量空间是一维的,但它的基向量有两个元素。
了解了向量空间的基,那我们该如何得到向量子空间的基呢?别怕,你只要通过三步操作,就能得到向量子空间$U$的基,$U=span[x_{1}, x_{2}, … , x_{m}]$。
1. 把向量$x_{1}, x_{2}, … , x_{m}$组合成矩阵$A$的列;
1. 得到$A$的行阶梯形矩阵;
1. 和主元列相关的向量就是$U$的一个基。
现在,我通过一个例子来说明如何判断向量子空间的基。一个向量子空间$U$属于五维实数向量空间,$U$的生成集合是$x_{1}, x_{2}, x_{3}, x_{4}$。
$$<br>
x_{1}=\left[\begin{array}{c}<br>
1 \\\<br>
2 \\\<br>
-1 \\\<br>
-1 \\\<br>
-1<br>
\end{array}\right], x_{2}=\left[\begin{array}{c}<br>
2 \\\<br>
-1 \\\<br>
1 \\\<br>
2 \\\<br>
-2<br>
\end{array}\right], x_{3}=\left[\begin{array}{c}<br>
3 \\\<br>
-4 \\\<br>
3 \\\<br>
5 \\\<br>
-3<br>
\end{array}\right], x_{4}=\left[\begin{array}{c}<br>
-1 \\\<br>
8 \\\<br>
-5 \\\<br>
-6 \\\<br>
1<br>
\end{array}\right]<br>
$$
$x_{1}, x_{2}, x_{3}, x_{4}$向量中的哪些是$U$的基?要解这个问题,首先就要判断$x_{1}, x_{2}, x_{3}, x_{4}$是否是线性无关的,也就是解方程组:$\lambda_{1} x_{1}+\lambda_{2} x_{2}+\lambda_{3} x_{3}+\lambda_{4} x_{4}=0$,接下来我们就按刚才说的三步,一起来走一遍。
第一步,我们把向量$x_{1}, x_{2}, x_{3}, x_{4}$组合成矩阵的列。
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 2 &amp; 3 &amp; -1 \\\<br>
2 &amp; -1 &amp; -4 &amp; 8 \\\<br>
-1 &amp; 1 &amp; 3 &amp; -5 \\\<br>
-1 &amp; 2 &amp; 5 &amp; -6 \\\<br>
-1 &amp; -2 &amp; -3 &amp; 1<br>
\end{array}\right]<br>
$$
第二步,我们把上一步中得到的矩阵转换成行阶梯形矩阵。
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 2 &amp; 3 &amp; -1 \\\<br>
0 &amp; 1 &amp; 2 &amp; -2 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1 \\\<br>
0 &amp; 0 &amp; 0 &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 0<br>
\end{array}\right]<br>
$$
第三步,我们从主元列可以判断,$x_{1}, x_{2}, x_{4}$是线性无关的。所以,我们就得出了结论:向量集合$x_{1}, x_{2}, x_{4}$是$U$的一个基。
## 秩
聊完了生成集合和基,我们来看看线性代数中的秩。我在前面说过,线性代数中的秩的作用可大了,它可以用来求方程组的通解的个数,可以用来判断向量组中的线性无关向量的个数,可以判定非齐次方程组有无解,还可以判断矩阵的行列式的值是否为零等等。
那我们就得来看看秩的定义了:一个矩阵$A$的线性无关列数,和它的线性无关行数相等,则这个列数或行数就是矩阵的秩,表示成:$rk(A)$rk是英语rank的缩写。矩阵的秩有一些重要性质需要你熟练掌握
- 列秩等于行秩,也就是$rk(A)=rk(A^{T})$
- $m*n$矩阵$A$的列组成子空间$U \subseteq R^{m}$的生成空间,而且$U$的维度等于矩阵$A$的秩,那么,$U$的一个基可以通过$A$的高斯消元法得到的主元列来获取;
- $m*n$矩阵$A$的行组成子空间$W \subseteq R^{n}$的生成空间,而且$W$的维度等于矩阵$A$的秩,那么,$W$的一个基可以通过$A^{T}$的高斯消元法得到的主元列来获取;
- $n*n$方阵$A$只有在它的秩等于$n$时可逆;
- $m*n$矩阵$A$和实数$b$组成的线性方程:$Ax=b$,只有在$A$的秩和$A$的增广矩阵的秩相等的情况下,$Ax=b$才有解;
- $m*n$矩阵$A$,对于$Ax=0$的解的子空间的维度等于$n-rk(A)$,这个子空间叫做零空间,零空间会在下一篇线性映射中介绍;
- $m*n$矩阵$A$,如果满足$A$的秩等于$m$行数和$n$列数中的最小值,$rk(A)=min(m,n)$,则矩阵$A$就是满秩矩阵,非满秩矩阵也叫做不满秩矩阵。
说了那么多矩阵秩的性质,现在我们还是通过两个例子,来看一看如何计算矩阵的秩。
1.已知矩阵A如下
$$<br>
\left[\begin{array}{lll}<br>
1 &amp; 0 &amp; 1 \\\<br>
0 &amp; 1 &amp; 1 \\\<br>
0 &amp; 0 &amp; 0<br>
\end{array}\right]<br>
$$
因为它是行阶梯形矩阵,所以我们可以很直观地判断,它有两个线性无关的列或行,所以$A$的秩就是$2$$rk(A)=2$。
2.已知矩阵A如下
$$<br>
\left[\begin{array}{ccc}<br>
1 &amp; 2 &amp; 1 \\\<br>
-2 &amp; -3 &amp; 1 \\\<br>
3 &amp; 5 &amp; 0<br>
\end{array}\right]<br>
$$
针对这样的矩阵,我们可以先使用高斯消元法,得到它的行阶梯形矩阵。
$$<br>
\left[\begin{array}{lll}<br>
1 &amp; 2 &amp; 1 \\\<br>
0 &amp; 1 &amp; 3 \\\<br>
0 &amp; 0 &amp; 0<br>
\end{array}\right]<br>
$$
通过主元列判断后,我们发现,线性无关的列或行数是$2$,所以,$A$的秩是$2$$rk(A)=2$。
## 秩在图像恢复和降噪上的运用
在了解了基和秩的定义后,是时候来看看在应用方面的运用了。在[线性空间](https://time.geekbang.org/column/article/270329)那节课的讲解中我通过车辆的牌照识别应用场景提到了一种机器学习的降维算法主成分分析PCA。
其实,它在图像降噪的场景中也是大有用处的,特别是它和低秩矩阵结合(低秩是指矩阵的秩比较小,而矩阵的低秩性是指矩阵的秩相对矩阵的行数或列数而言很小)。我们为什么要进行图像降噪呢?那是因为,现实中的数字图像在数字化和传输过程中常受到成像设备与外部环境噪声干扰等影响,含有“杂数据”,也就是没有意义的数据。
当我们把图像转换成一个矩阵后,它的秩如果远远小于矩阵大小的话,图像就是低秩的,那就是说,低秩矩阵的每行或每列都可以用其它的行或列线性表示,这也说明了这个矩阵包含了大量的冗余信息。而这些冗余信息就是我们要处理的对象,我们可以用冗余信息来**对错误的图像进行恢复**,或者可以**去除这些冗余信息对图片进行降噪**。
现在我用一个简单的例子来说明一下图像的恢复和降噪到底是怎么做的,在现实中,一张图片很多地方其实是相似的,比如这张来自百度搜索的绿化图片。
<img src="https://static001.geekbang.org/resource/image/b3/f1/b37d5d67b2f28a4f931c986642a057f1.jpg" alt="">
这两张图片中大部分都是绿化的背景,相比较而言,左侧的图片就是低秩的,因为它包含的信息量很少。而右侧这张再加上向日葵和飞机的图片就不同了,包含的信息会多很多,那么这时,它的秩要比全是绿化的秩要高很多,也就是说向日葵和飞机会增加图像矩阵的秩。
现实中的图片往往是低秩的,因为取景的对象,不论是和外部还是其自身都有很多相似性,如果图片的秩比较高,就说明它的噪声比较严重,所以,图像处理的低秩在图片的降噪上的运用比较多。
如果你想要使用图像的低秩来恢复图片或者降噪首先要构建低秩矩阵的先验模型再求解这个模型得到低秩矩阵这种模型就是低秩矩阵恢复模型LRMR。LRMR的具体算法就用到了PCA或者增强型PCA、Robust PCA。具体RPCA的算法由于还涉及到了其他方面的知识比如迭代阈值算法、加速近端梯度算法、对偶方法以及拉格朗日乘子法感兴趣的话可以参考类似文章。
## 本节小结
好了,到这里基和秩这一讲就结束了,最后我再总结一下前面讲解的内容。
向量空间和线性组合更多的是理论导向,而基和秩就有些不同了,在前者理论的基础上,叠加的是实践,强调的是“有用”和“最小化”。**基**是刻画向量空间的基本工具,掌握了线性映射作用在向量空间的一组基上的效果,就等于掌握了线性映射对向量空间中任意元素的效果,而**秩**可以用来求方程组的通解的个数,判断向量组中的线性无关向量的个数,判定非齐次方程组有无解,判断矩阵的行列式的值是否为零等等。所以,你一定要掌握基和秩,为后面的学习打好基础。
## 线性代数练习场
好,今天练习时刻到了,我们来看一看如何计算这个矩阵的秩:
$$<br>
\left[\begin{array}{ccccc}<br>
-2 &amp; 4 &amp; -2 &amp; -1 &amp; 4 \\\<br>
4 &amp; -8 &amp; 3 &amp; -3 &amp; 1 \\\<br>
1 &amp; -2 &amp; 1 &amp; -1 &amp; 1 \\\<br>
1 &amp; -2 &amp; 0 &amp; -3 &amp; 4<br>
\end{array}\right]<br>
$$
>
提示:你可以通过高斯消元法,获取行阶梯形矩阵后,再进行判断。
欢迎在留言区或部落里晒出你的运算过程和结果。如果你有所收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,264 @@
<audio id="audio" title="08 | 线性映射:如何从坐标系角度理解两个向量空间之间的函数?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/77/bf/77f8a64dc7407c6fa93b56be5759f4bf.mp3"></audio>
你好,我是朱维刚。欢迎你继续跟我学习线性代数,今天我们要讲的内容是“线性映射”。
前面我们学的内容都是局限在一个线性空间,或者说一个向量空间中,但今天不一样哦,我们要来看看两个向量空间之间的关系,也就是线性映射。
之前我说过,向量也是对象,是能够相加,能够被标量乘的对象,而且这样计算的结果还是向量。而**加和标量乘这样的运算同样适用线性映射**。比如:两个实数向量空间$V$和$W$,有一个函数$\phi$来完成向量空间$V$到$W$的映射,如果我们想要同时保持向量空间结构不变,那么$\phi$就要满足:
$$\begin{array}{l}<br>
\phi(x+y)=\phi(x)+\phi(y)\\\<br>
\phi(\lambda x)=\lambda \phi(x)<br>
\end{array}$$
其中,所有$x$和$y$属于向量空间$V$ $λ$属于实数。于是,我们得到了线性映射的定义。
## 线性映射定义
假设有两个向量空间$V$和$W$$\phi$是一个函数它完成了向量空间V到W的线性映射那么线性映射必须满足等式
$$\phi(\lambda x+\varphi y)=\lambda \phi(x)+\varphi \phi(y)$$
其中,任意$x$和$y$都属于向量空间$V$,而任意 $λ$和$φ$都属于实数。
当然,我们能把线性映射表示成矩阵,也就是线性映射矩阵,或者叫做变换矩阵。但因为向量还能组合成矩阵的列,所以我们要特别注意区分矩阵表示的是线性映射还是向量的集合。向量的集合是静态的,而变换矩阵则是动态的哦。
接下来我们再来看看两个任意集合$V$到$W$的三类特殊映射,了解一下函数 $\phi$在不一样的情况下究竟表达了怎样的关系。
1. 函数$\phi$是单射Injective如果 $\phi(x)= \phi(y)$ ,那么$x=y$ ,其中任意$x$和$y$都属于集合$V$,从图中可以看出它表达的是一对一的关系,也就是我们可以由集合$V$的一个元素唯一确定一个集合$W$的元素。
<img src="https://static001.geekbang.org/resource/image/0c/26/0c18ea555d414b0a762b5477b4b0ca26.jpg" alt="">
1. 函数$\phi$是满射Surjective也就是满足等式 $\phi(V)= W$,从图中我们可以看出它表达的是多对一的关系,也就是多个集合$V$的元素能够确定一个集合$W$的元素。
<img src="https://static001.geekbang.org/resource/image/0b/c2/0bca9ff7784015d6506be02d490bbcc2.jpg" alt="">
1. 函数$\phi$是双射Bijective就意味着它既是单射又是满射从图中我们可以看出它表达的是所有$V$集合的元素都和$W$集合的元素一一对应,不多不少。
<img src="https://static001.geekbang.org/resource/image/2e/30/2e161117c8074163a53d5850a2315b30.jpg" alt=""><br>
通过这些定义,我们就可以引入几个线性映射的特殊概念了。
1. 同构( Isomorphism即函数 $\phi$使$V$到$W$是线性且双射的;
1. 自同态Endomorphism即函数 $\phi$使$V$到$V$是线性的;
1. 自同构Automorphism即函数$\phi$使$V$到$V$是线性且双射的;
1. 把$V$到$V$,元素$x$到$x$的映射定义为恒等映射。
那么,为什么你需要了解这几个特殊的概念呢?那是因为我们需要通过这些概念引出一个定理:有限维度的向量空间$V$和$W$,如果它们的维度相等,那么它们就是同构的。那就是说,同一维度的向量空间某种程度来说是一样的,因为它们能在没有发生损失的条件下互相转换。
比如,$\mathrm{R}^{m \times n}$矩阵向量空间,和$\mathrm{R}^{mn}$长度是$mn$的向量空间,我们可以认为它们是相同的,因为它们维度都是$mn$,而且存在一个线性映射和双射使得它们能互相转换。还记得在矩阵那节课中,我提到的矩阵转换吗?很多时候这类转换就是为了计算方便。
<img src="https://static001.geekbang.org/resource/image/a5/4a/a59fefec5c22effacb862e61e87c034a.png" alt="">
## 线性映射的矩阵表示
刚才提到了线性映射的矩阵表达,那在了解了线性映射的定义后,现在是时候来具体看一看这个更直观,且有实践意义的表达了。之所以说它有实践意义,那是因为我们赋予了它动态特性,让矩阵表示线性变换的过程。
如果存在一个$n$维向量空间$V$和它的一个有序基$B=(b_{1},\cdots,b_{n})$,那么对于任意一个属于$V$的$x$,我们能得到一个这样的线性组合:$x=\alpha_{1} b_{1}+\cdots+\alpha_{n} b_{n}$,我们可以说
$$\alpha=\left[\begin{array}{c}<br>
\alpha_{1} \\\<br>
\cdot \\\<br>
\cdot \\\<br>
\cdot \\\<br>
\alpha_{n}<br>
\end{array}\right]$$
是$x$的坐标向量或坐标表达。
我们都了解二维直角坐标系,现在我们通过一个例子,看看一个同样的向量在两个不同坐标系中的表示,加深一下你对线性映射的理解。
<img src="https://static001.geekbang.org/resource/image/78/43/7827f539b7a52eec29d3b8272da55543.jpg" alt="">
假设图中绿色是坐标系$V$,黄色是坐标系$W$。
在$V$中,$e_{1}$和$e_{2}$是$V$的标准基,向量$x$由线性组合$e_{1}$和$e_{2}$表示,$x$的坐标是(2,2),于是,$x$在$V$中可以被表示成:$x=2 e_{1}+2 e_{2}$。
在$W$中,$b_{1}$和$b_{2}$是$W$的标准基,向量$x$由线性组合$b_{1}$和$b_{2}$表示,而这里的$x$坐标就不同了,变成了(1.09,0.72),于是,$x$在$W$中可以被表示成:$x=1.09 b_{1}+0.72 b_{2}$。
说到这,你是不是对线性映射有了一个更直观的感受?现在我们就把矩阵引入到线性映射中,于是,我们就有了**变换矩阵**,也就是用矩阵表示线性变换的过程。
变换矩阵的定义是:我们有向量空间$V$和$W$,它们各自有相应的有序基 $B=(b_{1},\cdots,b_{n})$和 $C=(c_{1},\cdots,c_{m})$ ,而$\phi$就是$V$到$W$的线性映射:$\phi\left(b_{j}\right)=\alpha_{1 j} c_{1}+\cdots+\alpha_{m j} c_{m}$。
线性映射$\phi$中的$j$是从$1$到$n$,于是,我们就能得到一个$\phi$的$m \times n$的变换矩阵 $A_{\phi}$,这个变换矩阵中的元素是$A_{\phi}(i, j)=\alpha_{i j}$,也就是说,$\phi\left(b_{j}\right)$的坐标就是 $A_{\phi}$的第$j$列。
我们可以来简化一下表达,把它表示成这样: $y=A_{\phi}(x)$。其中,$x$是$V$基于$B$基的坐标向量,$y$是$W$基于$C$基的坐标向量。所以,变换矩阵可以被用来在有序基上,映射坐标。
我们来看一个变换矩阵例子:已知两个向量空间$V$和$W$,它们各自相应的有序基是 $B=(b_{1},\cdots,b_{3})$和 $C=(c_{1},\cdots,c_{4})$ ,线性映射$\phi$表示成以下形式。
$$\begin{array}{l}<br>
\phi\left(b_{1}\right)=c_{1}-c_{2}+3 c_{3}-c_{4} \\\<br>
\phi\left(b_{2}\right)=2 c_{1}+c_{2}+7 c_{3}+2 c_{4} \\\<br>
\phi\left(b_{3}\right)=3 c_{2}+c_{3}+4 c_{4}<br>
\end{array}$$
于是,我们可以通过这些条件得到变换矩阵$A_{\phi}$如下。
$$ A_{\phi}=\left[\begin{array}{ccc}<br>
1 &amp; 2 &amp; 0 \\\<br>
-1 &amp; 1 &amp; 3 \\\<br>
3 &amp; 7 &amp; 1 \\\<br>
-1 &amp; 2 &amp; 4<br>
\end{array}\right]$$
理解到这里还不算透彻,我们要更进一步,看看在现实图形图像处理中的线性变换是什么样的。接下来我们通过下面三个图形的例子来理解一下。
<img src="https://static001.geekbang.org/resource/image/02/5f/0252e3b0c13f41e0dde6fa781c3eed5f.jpg" alt="">
第一个图形是原始数据,你可以把它看成是由几百个向量的密集点组成的图。
第二个图形的效果看起来很简单是由原始数据经过45度变换后得到的它的变换矩阵是下面这样的。
$$A_{1}=\left[\begin{array}{cc}<br>
\cos \left(\frac{\pi}{4}\right) &amp; -\sin \left(\frac{\pi}{4}\right) \\\<br>
\sin \left(\frac{\pi}{4}\right) &amp; \cos \left(\frac{\pi}{4}\right)<br>
\end{array}\right]$$
第三个图形是原始数据沿平行轴拉伸两倍的效果,变换矩阵是下面这样的。
$$A_{2}=\left[\begin{array}{cc}<br>
2 &amp; 0 \\\<br>
0 &amp; 1<br>
\end{array}\right]$$
当然,这三个图形是比较简单的例子,是为了方便你理解,其实我们还能做更复杂的变换,比如:旋转、伸缩的组合等等。
## 基的改变
之前我们讨论的线性映射都是在**基**是一定的情况下,通过变换矩阵做线性映射。那如果基改变了呢?讨论基的改变在实践中也是有重要意义的。比如,为了最小化数据压缩损失,我们需要找到一个合适的被用来数据投影的基。
现在我们就来看看,如果我们改变向量空间$V$和$W$的基,线性映射$\phi$的变换矩阵会如何改变。我们给向量空间$V$和$W$各自增加两个有序基:$\widetilde{B}=\left(\tilde{b}_{1}, \ldots, \widetilde{b}_{n}\right)$和$\widetilde{C}=\left(\tilde{c}_{1}, \ldots, \widetilde{c}_{m}\right)$,而 $\tilde{A}_{\phi}$是基于新的有序基的变换矩阵。这样,$\tilde{A}_{\phi}$变换矩阵的计算公式就是:$\tilde{A}_{\phi}=T^{-1} A_{\phi} S$。
在这个新的公式中,$S$是 $\mathrm{R}^{n \times n}$向量空间$V$的恒等映射变换矩阵,向量空间$V$的恒等映射把基于$\widetilde{B}$的坐标,映射到基于$B$的坐标上。同理,$T$是$\mathrm{R}^{m \times m}$向量空间$W$的恒等映射变换矩阵,向量空间$W$的恒等映射把基于$\widetilde{C}$的坐标,映射到基于$C$的坐标上。
理论是这样的,那我们还是要通过一个例子来看一下,基改变后,新的线性映射 $\phi$的变换矩阵到底是如何获取的。我们已知,一个三维实数向量空间$\mathrm{R}^{3}$到四维实数向量空间$\mathrm{R}^{4}$的一个线性映射,它们各自有标准基$B$和$C$。
$$B=\left\{\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
1 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
0 \\\<br>
1<br>
\end{array}\right]\right\}, C=\left\{\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
0 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
1 \\\<br>
0 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
0 \\\<br>
1 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
0 \\\<br>
0 \\\<br>
1<br>
\end{array}\right]\right\}$$
基于它们各自的标准基$B$和$C$,它的变换矩阵是:
$$A_{\phi}=\left[\begin{array}{ccc}<br>
1 &amp; 2 &amp; 0 \\\<br>
-1 &amp; 1 &amp; 3 \\\<br>
3 &amp; 7 &amp; 1 \\\<br>
-1 &amp; 2 &amp; 4<br>
\end{array}\right]$$
那么现在,我们来看一下,基$B$和$C$改变为$\widetilde{B}$和$\widetilde{C}$之后,会有怎样的变化。
$$\widetilde{B}=\left\{\left[\begin{array}{l}<br>
1 \\\<br>
1 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
1 \\\<br>
1<br>
\end{array}\right],\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
1<br>
\end{array}\right]\right\}, \widetilde{C}=\left\{\left[\begin{array}{l}<br>
1 \\\<br>
1 \\\<br>
0 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
1 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
0 \\\<br>
1 \\\<br>
1 \\\<br>
0<br>
\end{array}\right],\left[\begin{array}{l}<br>
1 \\\<br>
0 \\\<br>
0 \\\<br>
1<br>
\end{array}\right]\right\}$$
对于新基$\widetilde{B}$和$\widetilde{C}$,我们得到$S$和$T$
$$S=\left[\begin{array}{lll}<br>
1 &amp; 0 &amp; 1 \\\<br>
1 &amp; 1 &amp; 0 \\\<br>
0 &amp; 1 &amp; 1<br>
\end{array}\right], T=\left[\begin{array}{llll}<br>
1 &amp; 1 &amp; 0 &amp; 1 \\\<br>
1 &amp; 0 &amp; 1 &amp; 0 \\\<br>
0 &amp; 1 &amp; 1 &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]$$
于是,我们就可以通过公式得到想要的$\tilde{A}_{\phi}$了。
$$\tilde{A}_{\phi}=T^{-1} A_{\phi} S=\left[\begin{array}{ccc}<br>
-4 &amp; -4 &amp; -2 \\\<br>
6 &amp; 0 &amp; 0 \\\<br>
4 &amp; 8 &amp; 4 \\\<br>
1 &amp; 6 &amp; 3<br>
\end{array}\right]$$
## 两个重要的子空间
最后,我再来讲两个重要的子空间——核空间和像空间,说它们重要是有原因的。核空间可以帮助我们研究线性方程组的性质,同时还可以帮助我们把复杂问题简化,也就是将复杂的大集合分解成小集合的并来研究。而像空间可以帮助我们快速得到线性方程组的秩,这样就能快速判断线性方程组解的情况。现在我们来具体了解一下。
### 核空间
核空间也叫做零空间,你还记得$Ax=b$吗?核空间关注的就是$Ax=0$,也就是向量空间$V$中所有经过$\phi$映射为零的向量集合,用符号表示就是:$\operatorname{ker}(\phi)$ 。核的维数叫做零化度nullity表示成$\operatorname{dim}(\operatorname{ker}(\phi))$。
### 像空间
向量空间$V$中所有经过$\phi$映射后的向量集合,叫做像空间,用符号表示就是:$\operatorname{im}(\phi)$,像空间维数就是秩,表示成:$\operatorname{rk}(\phi)$。
通过图形表达出来,你应该能够更好地理解。
<img src="https://static001.geekbang.org/resource/image/55/b0/55cf796942f84eced026899316427eb0.jpg" alt="">
最后我以一个定理来结束本节的内容,秩-零化度定理V的维数等于核空间维数与像空间维数之和$\operatorname{dim}(\mathrm{V})=\operatorname{dim}(\operatorname{ker}(\phi))+\operatorname{rk}(\phi)$。
## 本节小结
好了,到这里线性映射这一讲就结束了,最后我再总结一下前面讲解的内容。
线性映射赋予了线性代数灵魂,也让它在计算机科学中发挥了很大的作用。线性映射的矩阵变换是这一节的重点,你要牢固掌握,因为它在无数现实场景中都在使用,比如:三维图形图像处理中的线性变换,图形的伸缩、旋转等等。
## 线性代数练习场
好,今天练习时刻到了,刚刚我们通过图形图像处理中的线性变换的例子,讲了矩阵变换。现在我们还是以这个例子为基础,不过这一次轮到你来解答问题了。如果我们把原始数据整体沿平行轴收缩两倍,那变换矩阵会是怎样的呢?
欢迎在留言区或者部落里晒出你的变换矩阵。如果你觉得有所收获,也欢迎你把这篇文章分享给你的朋友。

View File

@@ -0,0 +1,206 @@
<audio id="audio" title="09 | 仿射空间:如何在图形的平移操作中大显身手?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/b8/48/b820fbf6549d2a6d6e9597c76513c048.mp3"></audio>
你好,我是朱维刚。欢迎你继续跟我学习线性代数,今天我们要讲的内容是“仿射空间”。
一听到仿射空间,你也许会觉得很奇怪,之前我们说过了线性空间,现在怎么又来一个空间?特别是“仿射”这个词,它有什么含义?它和线性空间的区别和联系又是什么呢?这我们就要从线性空间开始说起了。
我们知道,线性空间中有向量和标量两个对象,而仿射空间与线性空间的区别就在于它又加了一个对象,那就是“点”,而且它们的运算规则也不相同。比如,在仿射空间中,点和标量之间没有定义运算;向量和点之间有加法,运算结果是点;点和点之间有减法,运算结果是向量。
所以,仿射空间可以说是点和向量的空间,而且可以被看成是一个没有原点的线性空间。那你有没有想过,我们为什么要研究仿射空间呢?
那是因为仿射空间在计算机图形处理中有着极其重要的地位。在线性空间中,我们可以用矩阵乘向量的方法表示各种线性变换。但是,有一种常用的变换却不能用线性变换的方式表示,那就是**平移**,一个图形的平移是非线性的。为了表示平移,以及方便现实世界的描述,就需要使用仿射空间。
## 仿射子空间
和向量子空间一样,我们现在需要把注意力转移到更有实践意义的仿射子空间上。仿射子空间在计算机科学中的运用主要体现在**计算机图形处理**中,比如:图形的平移、缩放和旋转等等。
如果我们把$Ax$看成是线性,那么$Ax+b$就是仿射,其实就是多了一个平移。也就是说,我们完全可以把仿射子空间看成是线性子空间的平移。
这样理解很容易,不过,我们还是要看看数学上对仿射子空间的严格定义:$V$是一个向量空间,$U$是$V$的一个向量子空间,$x_{0}$是$V$中的元素,那仿射子空间$L$就等于:$L=x_{0}+U:=\left\{x_{0}+u: u \in U\right\}$。
这里的$U$叫做方向,$x_{0}$叫做支撑点。仿射子空间在实数三维$R^{3}$中有点、线和面,它们在坐标系中都是不过原点的。
仿射子空间也经常由参数来描述。因为,我们能通过参数,把表达式组合成方程形式,这样更有助于计算。假设,有一个$k$维的仿射子空间$L$,它可以表示成:$L=x_{0}+U$。如果$U$有一个有序基$(b_{1}, \cdots, b_{k})$,那么,每一个属于仿射子空间$L$的元素$x$,都能够表示成:$x=x_{0}+λ_{1} b_{1}+\cdots+λ_{k} b_{k}$。
在这个表达式中,$(λ_{1}, \cdots, λ_{k})$是实数参数,我们把这个表达式叫做“参数方程”,而$(b_{1}, \cdots, b_{k})$就是方向向量。
现在我们来看看,仿射子空间在不同维度中的几个例子,让你能从几何角度更了解仿射子空间。
一维仿射子空间,也叫做“线”,参数方程是:$y=x_{0}+\lambda b_{1}$。也就是说,一条线是由一个支撑点$x_{0}$和一个方向向量$b_{1}$定义的。
二维仿射子空间,也叫做“平面”,参数方程是:$y=x_{0}+\lambda_{1} b_{1}+\lambda_{2} b_{2}$。也就是说,一个平面是由一个支撑点$x_{0}$和两个线性独立的向量$b_{1}$和$b_{2}$定义的。
$n-1$维仿射子空间,也叫做“超平面”,参数方程如下。
$$y=x_{0}+\sum_{i=1}^{n-1} \lambda_{i} b_{i}$$
在这个参数方程中,$(b_{1}, \cdots, b_{n-1})$是$n-1$维子空间的一个基。也就是说,超平面是由一个支撑点$x_{0}$和$n-1$个线性独立的向量$(b_{1}, \cdots, b_{n-1})$所定义的。
## 仿射映射
空间说完,必定会来到动态部分,对应到今天的内容就是仿射映射了。仿射映射和向量空间之间的线性映射是类似的,很多线性映射的特性也能使用在仿射映射上。现在,我们试着来定义两个仿射空间之间的仿射映射。
现在我们有两个向量空间$V$和$W$,一个$V$到$W$的线性映射$\phi$,以及一个属于向量空间$W$的向量$a$。
$$<br>
\begin{aligned}<br>
\varphi: &amp; \ \rightarrow W \\\<br>
&amp; x \rightarrow a+\phi(x)<br>
\end{aligned}<br>
$$
上面这样的映射就是$V$到$W$的仿射映射,其中,你可以看到$x$元素是通过线性映射函数$\phi$和平移向量$a$进行仿射变换的。
事情就是那么简单,看上去就是一个线性映射加上一个向量,或者从几何角度说,就是做了一次线性变换后,进行了一次平移操作。而更专业一点的说法就是,每个$V$到$W$的仿射映射,都是“一个$V$到$W$的线性映射”和“一个$W$到$W$平移”的组合。
从这里你也可以判断出,仿射映射是保持了原几何结构和维度不变的。
接下来,我们再来看看三维世界中物体的仿射映射,这就包括物体的平移、缩放和旋转了。在几何空间中,物体的平移、旋转、放大缩小,这类操作如果从局部坐标系来看,就是在局部坐标系定义的点,或者向量$x$经过变换后,得到点或向量$y$。这类变换可以用公式$y=Ax+v$来表示,其中$A$就是$3×3$矩阵,$v$就是三维向量。
当然,我们还可以用矩阵来表示这类变换,也就是仿射变换矩阵和向量乘,这和公式$y=Ax+v$达到的效果是一样的。不过,由于仿射变换矩阵是在实践中经常用的方式,所以我们要来具体看看仿射变换矩阵。
## 仿射变换矩阵
在三维世界中,物体的平移、缩放和旋转,这些操作其实都可以放到一个$4×4$的矩阵中,并且统一用这个矩阵与向量的乘操作来进行物体的变换,或者说向量的空间变换。这个$4×4$仿射变换矩阵是下面这样的。
$$<br>
A^{\prime}=\left[\begin{array}{cccc}<br>
a_{11} &amp; a_{12} &amp; a_{13} &amp; a_{14} \\\<br>
a_{21} &amp; a_{22} &amp; a_{23} &amp; a_{24} \\\<br>
a_{31} &amp; a_{32} &amp; a_{33} &amp; a_{34} \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
其中,$a_{11}$到$a_{33}$的$3×3$矩阵就是变换公式$y=Ax+v$中的$A$矩阵,表示的是线性变换。而右上角的$a_{14} , a_{24}, a_{34}$表示的是平移变换,也就是变换公式中的$v$向量。右下角的数字表示的则是整体缩放,现在它是$1$,也就意味着不进行整体缩放。
在计算机图形图像处理中,仿射变换尤其重要,那是因为它能保持变换后的共线或共面性。也就是说,线段变换到线段,还是一条直线,变换前的线段中心点就是变换后的线段中心点。同样,三角形变换后,原三角形的重心还是变换后新三角形的重心。
现在,我们拿一个三角形来举例,因为三角形从计算机图形图像上来说是最基础的图形,是组合成其它多边形的基础。如果我们要变换一个三角形,只要对三个定点$a$、$b$、$c$进行仿射变换就行了,对于三角形边上的其它点,变换后还是一样会在边上,这样计算量会极大地降低,变换效率就提高了。
接下来,我们把具体的这几个仿射变换矩阵:平移、缩放和旋转,都单独拿出来,看看它们长什么样。
### 平移矩阵
我们先来看看$4×4$的平移仿射变换矩阵$A^{\prime}$,你有没有注意到矩阵中的$x$、$y$、$z$?它们就像公式里写的那样固定在矩阵的右边,定义了矩阵在三个轴方向上的平移距离。
$$<br>
A^{\prime}=\left[\begin{array}{llll}<br>
1 &amp; 0 &amp; 0 &amp; x \\\<br>
0 &amp; 1 &amp; 0 &amp; y \\\<br>
0 &amp; 0 &amp; 1 &amp; z \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
### 缩放矩阵
接下来,我们再来看看缩放仿射变换矩阵$A^{\prime}$,这里$x$、$y$、$z$的位置产生了变化,固定在了矩阵的对角线上,定义了矩阵在三个轴方向上的缩放大小。
$$<br>
A^{\prime}=\left[\begin{array}{llll}<br>
x &amp; 0 &amp; 1 &amp; 0 \\\<br>
0 &amp; y &amp; 0 &amp; 0 \\\<br>
0 &amp; 0 &amp; z &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
### 旋转矩阵
最后,我们来看看旋转仿射变换矩阵$A^{\prime}$。这里有三种情况:绕$x$轴旋转、绕$y$轴旋转、绕$z$轴旋转。
绕$x$轴旋转的矩阵:
$$<br>
A^{\prime}=\left[\begin{array}{cccc}<br>
1 &amp; 0 &amp; 0 &amp; 0 \\\<br>
0 &amp; \cos \theta &amp; -\sin \theta &amp; 0 \\\<br>
0 &amp; \sin \theta &amp; \cos \theta &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
绕$y$轴旋转的矩阵:
$$<br>
A^{\prime}=\left[\begin{array}{cccc}<br>
\cos \theta &amp; 0 &amp; \sin \theta &amp; 0 \\\<br>
0 &amp; 1 &amp; 0 &amp; 0 \\\<br>
-\sin \theta &amp; 0 &amp; \cos \theta &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
绕$z$轴旋转的矩阵:
$$<br>
A^{\prime}=\left[\begin{array}{cccc}<br>
\cos \theta &amp; -\sin \theta &amp; 0 &amp; 0 \\\<br>
\sin \theta &amp; \cos \theta &amp; 0 &amp; 0 \\\<br>
0 &amp; 0 &amp; 1 &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
在3D图形实践中一般仿射变换矩阵上的操作都是可以叠加的。也就是说我们可以通过连续的矩阵乘来完成一系列的对象变换。比如如果我们的对象要先平移再缩放最后再绕$x$轴旋转,那么我们就可以通过矩阵的三连乘来表达这个变换。
$$<br>
\left[\begin{array}{llll}<br>
1 &amp; 0 &amp; 0 &amp; x \\\<br>
0 &amp; 1 &amp; 0 &amp; y \\\<br>
0 &amp; 0 &amp; 1 &amp; z \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]\left[\begin{array}{llll}<br>
x &amp; 0 &amp; 1 &amp; 0 \\\<br>
0 &amp; y &amp; 0 &amp; 0 \\\<br>
0 &amp; 0 &amp; z &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]\left[\begin{array}{cccc}<br>
1 &amp; 0 &amp; 0 &amp; 0 \\\<br>
0 &amp; \cos \theta &amp; -\sin \theta &amp; 0 \\\<br>
0 &amp; \sin \theta &amp; \cos \theta &amp; 0 \\\<br>
0 &amp; 0 &amp; 0 &amp; 1<br>
\end{array}\right]<br>
$$
在这里我也给你推荐一个数学库作为研究使用。因为工作的缘故我们做的事情和WebGL有关所以我推荐的是一个前端TS实现的数学库TSM你可以访问[GitHub](https://github.com/matthiasferch/tsm)来了解。TSM很好地封装了仿射映射刚才的仿射变换矩阵的叠加操作也是封装好的比如平移translate(vector:vec3):mat4缩放scale(vector:vec3):mat4旋转rotate(angle:number,u:vec3):mat4
## 本节小结
这一节课的重点是仿射空间和仿射映射。有关仿射空间,你一定要掌握的是仿射子空间在不同维度中的几个例子,特别是$n-1$维仿射子空间也叫做“超平面”。因为超平面在机器学习的分类算法中很重要比如SVM支持向量机的二分类算法就会用到它。
而在仿射映射中仿射变换矩阵是重点。因为在3D计算机图形图像处理中它能够被用来进行物体的平移、缩放和旋转。而且在计算性能方面仿射变换矩阵可以极大地降低计算机的运算量提高变换效率。
## 线性代数练习场
今天的练习时刻到了不过今天的练习会有一些特别。刚刚我推荐了前端TS实现的数学库TSM这里我再推荐另一个在Python中广泛使用的库OpenCV。
我希望你能够使用它对一张JPG图片做一个简单的仿射变换平移平移$(50, 20)$。JPG素材如下图所示。
<img src="https://static001.geekbang.org/resource/image/0e/ff/0ed10eefe36ce9ec7d02e34996a8e4ff.png" alt="">
>
友情提示你可以使用CV2来读图片NumPy的shape来获取图片的行和列数据再使用NumPy的float32产生仿射变换矩阵最后使用CV2的warpAffine来完成图片的平移操作。我贴了部分代码在下面其中的仿射变换矩阵的产生和仿射变换这两行代码是需要你来完成的。
```
import cv2
import numpy as np
//读取图片
img = cv2.imread('09.jpg',0)
rows,cols = img.shape
//这里是你要完成的代码
//显示原图片和仿射变换后的图片
cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindow
```
当然你也可以用其它的库来完成比如TSM这些都没问题你可以自由发挥。
欢迎在留言区贴出你的代码和最后的输出结果,我会及时回复。同时,也欢迎你把这篇文章分享给你的朋友,一起讨论、学习。

View File

@@ -0,0 +1,267 @@
<audio id="audio" title="10 | 解析几何:为什么说它是向量从抽象到具象的表达?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/c8/7c/c8f3a5309f447a6566a3b4d85e43a37c.mp3"></audio>
你好,我是朱维刚。欢迎你继续跟我学习线性代数,今天我们要讲的内容是“解析几何”。
前面所有章节我们都是围绕向量、矩阵以及向量空间来展开的。但这一节课有点不一样我要讲的是解析几何它使得向量从抽象走向了具象让向量具有了几何的含义。比如计算向量的长度、向量之间的距离和角度这在机器学习的主成分分析PCA中是非常有用的。
## 范数
讲解析几何我们得从“范数”开始讲起。
因为很多人看到几何向量的第一反应就是,它是从原点开始的有向线段,并且向量的长度是这个有向线段的终端和起始端之间的距离。而范数,就是被用来度量某个向量空间或矩阵中的每个向量的长度或大小的。
现在,我们先来看一下范数的数学定义:一个向量空间$V$上的一个范数就是一个函数,它计算$V$中的每一个向量$x$的长度,用符号来表示的话就是:$\|x\| \in R$,它满足三种性质:
1. 正齐次性: 如果输入参数扩大正$λ$倍,其对应的函数也扩正大倍。设$λ \in R$$x \in V$$\|\lambda x\|=|\lambda|\|x\|$
1. 次可加性:类似三角不等式,两边之和大于第三边。设$x,y \in V$$\|x+y\| \leq\|x\|+\|y\|$
1. 正定性:向量$x$的长度一定大于等于零。$\|x\| \geq 0$。
看到这里,你也许会问,范数似乎和以前老师教的**向量的模**一样啊。先别急,它们还真有那么一点关系,你听我慢慢道来。由于范数是度量某个向量空间或矩阵中的每个向量的长度或大小的,所以它和向量空间维度是有关系的,于是,我们可以把范数写成这样的模式来区分不同维度的大小计算:$L_{1}, L_{2}, \ldots, L_{\infty}$。
- $L_{1}$范数:曼哈顿范数,也叫曼哈顿距离,设$x \in R^{n}$,得到下面这个表达式。
$$<br>
\|x\|_{1}=\sum_{i=1}^{n}\left|x_{i}\right|<br>
$$
- $L_{2}$范数:欧式范数,也叫欧式距离,设$x \in R^{n}$,得到下面这个表达式。
$$<br>
\|x\|_{2}=\sqrt{\sum_{i=1}^{n} x_{i}^{2}}<br>
$$
- $L_{\infty}$范数:切比雪夫范数,也叫切比雪夫距离,设$x \in R^{n}$,得到下面这个表达式。
$$<br>
\|x\|_{\infty}=\max \left(\left|x_{1}\right|,\left|x_{2}\right|, \ldots,\left|x_{n}\right|\right)<br>
$$
我们发现,向量的模和$L_{2}$范数的计算方式都是一样的,都表示的是欧氏距离,所以,我们可以简单地认为向量的模等于$L_{2}$范数。而其他的范数模式和向量的模则没有任何关系。
## 内积
学习解析几何时,我们必须掌握的第二个概念就是内积。
如果说范数是模式,是用来描述向量长度或大小的概念性表达,那么内积可以让我们很直观地了解一个向量的长度、两个向量之间的距离和角度,它的一个主要目的就是判断向量之间是否是正交的,正交这个概念我们会在后面讲解。
### 点积
我们从特殊到一般,先来看点积,它和第三篇矩阵中说的“普通矩阵乘”形式一样,点积是特殊的内积,为什么说它特殊呢?那是因为在表示两个向量之间的距离时,它就是大家熟悉的欧式距离,点积可以表示成这样的形式:
$$<br>
x^{T} y=\sum_{i=1}^{n} x_{i} y_{i}<br>
$$
### 其他内积
除了点积外,我们再来看另一个不同的内积:设内积空间$V$是$R^{2}$,定义内积$\langle x, y\rangle=x_{1} y_{1}-(x_{1} y_{2}+x_{2} y_{1})+2 x_{2} y_{2}$,一看便知这个和点积完全不同。
### 内积空间
最后,我们再来看一般内积和内积空间。因为解析几何关注的是向量的长度、两个向量之间的距离和角度,所以,我们要在原来向量空间上加一个额外的结构,这个额外结构就是内积,而加了内积的向量空间,我们就叫做内积空间。
为了表达方便,我们可以把内积写成$\langle\ ·,· \rangle$这样的形式,那么内积空间$V$可以被表示成这样:$(V,\langle\ ·,· \rangle)$。这时,如果一般内积由点积来表达,那这个向量空间就变成了更具体的欧式向量空间。
接下来看下内积空间有什么性质我们定义一个内积空间V和它的元素$x$、$y$、$z$,以及一个$c \in R$
<li>
满足对称性:$x$和$y$的内积等于$y$和$x$的内积,$\langle x, y\rangle=\langle y, x\rangle$
</li>
<li>
<p>满足线性性:$x$和$y+cz$的内积等于,$x$和$y$的内积,与$x$和$z$的内积乘以$c$后的和,<br>
$\langle x, y+c z\rangle=\langle x, y\rangle+c\langle x, z\rangle$</p>
</li>
<li>
满足正定性:$x$和$y$的内积大于等于零,$\langle x, y\rangle \geq 0$。
</li>
## 对称正定矩阵
内积还定义了一类矩阵,这类矩阵在机器学习中很重要,因为它可以被用来判定多元函数极值,而在深度学习中,它更是被用来获取最小化损失函数,我们把这类矩阵叫做对称正定矩阵。
对称正定矩阵的定义是:如果一个对称矩阵$A$属于方阵$R^{n×n}$,对任意非零向量$x$,都有$x^{T} A x&gt;0$,那么$A$就是对称正定矩阵。
我们来看两个例子,判断它们是不是对称正定矩阵。
第一个例子,请你回答下面这个矩阵是对称正定矩阵吗?
$$<br>
A=\left[\begin{array}{ll}<br>
9 &amp; 6 \\\<br>
6 &amp; 5<br>
\end{array}\right]<br>
$$
答案:是的,它是对称正定矩阵。因为$x^{T} A x&gt;0$。
$$<br>
x^{T} A x=\left[\begin{array}{ll}<br>
x_{1} &amp; x_{2}<br>
\end{array}\right]\left[\begin{array}{ll}<br>
9 &amp; 6 \\\<br>
6 &amp; 5<br>
\end{array}\right]\left[\begin{array}{l}<br>
x_{1} \\\<br>
x_{2}<br>
\end{array}\right]=(3 x_{1}+2 x_{2})^{2}+x_{2}^{2}&gt;0<br>
$$
第二个例子,请你看下面这个矩阵是对称正定矩阵吗?
$$<br>
A=\left[\begin{array}{ll}<br>
9 &amp; 6 \\\<br>
6 &amp; 3<br>
\end{array}\right]<br>
$$
答案:不是的,它只是对称矩阵。因为$x^{T} A x$可能小于0。
$$<br>
x^{T} A x=\left[\begin{array}{ll}<br>
x_{1} &amp; x_{2}<br>
\end{array}\right]\left[\begin{array}{ll}<br>
9 &amp; 6 \\\<br>
6 &amp; 3<br>
\end{array}\right]\left[\begin{array}{l}<br>
x_{1} \\\<br>
x_{2}<br>
\end{array}\right]=(3 x_{1}+2 x_{2})^{2}-x_{2}^{2}<br>
$$
## 长度、距离和角度
前面我们通过范数讲了向量的长度,但从内积的角度来看,我们发现,内积和范数之间有着千丝万缕的关系。我们来看看下面这个等式。
$$<br>
\|x\|=\sqrt{\langle x, x\rangle}<br>
$$
从这个等式我们发现,内积可以用来产生范数,确实是这样。不过,不是每一个范数都能被一个内积产生的,比如:曼哈顿范数。接下来,我们还是来关注能由内积产生的范数上,从不同的角度来看看几何上的长度、距离和角度的概念。
我们先用内积来计算一个**向量的长度**,比如:向量$x=[\begin{array}{ll}1 &amp; 1\end{array}]^{T}$,我们可以使用点积来计算,计算后得出$x$的范数是$\sqrt{2}$,具体计算过程是这样的:$\|x\|=\sqrt{x^{T} x}=\sqrt{1^{2}+1^{2}}=\sqrt{2}$。
接着,我们再来看一下**向量之间的距离**,一个内积空间$V$$(V,\langle\ ·,· \rangle)$$x$和$y$是它的两个向量,那么$x$和$y$之间的距离就可以表示成:$d(x, y)=\|x-y\|=\sqrt{\langle x-y, x-y\rangle}$。
如果用点积来计算$x$和$y$之间的距离,那这个距离就叫做欧式距离。
再接着,来看看两个**向量之间的角度**。我们使用柯西-施瓦茨不等式Cauchy-Schwarz Inequality来表示内积空间中两个向量$x$和$y$之间的角度:$a$。
$$<br>
-1 \leq \frac{\langle x, y\rangle}{\|x\|\|y\|} \leq 1<br>
$$
取值是从$-1$到$1$之间,那么角度就是从$0$到$π$之间,我们用$cos$来表示就是:
$$<br>
\cos (a)=\frac{\langle x, y\rangle}{\|x\|\|y\|}<br>
$$
其中$a$就是角度,$a$的角度取值是$0$到$π$之间。我们很容易就能发现,其实两个向量之间的角度,就是告诉了我们两个向量之间方向的相似性。例如:$x$和$y=4x$,使用点积来计算它们之间的角度是$0$,也就是说它们的方向是一样的,$y$只是对$x$扩大了$4$倍而已。
现在,我们通过一个例子,再来更清楚地看下两个向量之间角度的计算,设$x=[\begin{array}{ll}1 &amp; 1\end{array}]^{T}$$y=[\begin{array}{ll}1 &amp; 2\end{array}]^{T}$,使用点积来计算,我们得出:
$$<br>
\cos (a)=\frac{\langle x, y\rangle}{\sqrt{\langle x, x\rangle\langle y, y\rangle}}=\frac{x^{T} y}{\sqrt{x^{T} x y^{T} y}}=\frac{3}{\sqrt{10}}<br>
$$
那么,这两个向量之间的角度如下。
$$<br>
\arccos \left(\frac{3}{\sqrt{10}}\right) \approx 0.32<br>
$$
我们可以用图来更直观地表达一下。
<img src="https://static001.geekbang.org/resource/image/aa/e0/aabb363c1ae08fdcdf568555b62f87e0.png" alt="">
于是,我们最后可以引出一个概念,也就是我们在一开始提到的**正交性**。如果两个向量$x$和$y$内积等于$0$$\langle x, y\rangle=0$,那么$x$和$y$是正交的,这可以写成:$x \perp y$。再如果,$x$和$y$的范数都等于$1$$\|x\|=\|y\|=1$,也就是说,如果它们都是单位向量,那么$x$和$y$就是标准正交的。
我们用图来更直观地表达一下。
<img src="https://static001.geekbang.org/resource/image/99/10/9982b991fb207180970caf85d867a210.png" alt="">
## 正交投影
在理论讲解之后,我们要来了解一下解析几何在实践中经常运用的概念——正交投影,它是一种重要的线性变换,在图形图像、编码理论、统计和机器学习中扮演了重要角色。
在机器学习中,数据一般都是高维的。众所周知,高维数据是很难来分析和可视化的。而且,不是所有的高维数据都是有用的,可能只有一些数据包含了大部分的重要信息。
正交投影就是高维到低维的数据投影,在[第5节课线性空间](https://time.geekbang.org/column/article/270329)中我简单介绍了高维数据投影到低维后我们就能在低维空间更多地了解数据集、提炼相关模式。而在机器学习中最普遍的降维算法——PCA主成分分析就是利用了降维的观点。
接下来,我开始讲解正交投影,在给出定义之前,先从一张图来了解会更直观。
<img src="https://static001.geekbang.org/resource/image/be/68/be7421186446670dcd791a94da190468.png" alt="">
图中的蓝点是原二维数据,黄点是它们的正交投影。所以,实际降维后,在一维空间中就形成了这条黑线表示,它近似地表达了原来二维数据表示的信息。
现在我们可以来看一下投影的定义:$V$是一个向量空间,$U$是$V$的一个向量子空间,一个从$V$到$U$的线性映射$\Phi$是一个投影,如果它满足:$\Phi^{2}=\Phi \circ \Phi=\Phi$。因为线性映射能够被变换矩阵表示,所以,这个定义同样适用于一个特殊类型变换矩阵:投影矩阵$P_{\Phi}$,它也满足:$P_{\Phi}^{2}=P_{\Phi}$。
### 投影到一维子空间上(线)
接下来,我们来看看如何投影到一维子空间,也就是把内积空间的向量正交投影到子空间,这里我们使用点积作为内积。
假设有一条通过原点的线,这条线是由基向量$b$产生的一维子空间$U$,当我们把一个向量$x$投影到$U$时,需要寻找另一个最靠近$x$的向量$\Phi_{U}(x)$。还是老样子,我们通过图来看一下。
<img src="https://static001.geekbang.org/resource/image/e1/90/e1e9yy6ae45b6b36975bf20acf5c8a90.png" alt="">
首先,投影$\Phi_{U}(x)$靠近$x$,也就是要找出$x$和$\Phi_{U}(x)$之间的$\left\|x-\Phi_{U}(x)\right\|$最小距离,从几何角度来说,就是线段$\Phi_{U}(x)-x$和$b$正交,满足等式:$\left\langle\Phi_{U}(x)-x, b\right\rangle=0$。其次,投影$\Phi_{U}(x)$必须是$U$的一个元素,也就是,基向量$b$的一个乘来产生$U$$\Phi_{U}(x)=λb$。
于是,我们可以通过三个步骤来分别得到$λ$、投影$\Phi_{U}(x)$和投影矩阵$P_{\Phi}$,来把任意$x$映射到子空间$U$上。
第一步,计算$λ$,通过正交条件产生这样的等式:<br>
$\left\langle x-\Phi_{U}(x), b\right\rangle=0$。因为$\Phi_{U}(x)=λb$,所以它可以转变成:$\langle x-\lambda b, b\rangle=0$。
利用内积的双线性:$\langle x, b\rangle-\lambda\langle b, b\rangle=0$,我们得到:
$$<br>
\lambda=\frac{\langle x, b\rangle}{\langle b, b\rangle}=\frac{\langle b, x\rangle}{\|b\|^{2}}<br>
$$
然后,我们通过点积得到:
$$<br>
\lambda=\frac{b^{T} x}{\|b\|^{2}}<br>
$$
如果$\|b\|=1$,那$λ$就等于$b^{T}x$。
接着第二步,是计算投影点$\Phi_{U}(x)$。从$\Phi_{U}(x)=λb$,我们得到:
$$<br>
\Phi_{U}(x)=\lambda b=\frac{\langle x, b\rangle}{\|b\|^{2}} b=\frac{b^{T} x}{\|b\|^{2}} b<br>
$$
通过点积来计算,我们就得到了$\Phi_{U}(x)$的长度:
$$<br>
\left\|\Phi_{U}(x)\right\|=\frac{\left|b^{T} x\right|}{\|b\|^{2}}\|b\|=|\cos (a)|\|x\|\|b\| \frac{\|b\|}{\|b\|^{2}}=\mid \cos (a)\|x\|<br>
$$
这里的$a$,是$x$和$b$之间的夹角。
最后第三步,是计算投影矩阵$P_{\Phi}$,投影矩阵是一个线性映射。所以,我们可以得到:$\Phi_{U}(x)=P_{\Phi}x$,通过$\Phi_{U}(x)=λb$,我们可以得到:
$$<br>
\Phi_{U}(x)=\lambda b=b \lambda=b \frac{b^{T} x}{\|b\|^{2}}=\frac{b b^{T}}{\|b\|^{2}} x<br>
$$
这里,我们立即可以得到投影矩阵$P_{\Phi}$的计算等式:
$$<br>
P_{\Phi}=\frac{b b^{T}}{\|b\|^{2}}<br>
$$
## 本节小结
这一节课覆盖的知识点有点多,因为要把解析几何的知识点,浓缩到核心的几个点来讲解是一项艰巨的任务。不过不要怕,前面的几个知识点都是为这一节的重点“正交投影”来铺垫的。范数,被用来度量某个向量空间或矩阵中的每个向量的长度或大小,而内积让我们很直观地了解一个向量的长度、两个向量之间的距离和角度,以及判断向量之间是否是正交的。
所以希望你能掌握范数和内积的理论知识并把它和正交投影结合运用在一些实践应用场景中比如3D图形图像的坐标变换、数据压缩以及机器学习的降维。
## 线性代数练习场
请用之前学到的正交投影的投影矩阵算法,来计算一条线上的投影矩阵$P_{\Phi}$。
这条线通过原点,由基$b=\left[\begin{array}{lll}1 &amp; 2 &amp; 2\end{array}\right]^{T}$产生,$P_{\Phi}$计算后,再通过一个$x$来验证一下它是否在$b$产生的子空间中,我们取$x=\left[\begin{array}{lll}1 &amp; 1 &amp; 1\end{array}\right]^{T}$。
欢迎在留言区晒出你的运算结果,我会及时回复。同时,也欢迎你把这篇文章分享给你的朋友,一起讨论、学习。

View File

@@ -0,0 +1,222 @@
<audio id="audio" title="基础通关 | 线性代数5道典型例题及解析" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/15/3d/1571aefebc1158aa4b39450b15a86d3d.mp3"></audio>
你好,我是朱维刚。欢迎你继续跟我学习线性代数。
今天这一节课的内容是基础通关。这里会用5道典型例题让你巩固一下线性代数的基础知识这也是进入应用篇学习之前的一次动手机会。从课程上线到现在快有一个月了这期间我收到了不少同学的提问和建议有些问题也是我没有想到的非常有深度说实话这让我感觉挺意外的希望你再接再厉。
现在你可以看一下基础通关的5道例题了题目和解析都放在了正文中你可以自己试着做一下。基础通关后我们应用篇再见。
## 例题一
找到线性方程组$Ax=b$的所有解,其中:
$$<br>
A=\left[\begin{array}{cc}<br>
1 &amp; 2 \\\<br>
3 &amp; 0 \\\<br>
-1 &amp; 2<br>
\end{array}\right], b=\left[\begin{array}{c}<br>
1 \\\<br>
0 \\\<br>
1<br>
\end{array}\right]<br>
$$
### 解析:
这里考察了解线性方程组的方法特别是高斯消元法你可以参考第4节的内容。
首先,形成增广矩阵:
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 2 &amp; 1 \\\<br>
3 &amp; 0 &amp; 0 \\\<br>
-1 &amp; 2 &amp; 1<br>
\end{array}\right]<br>
$$
接着,分步计算增广矩阵的行阶梯形矩阵:
1. 第一行乘-3和第二行相加。
1. 第一行和第三行相加。
$$<br>
\left[\begin{array}{cccc}<br>
1 &amp; 2 &amp; 1 \\\<br>
0 &amp; -6 &amp; -3 \\\<br>
0 &amp; 4 &amp; 2<br>
\end{array}\right]<br>
$$
1. 第二行乘$\frac{1}{3}$和第一行相加。
1. 第二行乘$\frac{2}{3}$和第三行相加。
1. 第三行乘$-\frac{1}{6}$。
$$<br>
\left[\begin{array}{llll}<br>
1 &amp; 0 &amp; 0 \\\<br>
0 &amp; 1 &amp; \frac{1}{2} \\\<br>
0 &amp; 0 &amp; 0<br>
\end{array}\right]<br>
$$
最后得出该线性方程组的唯一解:
$$<br>
x=\left[\begin{array}{l}<br>
0 \\\<br>
\frac{1}{2}<br>
\end{array}\right]<br>
$$
## 例题二
找到线性方程组$Ax=b$的所有解,其中:
$$<br>
A=\left[\begin{array}{lll}<br>
1 &amp; 2 &amp; 3 \\\<br>
0 &amp; 2 &amp; 2<br>
\end{array}\right], b=\left[\begin{array}{l}<br>
1 \\\<br>
1<br>
\end{array}\right]<br>
$$
### 解析:
这里考察了解线性方程组的方法特别是高斯消元法。你可以参考第4节的内容和例题一不同的是例题二这里得到的会是无穷解。所以这一题里找特殊解和通用解的方法是关键。
首先,形成增广矩阵:
$$<br>
\left[\begin{array}{lllll}<br>
1 &amp; 2 &amp; 3 &amp; 1 &amp; 1 \\\<br>
0 &amp; 2 &amp; 2 &amp; 1 &amp; 1<br>
\end{array}\right]<br>
$$
接着,形成增广矩阵:分步计算增广矩阵的行阶梯形矩阵:
1. 第一行乘-1和第二行相加
1. 第二行乘1/2。
$$<br>
\left[\begin{array}{lllll}<br>
1 &amp; 0 &amp; 1 &amp; 1 &amp; 0 \\\<br>
0 &amp; 1 &amp; 1 &amp; 1 &amp; \frac{1}{2}<br>
\end{array}\right]<br>
$$
使用主元列,得到特殊解:
$$<br>
x=\left[\begin{array}{l}<br>
0 \\\<br>
\frac{1}{2} \\\<br>
0<br>
\end{array}\right]<br>
$$
下一步,获取线性方程组$Ax=0$的通用解,从增广矩阵的左边,能够立即得出:
$$<br>
\lambda\left[\begin{array}{c}<br>
1 \\\<br>
1 \\\<br>
-1<br>
\end{array}\right]<br>
$$
最后,把特殊解和通用解组合起来就是:
$$<br>
x=\left[\begin{array}{l}<br>
0 \\\<br>
\frac{1}{2} \\\<br>
0<br>
\end{array}\right]+\lambda\left[\begin{array}{c}<br>
1 \\\<br>
1 \\\<br>
-1<br>
\end{array}\right]<br>
$$
## 例题三
计算矩阵乘$AB$。
$$<br>
A=\left[\begin{array}{ccc}<br>
1 &amp; 2 &amp; 3 \\\<br>
0 &amp; -1 &amp; 2<br>
\end{array}\right], B=\left[\begin{array}{ccc}<br>
4 &amp; -1 &amp; 2 \\\<br>
0 &amp; 2 &amp; 1<br>
\end{array}\right]<br>
$$
### 解析:
这里考察了基本的矩阵乘运算特别是普通矩阵乘只有相邻阶数匹配的矩阵才能相乘你可以参考第3节的内容。
矩阵乘无法完成,因为$A$是2行3列矩阵$B$也是2行3列矩阵$A$和邻居维度不同。
## 例题四
计算矩阵乘$AB$。
$$<br>
A=\left[\begin{array}{ccc}<br>
1 &amp; 2 &amp; 3 \\\<br>
0 &amp; -1 &amp; 2<br>
\end{array}\right], B=\left[\begin{array}{cc}<br>
4 &amp; -1 \\\<br>
2 &amp; 0 \\\<br>
2 &amp; 1<br>
\end{array}\right]<br>
$$
### 解析:
这里考察了基本的矩阵乘运算特别是普通矩阵乘你可以参考第3节的内容。
矩阵乘可以完成,因为两个矩阵的邻居维度相同,拿$a_{11}$举例:$a_{11}=1 \times 4+2 \times 2+3 \times 2=14$,结果:
$$<br>
A B=\left[\begin{array}{cc}<br>
14 &amp; 2 \\\<br>
2 &amp; 2<br>
\end{array}\right]<br>
$$
## 例题五
假设$R^{3}$和它的运算$\langle\ ·,· \rangle$$x, y \in R^{3}$,我们有:
$$<br>
\langle x, y\rangle=x^{T} A y, A=\left[\begin{array}{ccc}<br>
4 &amp; 2 &amp; 1 \\\<br>
0 &amp; 4 &amp; -1 \\\<br>
1 &amp; -1 &amp; 5<br>
\end{array}\right]<br>
$$
那么,$\langle\ ·,· \rangle$是内积吗?
### 解析:
这里考察了内积以及内积的性质之一对称性你可以参考第10节的内容。
选择$x=\left[\begin{array}{lll}1 &amp; 1 &amp; 0\end{array}\right]^{T}$$y=\left[\begin{array}{lll}1 &amp; 2 &amp; 0\end{array}\right]^{T}$,通过计算,能够得到:
$$<br>
\begin{array}{l}<br>
\langle x, y\rangle=16 \\\<br>
\langle y, x\rangle=14 \\\<br>
\langle x, y\rangle \neq\langle y, x\rangle<br>
\end{array}<br>
$$
于是,$\langle\ ·,· \rangle$是不对称的。