Loading

吴恩达机器学习笔记-6(Octave)

Octave

Octave能够更好地实现并快速地掌握机器学习算法。之后再用Java、C++或Python之类的语言去重新实现,会节约很多时间。Octave和MATLAB几乎完全相同,因为Octave开源且免费,安装使用起来比MATLAB更方便,所以我在这里选择使用Octave作为我机器学习入门的语言。

基本操作

image
四则运算是基本功能,也可以进行高次运算。最上面一行是一个有趣的命令PS1('>>')这个命令可以更改等待命令的样式,使界面看起来更简洁。

image
逻辑运算在此处会如其他编程语言一样,返回一个布尔值,1表示True0表示False,要注意的是,octave里的不等于,应该写成~=,而不是其他编程语言中的!=

image
异或运算

image
Octave中用%来进行注释,%后面的代码不会执行。

变量

image
可以使用 a = 3 给变量 a 赋值 3 ,该句命令会一并打印结果

image
如果在a = 3后面加上一个分号,则不会打印结果,但是仍然会将3赋值给变量a
在 Octave 中 " ; " 不会将语句的执行结果输出。
如果想打印变量 a 的值,只需输入变量名,或者使用命令disp(a)。

image
除了可以将数值赋值给变量,也可以将字符串或者布尔值赋值给变量

image
format long 命令输出字符串默认的位数。
format short 命令输出少量小数点后位数。
也可以使用类似C语言风格的格式化字符串来控制打印结果, "%0.2f" 表示 代替d放在这里 并显示d值的小数点后两位数字 。(注: pi 为圆周率 π 。)

向量和矩阵

image
分号表示在矩阵内换到下一行。
空格分隔同一行不同列的元素。

image
运用前面讲过的分号的特性来建立矩阵也是可行的。

image
那么容易知道建立向量的方法

image
V=1:0.1:2表示从1开始以0.1为步长递增到2,建立一个向量,容易想到,这是一个11列的行向量。默认以1为步长。

image
ones(2,3)表示生成一个元素全为1的2*3的矩阵。
zeros则表示生成元素全为0的矩阵
rand表示生成元素全为随机值的矩阵
randn表示生成的元素符合高斯分布的矩阵

image
容易想到,可以运用矩阵的运算来生成不同的矩阵

image
hist命令用于打印直方图

image
eye命令用于生成单位阵

image
类似python,help命令可以查询内置函数的作用。
quit或者exit可以退出octave。

移动矩阵中的数据

image
size可以读取矩阵的尺寸,该方法返回的也是一个矩阵。

image
可以分别返回矩阵A的行数和列数

image
length会返回矩阵最大的维度

image
pwd命令会显示octave当前所处的路径

image
ls命令会列出当前所处目录下的所有文件,类似于unix/linux系统命令

image
who命令可以显示出当前工作空间中存在的变量

load xxxx.dat命令可以将外部数据导入到工作空间中

image
whos命令可以更详细地显示出变量的信息

image
将priceY的前10个元素赋给变量v

image
save命令会将变量v以二进制的形式存储到当前工作空间(即前面pwd命令显示的那个地址)中的指定文件里

image
clear命令会清除掉当前工作空间的所有变量

image
这个命令会将变量v,或者说将变量v的ASCII值存为文本文档

image
Ocatve中同样可以通过索引来读取单个元素的值

image
“:”表示某行/列的每一个元素

image
表示第1行和第3行的每一个元素

image
image
也可以通过索引来更新

image
这样可以在原矩阵右边连接一个新矩阵,左边同理。(逗号可加可不加)

image
这样可以将A中所有元素放进一个向量中

image
分号表示添加在下面,因为分号的含义是下一行,所以会换行连接矩阵

矩阵运算

image
image
四则运算是可行的。

image
image
在octave中,“.”表示对元素位进行运算,这行代码表示将A中每个元素与B中每个元素相乘

image
单引号表示转置

image
max函数会返回最大值和最大值所在的索引

image
如果对象是一个矩阵,则会查找每列的最大值

image
每个元素返回一个布尔值

image
返回结果为真的索引

