5.3 计算数据
参考视频: 5 - 3 - Computing on Data (13 min).mkv
现在,你已经学会了在 Octave 中如何加载或存储数据,如何把数据存入矩阵等等。在这段视频中,我将介绍如何对数据进行运算,稍后我们将使用这些运算操作来实现我们的学习算法。
这是我的 Octave 窗口,我现在快速地初始化一些变量。比如设置 A 为一个 3×2 的矩阵,设置 B 为一个 3 × 2 矩阵,设置 C 为 2 × 2 矩阵。
我想算两个矩阵的乘积,比如说 A × C,我只需键入 A×C,这是一个 3×2 矩阵乘以2×2 矩阵,得到这样一个 3×2 矩阵。
![3f62e3fbf9a65cb013ec2386dd8a2ee6.png](https://i-blog.csdnimg.cn/blog_migrate/42d4f782f9d7c977c5a5603fed4540f2.jpeg)
![0191924bda2f42062926e345f9392600.png](https://i-blog.csdnimg.cn/blog_migrate/56924ba46aaa5011ce47100986612108.jpeg)
你也可以对每一个元素,做运算 方法是做点乘运算 A .*B,这么做 Octave 将矩阵 A 中的每一个元素与矩阵 B 中的对应元素相乘A .* B
这里第一个元素 1 乘以 11 得到 11,第二个元素 2 乘以 12 得到 24,这就是两个矩阵的元素位运算。通常来说,在 Octave 中点号一般用来表示元素位运算。
![afc64fee77219520867a3db07c27a777.png](https://i-blog.csdnimg.cn/blog_migrate/93101e89a5bbb5da93e69bd45de8be15.jpeg)
这里是一个矩阵 A,这里我输入 A .^ 2,这将对矩阵 A 中每一个元素平方。
![517229db473b2e23efdba8723d64a2d3.png](https://i-blog.csdnimg.cn/blog_migrate/1564b364cdaef08bca488b9e5f56bff3.jpeg)
我们设 V 是一个向量,设V 为 [1; 2; 3] 是列向量,你也可以输入 1 ./ V,得到每一个元素的倒数,所以这样一来,就会分别算出 1/11/21/3。
矩阵也可以这样操作,1 ./ A 得到 A 中每一个元素的倒数。同样地,这里的点号还是表示对每一个元素进行操作。
我们还可以进行求对数运算,也就是对每个元素进行求对数运算。
![14aa7e57701b67c6bce7085621bea761.png](https://i-blog.csdnimg.cn/blog_migrate/048b4c787816076c66a6a7dc07d95d67.jpeg)
还有自然数 e 的幂次运算,就是以e 为底,以这些元素为幂的运算。
![2d49c3f51fe053799ccfde1415e7b35a.png](https://i-blog.csdnimg.cn/blog_migrate/6dd817e4cfcf36540cb7a0caf00d9a72.jpeg)
我还可以用 abs 来对 v 的每一个元素求绝对值,当然这里 v 都是正数。我们换成另一个这样对每个元素求绝对值,得到的结果就是这些非负的元素。还有 –v,给出 V 中每个元素的相反数,这等价于 -1 乘以 v,一般就直接用 -v 就好了,其实就等于 -1*v。
还有一个技巧,比如说 我们想对 v 中的每个元素都加 1,那么我们可以这么做,首先构造一个 3 行 1 列的 1 向量,然后把这个 1 向量跟原来的向量相加,因此 v 向量从[1 2 3]
增至 [2 3 4]。我用了一个,length(v) 命令,因此这样一来,ones(length(v) ,1) 就相当于ones(3,1),然后我做的是 v + ones(3,1),也就是将 v 的各元素都加上这些 1,这样就将 v 的每个元素增加了 1。
![7152f7f0b46e3208043624de1f098a05.png](https://i-blog.csdnimg.cn/blog_migrate/b70db68a364c79160303eec361fa4f56.jpeg)
另一种更简单的方法是直接用 v+1,v + 1 也就等于把 v 中的每一个元素都加上 1。
![0899e95a63449aecb4e81cb9eec91fad.png](https://i-blog.csdnimg.cn/blog_migrate/1d0203b6447703d03afd98b1fffdbaad.jpeg)
现在,让我们来谈谈更多的操作。
矩阵 A 如果你想要求它的转置,那么方法是用 A’,将得出 A 的转置矩阵。当然,如果我写 (A’)’,也就是 A 转置两次,那么我又重新得到矩阵 A。
还有一些有用的函数,比如: a=[1 15 2 0.5],这是一个 1 行 4 列矩阵, val=max(a),这将返回 A 矩阵中的最大值 15。
我还可以写 [val, ind] = max(a),这将返回 a 矩阵中的最大值存入 val,以及该值对应的索引,元素 15 对应的索引值为 2 存入 ind,所以 ind 等于 2
特别注意一下,如果你用命令 max(A), A 是一个矩阵的话,这样做就是对每一列求最大值。
我们还是用这个例子,这个 a 矩阵 a=[1 15 2 0.5],如果输入 a<3,这将进行逐元素的运算,所以元素小于 3 的返回 1,否则返回 0。
![e93a567d1d061c7d2623ea5f2d1a5506.png](https://i-blog.csdnimg.cn/blog_migrate/dd936feb85e7a7aae9541778e335dd19.jpeg)
因此,返回[1 1 0 1]。也就是说,对 a 矩阵的每一个元素与 3 进行比较,然后根据每一
个元素与 3 的大小关系,返回 1 和 0 表示真与假。
如果我写 find(a<3),这将告诉我 a 中的哪些元素是小于 3 的。
![25c406e5a314981b1e413dcdd0afbef2.png](https://i-blog.csdnimg.cn/blog_migrate/5a28ac787ff00ade29a0b5a222fad9f7.jpeg)
设 A = magic(3),magic 函数将返回一个矩阵,称为魔方阵或幻方 (magic squares),它们具有以下这样的数学性质:它们所有的行和列和对角线加起来都等于相同的值。
当然据我所知,这在机器学习里基本用不上,但我可以用这个方法很方便地生成一个
3 行 3 列的矩阵,而这个魔方矩阵这神奇的方形屏幕。每一行、每一列、每一个对角线三个数字加起来都是等于同一个数。
![f75c0d24b1dac1a11db5b388a79cf2f7.png](https://i-blog.csdnimg.cn/blog_migrate/5bf443ec1eff0e33139514770a489c29.jpeg)
在其他有用的机器学习应用中,这个矩阵其实没多大作用。
如果我输入 [r,c] = find( A>=7 ),这将找出所有A 矩阵中大于等于 7 的元素,因此,r 和c 分别表示行和列,这就表示,第一行第一列的元素大于等于 7,第三行第二列的元素大于等于 7,第二行第三列的元素大于等于 7。
![3dffbe82d06379f03eb2cbaaedd916da.png](https://i-blog.csdnimg.cn/blog_migrate/8a30e7919f4e56e1190c7c459459d593.jpeg)
顺便说一句,其实我从来都不去刻意记住这个 find 函数,到底是怎么用的,我只需要会用 help 函数就可以了,每当我在使用这个函数,忘记怎么用的时候,我就可以用 help 函数,键入 help find 来找到帮助文档。
最后再讲两个内容,一个是求和函数,这是 a 矩阵:
![73a3500d827e90c9d4d42e95fc593877.png](https://i-blog.csdnimg.cn/blog_migrate/e7ef569bb6f033e825c3be7086b1e0ee.jpeg)
键入 sum(a),就把 a 中所有元素加起来了。
如果我想把它们都乘起来,键入 prod(a),prod 意思是 product(乘积),它将返回这四个
元素的乘积。
floor(a) 是向下四舍五入,因此对于 a 中的元素 0.5 将被下舍入变成 0。
还有 ceil(a),表示向上四舍五入,所以 0.5 将上舍入变为最接近的整数,也就是 1。 键入 type(3),这通常得到一个 3×3 的矩阵,如果键入 max(rand(3), rand(3)),这样做的
结果是返回两个 3×3 的随机矩阵,并且逐元素比较取最大值。假如我输入 max(A,[],1),这样做会得到每一列的最大值。
所以第一列的最大值就是 8,第二列是 9,第三列的最大值是 7,这里的 1 表示取 A 矩阵第一个维度的最大值。
相对地,如果我键入 max(A,[],2),这将得到每一行的最大值,所以,第一行的最大值是等于 8,第二行最大值是 7,第三行是 9。
![230cff05d92fd33fa0fd96ffd0d2957d.png](https://i-blog.csdnimg.cn/blog_migrate/3995aa43f24dc23293ec2fe229e89298.jpeg)
所以你可以用这个方法来求得每一行或每一列的最值,另外,你要知道,默认情况下max(A)返回的是每一列的最大值,如果你想要找出整个矩阵 A 的最大值,你可以输入max(max(A)),或者你可以将 A 矩阵转成一个向量,然后键入 max(A(:)),这样做就是把 A 当做一个向量,并返回 A 向量中的最大值。
最后,让我们把 A 设为一个 9 行 9 列的魔方阵,魔方阵具有的特性是每行每列和对角线的求和都是相等的。
这是一个 9×9 的魔方阵,我们来求一个 sum(A,1),这样就得到每一列的总和, 这也验证了一个 9×9 的魔方阵确实每一列加起来都相等,都为 369。
![7b397ed6321672d6a58a1094bf37adfe.png](https://i-blog.csdnimg.cn/blog_migrate/d6581371e64f6ce3f0671a4e5a90398b.jpeg)
现在我们来求每一行的和,键入 sum(A,2),这样就得到了 A 中每一行的和加起来还是
369。
现在我们来算 A 的对角线元素的和。我们现在构造一个 9×9 的单位矩阵, 键入 eye(9)
设为 I9
然后我们要用 A 逐点乘以这个单位矩阵,除了对角线元素外,其他元素都会得到 0。键入 sum(sum(A.*eye(9))
这实际上是求得了,这个矩阵对角线元素的和确实是 369。你也可以求另一条对角线的和也是是 369。
flipup/flipud 表示向上/向下翻转。
同样地,如果你想求这个矩阵的逆矩阵,键入 pinv(A),通常称为伪逆矩阵,你就把它看成是矩阵 A 求逆,因此这就是 A 矩阵的逆矩阵。
设 temp = pinv(A),然后再用 temp 乘以 A,这实际上得到的就是单位矩阵,对角线为
1 其他元素为 0。
如何对矩阵中的数字进行各种操作,在运行完某个学习算法之后,通常一件最有用的事情是看看你的结果,或者说让你的结果可视化,在接下来的视频中,我会非常迅速地告诉你, 如何很快地画图,如何只用一两行代码,你就可以快速地可视化你的数据,这样你就能更好地理解你使用的学习算法。