image
image
sum函数返回所有元素之和
prod函数返回所有元素之积
floor函数对所有元素进行向下四舍五入
ceil函数对所有元素进行向上四舍五入

image
magic函数可以生成一个指定阶数的幻方
此处的sum函数中,1和2分别表示矩阵A的第1个维度和第2个维度

数据可视化

octave可以方便地对数据进行可视化操作

image
其中t=[0:0.01:0.98]
plot函数可以返回一个二维函数图像

image
hold on命令可以将另一个函数图像与之前的置于统一坐标系中

image
xlabel、ylabel、legend、title命令分别可以对函数图像的信息进行编辑

print -dpng 'myplot.png'命令可以将图像保存到当前工作空间

image
figure(2):plot(t,y2)命令可以打开新窗口并绘制函数图像

image
subplot命令可以将一个图像窗口分隔为多块显示,如图中的subplot(1,3,1)命令,指的是将窗口分隔为1*3的格子来分别绘制不同的函数图像,最后一个1指的是第1个格子

image
axis命令可以更改坐标轴的显示范围,如axis([0.5 1 -1 1])中,前两个数字表示X轴,后两个数字表示Y轴,Octave会自动地将坐标轴调整为相同的比例
clf可以清空一个图像窗口

image
imagesc函数可以返回一个彩色格子图,不同颜色对应于矩阵A中不同的值

image
imagesc(A),colorbar,colormap gray可以生成一个灰度分布图colorbar可以生成一个色度条表示不同颜色对应的不同值

控制语句

for循环

image
也可以构建一个索引,将索引的值赋给i,达到指定循环条件的效果
image

while循环

image

if-elseif选择

image

嵌套

image
控制语句嵌套,注意end;作为哪个控制体的结尾

函数定义与使用

Octave中,想要使用自定义的函数,首先需要创建一个以.m为后缀的文件
image

image
该函数只有两行代码。
第一行告诉Octave我需要squareThisNumber函数返回一个值,并将这个值赋给变量y,同时squareThisNumber函数有一个形参x。
第二行代码是函数体,里面是该函数具体的执行方法。

image
调用函数要保证,定义的函数文件与当前Octave所处工作空间在同一路径下,使用pwd命令来确定当前工作空间,或者用cd命令来改变当前工作空间。

image
要注意Octave是通过文件名来调用函数的,我在此处犯了一个错误,我误将函数名写成了小写,而文件名是大写,但是编译同样通过,甚至输出了正确的答案,因此在以后的编程中,应当注意,保证文件名与函数名匹配。

image
此处还有一个地方需要注意,函数中定义了将值赋给变量y,但是实际上工作空间中是不存在变量y的。和其他语言也是类似的,函数中的局部变量只在函数中起作用。因此应当注意区别变量名,避免混淆。

image
Octave提供了添加搜索路径的功能,可以添加欲搜索的路径,这样即使函数文件不在当前工作空间中,编译器也知道去哪里搜索这个函数。

多返回值函数

image
image
因为返回的多个值,是以列表的形式存储的,所以必须要在控制台以列表的形式接收,才能全部打印出来,否则

代价函数实践

有这样一个数据集\([x,y]=[1,1;2,2;3,3]\)
image
|---|---|---|
|\(x^0\)|\(x^1\)|\(y\)|
|1|1|1|
|1|2|2|
|1|3|3|
容易得到假设函数\(h(x)=\theta_0+\theta_1{\times}x\)我们需要利用octave来计算代价函数,求出一个\(\theta\)值使得代价函数值最小

首先构建一个设计矩阵(design matrix)
image
第一列是为了便于计算约定的\(x^{(0)}=1\),第二列即是三个样本各自的特征值。

然后构建一个结果y的矩阵
image

因为只有一个特征值,所以容易得到假设函数\(h_{\theta}(x)=\theta_0+\theta_1{\times}x\)
回顾之前所学,容易得到代价函数\(J(θ_0,θ_1)=\frac{1}{2m} \sum^{m}_{i=1}{(h_θ(x_i)-y_i)^2}\)
根据算法要求编写自定义的函数costFunctionJ
image

image
此处定义的变量theta表示假设函数中的\(\theta_0,\theta_1\)的值。
那么经过计算,容易得出当\(\theta_0=0,\theta_1=1\)时,代价函数的值最小。
octave\matlab的优势在于有许多内置的数学相关的库,进行数学运算时会比其他语言快得多得多。

向量化

很多时候我们可以将复杂的方程或者函数表示为向量或者矩阵运算的结果。
前面的多元线性回归章节中有提到过关于假设函数\(h_θ(x)=θ_0+θ_1x_1+θ_2x_2+θ_3x_3+θ_4x_4+……+θ_nx_n\)的向量化例子
\(x=\begin{bmatrix} x_0\\\\ x_1\\\\ x_2\\\\…\\\\x_n \end{bmatrix}\) \(θ=\begin{bmatrix} θ_0\\\\ θ_1\\\\ θ_2\\\\…\\\\θ_n \end{bmatrix}\)

\[h_θ(x)=θ_0+θ_1x_1+θ_2x_2+θ_3x_3+θ_4x_4+……+θ_nx_n=θ^Tx \]

对于这个假设函数,如果要用普通的for循环来实现的话,应该如下
image
这里需要注意的是,数学上\(\theta\)的下标是从0开始的,但是在octave\matlab中,下标是从1开始的,所以需要建立从1到n+1的索引才能正确对应

如果使用向量化呢?
image
一行代码即可,所利用的就是matlab\octave高度优化的数值线性代数(数值线性代数:研究在计算机上进行线性代数计算的学科)算法来计算,不仅实现起来简单,运行起来也更加高效。

梯度下降实例

在多元线性回归模型中,梯度下降法中对参数\(\theta\)进行每次迭代时,式子如下:
\(θ_0:=θ_0- α\frac{1}{m} \sum^{m}_{i=1}{(h_θ(x^i)-y^i)x_0^i}\)
\(θ_1:=θ_1- α\frac{1}{m} \sum^{m}_{i=1}{(h_θ(x^i)-y^i)x_1^i}\)
\(θ_2:=θ_2- α\frac{1}{m} \sum^{m}_{i=1}{(h_θ(x^i)-y^i)x_2^i}\)
\((n=2)\)
我们将其向量化为:
\(\theta:=\theta-\alpha\delta\),其中\(\theta\alpha\delta都是n+1维向量\)
下面详细分析一下为何\(\delta\)是一个n+1维的向量
且其中\(\delta=α\frac{1}{m} \sum^{m}_{i=1}{(h_θ(x^i)-y^i)x^i}\)
那么有\(\delta_0=α\frac{1}{m} \sum^{m}_{i=1}{(h_θ(x^i)-y^i)x_0^i}\)
根据假设函数的定义,以及y的定义,我们容易知道\(h_θ(x^i)-y^i\)
是一个实数,而\(x^i\)是一个向量
\(x^i=\begin{bmatrix} x_0^i\\\\ x_1^i\\\\ x_2^i \end{bmatrix}\)

再看下面这个式子
\(n=2\)的情况下,\(\sum^m_{i=1}(h_θ(x^i)-y^i)\times{x^i}=(h_θ(x^0)-y^0)\times{x^0}+(h_θ(x^1)-y^1)\times{x^1}+(h_θ(x^2)-y^2)\times{x^2}\)
前面提到过\((h_θ(x^i)-y^i)\)是一个实数,而\(x^i\)是一个向量,根据矩阵\向量运算法则,实数乘一个矩阵\向量其结果仍然是一个矩阵\向量,而多个矩阵\向量相加,其结果依然为矩阵\向量,故而\(\delta\)是一个n+1维的向量
comment:可以表示为:
comment:\(\sum={\begin{bmatrix} (h_θ(x^0)-y^0)&(h_θ(x^1)-y^1)&(h_θ(x^2)-y^2) \end{bmatrix}}\times{\begin{bmatrix} x_0^i\\\\ x_1^i\\\\ x_2^i \end{bmatrix}}\)

posted @ 2021-06-09 10:41  mmmhongyu  阅读(753)  评论(0)    收藏  举报