数学运算
加: 5+6
减: 3-2
乘: 5*8
除:1/2
指数:2^6
逻辑运算
相等: ==
不相等 ~=
与: &&
或: ||
异或: xor( , )
注释:%
赋值运算
>> a = 3
在结尾加; 即可抑制打印输出:
>> a = 3;
对于一些复杂的输出,可以使用disp命令:
>> disp(sprintf('2 decimals: %0.2f', a))
2 decimals: 3.14
矩阵的表示
表示一个三行两列的矩阵:
>> A = [1 2; 3 4; 5 6]
A =
1 2
3 4
5 6
分配一个一行三列的行向量:
>> v = [1 2 3]
v =
1 2 3
分配一个三行一列的列向量:
>> v = [1; 2; 3]
v =
1
2
3
表示一个行向量,其中第一个值是起始值,中间的值是步长,最后一个值是终止值:
>> v = 1:0.2:2
v =
1.0000 1.2000 1.4000 1.6000 1.8000 2.000
生成一个2行3列,所有元素都为1的矩阵:
>> ones(2,3)
ans =
1 1 1
1 1 1
生成一个2行3列,所有元素都为2的矩阵:
>> 2*ones(2,3)
ans =
2 2 2
2 2 2
生成一个1行3列的0矩阵:
>> w = zeros(1,3)
w =
0 0 0
生成单位矩阵
>> A = eye(5)
A =
Diagonal Matrix
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
生成一个元素为介于0到1之间随机数的1行3列的矩阵:
>> w = rand(1,3)
w =
0.65555 0.77468 0.85729
均值为0的高斯分布:
>> w = randn(1,3)
w =
0.61607 0.53219 1.48783
-6加上根号10乘以一个一行10000列的正太分布的随机向量。
>> w = -6 + sqrt(10)*(randn(1,10000));
绘制直方图
>> hist(w)
绘制有50条的直方图:
>> hist(w,50)
help命令,后面跟任何其他指令,都可以查看该指令的说明文档,包括help自身:
>> help eye
获取矩阵的尺寸
首先,创建一个3行2列的矩阵A:
>> A = [1 2; 3 4; 5 6]
A =
1 2
3 4
5 6
通过size命令,我们能看到这个矩阵的尺寸:
>> size(A)
ans =
3 2
实际上size的这个输出结果自身也是一个矩阵:
>> sz = size(A)
sz =
3 2
>> size(sz)
ans =
1 2
分别查看A向量的size的输出结果中的两个值:
>> size(A,1)
ans = 3
>> size(A,2)
ans = 2
length指令,来获取矩阵的最大维度,这个命令其实通常只对向量使用:
>> v = [1 2 3 4]
v =
1 2 3 4
>> length(v)
ans = 4
加载文件
通过load命令,加载外部文件:
>> load featuresX.dat
>> load priceY.dat
你也可以使用load()的方式来加载,效果相同:
>> load('featuresX.dat')
>> load('priceY.dat')
我们可以使用who命令来查看当前Octave中存储的变量:
>> who
Variables in the current scope:
A ans c priceY v
a b featuresX sz w
whos命令可以查看更详细的信息,包括尺寸,内存占用,以及类型:
>> whos
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
A x2 48 double
a x1 8 double
ans x2 16 double
b x2 2 char
c x1 1 logical
featuresX 7x2 752 double
priceY 7x1 376 double
sz x2 16 double
v x4 32 double
w x10000 80000 double
Total is 10159 elements using 81251 bytes
可以看到featuresX和priceY已经被成功的被作为一个变量加载进来了,我们可以直接输入featuresX来查看这个变量的内容。
清空变量
可以使用clear命令来删除某个变量,直接输入clear命令,会清空所有的变量。
截取矩阵部分元素
将priceY的前10个元素存入变量V:
>> V = priceY(1:10)
V =
3999
3299
3690
2320
5399
2999
3149
1989
2120
2425
变量的存储
将变量V存入hello.mat文件中:
>> save hello.mat V
>> ls
FeaturesX.dat PriceY.dat hello.mat
这里其实是把V按照压缩的二进制的形式进行存储,如果说V的数据很大,那么压缩的幅度也很大。
如果想按照一个我们可以看得懂的格式进行存储的话,可以这样输入:save hello.txt V -ascii
用索引来操作矩阵
首先创建矩阵A:
>> A = [1 2; 3 4; 5 6]
A =
1 2
3 4
5 6
你可以通过A(3,2)来访问矩阵的第三行第二列的元素:
>> A(3,2)
ans = 6
你也可以通过A(2,:)来访问第二行的所有元素,其中:代表该行/列的所有元素:
>> A(2,:)
ans =
3 4
你可以通过A([1 3], :)来取矩阵第1行以及第3行的所有元素:
>> A([1 3], :)
ans =
1 2
5 6
通过A(:)来将所有的元素以一个列向量的形式展示:
>> A(:)
ans =
1
3
5
2
4
6
你也可以通过索引来进行复制操作:
>> A
A =
1 2
3 4
5 6
>> A(:,2) = [10; 11; 12]
A =
1 10
3 11
5 12
在矩阵的右侧新增一列:
>> A = [A,[100; 101; 102]]
A =
1 10 100
3 11 101
5 12 102
将两个行相等的向量按照从左到右的顺序连在一起:
>> A = [1 2;3 4;5 6]
A =
1 2
3 4
5 6
>> B = [11 12;13 14;15 16]
B =
11 12
13 14
15 16
>> C = [A B]
C =
1 2 11 12
3 4 13 14
5 6 15 16
将两个列数相等的向量按照从上到下的顺序连在一起:
>> A
A =
1 2
3 4
5 6
>> B
B =
11 12
13 14
15 16
>> C = [A;B]
C =
1 2
3 4
5 6
11 12
13 14
15 16
矩阵的乘法
>> A = [1 2; 3 4; 5 6]
A =
1 2
3 4
5 6
>> C = [1 1; 2 2]
C =
1 1
2 2
>> A*C
ans =
5 5
11 11
17 17
点乘操作
让两个矩阵中的每个对应位置的元素相乘(点乘操作):
>> A = [1 2; 3 4; 5 6]
A =
1 2
3 4
5 6
>> B = [11 12; 13 14; 15 16]
B =
11 12
13 14
15 16
>> A.*B
ans =
11 24
39 56
75 96
对每个元素求平方
对矩阵A中的每个元素求平方:
>> A .^ 2
ans =
1 4
9 16
25 36
对每个元素求倒数
>> v = [1; 2; 3]
v =
1
2
3
>> 1 ./ v
ans =
1.00000
0.50000
0.33333
对矩阵的每个元素进行的计算
对每个元素求对数: log(v)
以e为低,以每个元素为幂的运算: exp(v)
对所有元素求绝对值: abs(v)
求相反数运算: -v
对向量每个元素自增1:v + 1
矩阵的转置
>> A
A =
1 2
3 4
5 6
>> A'
ans =
1 3 5
2 4 6
获取向量中最大的元素
>> a = [1 15 2 0.5]
a =
1.00000 15.00000 2.00000 0.50000
>> val = max(a)
val = 15
也可以获取最大元素的索引:
>> [val, ind] = max(a)
val = 15
ind = 2
值得注意的是,如果这里不是向量,而是矩阵,那么将得到每一列的最大值
>> D = [1 5;2 4; 3 3]
D =
1 5
2 4
3 3
>> max(D)
ans =
3 5
判断矩阵中每个元素是否满足某条件
>> a
a =
1.00000 15.00000 2.00000 0.50000
>> a < 3
ans =
1 0 1 1
这里1代表真,0代表假
找出矩阵中满足某条件元素的索引
>> A
A =
8 1 6
3 5 7
4 9 2
>> [r,c] = find(A >= 7)
r =
1
3
2
c =
1
2
3
其中r是所在行的索引,c是所在列的索引。
比如:元素(1,1),(3,2),(2,3)。
求和函数
将矩阵中所有元素求和:
>> a
a =
1.00000 15.00000 2.00000 0.50000
>> sum(a)
ans = 18.500
对矩阵的每一行(列)求和
>> A = magic(9)
A =
47 58 69 80 1 12 23 34 45
57 68 79 9 11 22 33 44 46
67 78 8 10 21 32 43 54 56
77 7 18 20 31 42 53 55 66
6 17 19 30 41 52 63 65 76
16 27 29 40 51 62 64 75 5
26 28 39 50 61 72 74 4 15
36 38 49 60 71 73 3 14 25
37 48 59 70 81 2 13 24 35
>> sum(A,1)
ans =
369 369 369 369 369 369 369 369 369
>> sum(A,2)
ans =
369
369
369
369
369
369
369
369
369
求A的对角线元素的和:
>> A.*eye(9)
ans =
47 0 0 0 0 0 0 0 0
0 68 0 0 0 0 0 0 0
0 0 8 0 0 0 0 0 0
0 0 0 20 0 0 0 0 0
0 0 0 0 41 0 0 0 0
0 0 0 0 0 62 0 0 0
0 0 0 0 0 0 74 0 0
0 0 0 0 0 0 0 14 0
0 0 0 0 0 0 0 0 35
>> sum(sum(A.*eye(9)))
ans = 369
求积函数
将矩阵中所有元素求积:
>> a
a =
1.00000 15.00000 2.00000 0.50000
>> prod(a)
ans = 15
四舍五入
向下四舍五入: floor(a)
向上四舍五入: ceil(a)
max函数
获取一个矩阵中每一列最大的元素组成的向量:
>> A
A =
8 1 6
3 5 7
4 9 2
>> max(A,[],1)
ans =
8 9 7
获取矩阵每一行的最大值:
>> max(A,[],2)
ans =
8
7
9
找出矩阵A中最大元素的两种方法:
>> max(max(A))
ans = 9
>> max(A(:))
ans = 9
将矩阵上下翻转
>> magic(3)
ans =
8 1 6
3 5 7
4 9 2
>> flipud(magic(3))
ans =
4 9 2
3 5 7
8 1 6
求逆矩阵
>> A = magic(3)
A =
8 1 6
3 5 7
4 9 2
>> temp = pinv(A)
temp =
0.147222 -0.144444 0.063889
-0.061111 0.022222 0.105556
-0.019444 0.188889 -0.102778
>> temp * A
ans =
1.00000 0.00000 -0.00000
-0.00000 1.00000 0.00000
0.00000 0.00000 1.00000
实际上,这里的pinv()函数求得的是伪逆矩阵。
绘制正弦余弦函数
绘制一个正弦函数:
>> t=[0:0.01:0.98]; % 生成一个0到0.98的等差数列,差值为0.01
>> y1 = sin(8*pi*t)
>> plot(t,y1);
同理,可以绘制余弦图:
>> y2 = cos(8*pi*t);
>> plot(t,y2)
这样会覆盖掉之前的图,得到新的图。
如果我们想将两个图重叠在一起绘制,可以使用hold on命令:
>> plot(t,y1);
>> hold on
>> plot(t,y2,'r'); % 这里第三个参数'r'代表颜色为红色
图的标记
可以用以下命令来对图进行标记:
>> xlabel('time') % 标记x坐标
>> ylabel('value') % 标记y坐标
>> legend('sin','cos') % 标记图例
>> title('my plot') % 标记标题
图片的保存与删除
将图片保存在Octave所在目录。可能会花费一些时间
>> print -dpng 'myPlot.png'
warning: print.m: fig2dev binary is not available.
Some output formats are not available.
这里其实可以保存多种格式,可以查看help来了解。
如果想删除这个文件,直接输入close即可。
>> close
这样就会关闭视图窗口,并且删除刚才生成的文件。
使用subplot将图像分割显示
subplot函数接受三个参数,前两个参数代表获取一个a × b格子,第三个参数代表当前使用的格子的索引。
>> subplot(1,2,1); % 将图像划分成1×2的格子,并且使用第一个格子
如果这个时候输入:
>> plot(t,y1);
那么将会绘制在第一个格子里。
同理,我们可以通过以下命令,将y2绘制在第二个格子里:
>> subplot(1,2,2);
>> plot(t,y2);
另外,你可以使用axis函数,来改变当前图像的刻度:
>> axis([0.5 1 -1 1]) % 将x轴的范围调整到0.5到1之间,y轴的范围调整到-1到1之间
矩阵的可视化
通过imagesc函数,将矩阵绘制出来,其中一种颜色代表一种数值。
>> A = magic(5)
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> imagesc(A)
设置用来显示的颜色:
>> imagesc(A), colorbar, colormap gray;
这里其实相当于连续输入了三条命令,将颜色变为了灰色,并且颜色对应的数值范围也在右侧列出。
控制语句:for, while, if符号的使用
>> v = zeros(10,1);
>> for i=1:10,
> v(i) = 2^i;
> end;
>> v
v =
2
4
8
16
32
64
128
256
512
1024
也可以通过for来访问一个索引序列:
>> indices=1:10;
>> indices
indices =
1 2 3 4 5 6 7 8 9 10
>> for i=indices,
> disp(i);
> end;
1
2
3
4
5
6
7
8
9
10
while的使用:
>> v
v =
100
100
100
100
100
64
128
256
512
1024
>> i=1;
>> while true,
> v(i) = 999;
> i = i+1;
> if i == 6,
> break;
> end;
> end;
>> v
v =
999
999
999
999
999
64
128
256
512
1024
else 的使用
>> v(1)
ans = 2
>> v(1)=2;
>> if v(1)==1,
> disp('The value is one');
> elseif v(1) == 2,
> disp('The value is two');
> else
> disp('The value is not one or two.');
> end;
The value is two
函数的定义以及调用
在当前Octave的目录下创建一个文件squareThisNumber.m
内容如下:
function y = squareThisNumber(x)
y = x^2;
在当前目录下就可以直接使用这个函数了:
>> squareThisNumber(5)
ans = 25
这里y是函数squareThisNumber的返回值,函数体是y = x^2;,参数是x。
如果想要正常使用这个函数,必须把这个函数所在的文件放到当前目录下。
多个返回值
Octave的函数有一个其他大多数语言不具备的一个特性,就是允许返回多个参数。
例如:
function [y1,y2] = squareAndCubeThisNumber(x)
y1 = x^2;
y2 = x^3;
可以看到函数squareAndCubeThisNumber返回两个值,分别为y1和y2。
使用这个函数:
>> [a,b] = squareAndCubeThisNumber(5);
>> a
a = 25
>> b
b = 125
使用函数求解代价函数值
定义函数costFunctionJ.m,入参分别为X,y以及θ:
function J = costFunctionJ(X, y, theta)
% X is the "design matrix" containing our training examples.
% y is the class labels
m = size(X,1); % number of training examples
predictions = X*theta; % predictions of hypothesis on all m examples
sqrErrors = (predictions-y).^2; % squaed errors
J = 1/(2*m) * sum(sqrErrors);
使用这个方法求解代价函数J(θ)值:
>> X = [1 1; 1 2; 1 3]
X =
1 1
1 2
1 3
>> y = [1; 2; 3]
y =
1
2
3
>> theta = [0; 1];
>> j = costFunctionJ(X,y,theta)
j = 0
其中X矩阵第一列代表x0项,第二列代表x1项。
y矩阵代表y的值。theta的两个值分别代表θ0和θ1。
可以看到X和y对应的值能够被所给的θ值完全拟合,所以得到J(θ)=0
向量化
无论你使用Octave还是别的语言,比如matlab或者你正在使用python Numpy或者Java、C 、C++所有这些语言都具有线性代数的库。这些库已经经过高度优化,通常是数值计算方面的博士或者专业人士开发的,而当你实现机器学习算法时,如果你能好好利用这些线性代数库,并联合调用它们,而不是自己去实现这些库可以实现的功能,那么通常情况下,运行速度会更快一些。出错的概率也更小一些。
为了能使用库函数提供的矩阵乘法之类的API,我们通常情况下解决问题的思路应该是向着把参数向量化的方向努力。这样你就会有一个简单得多,也有效得多的代码。
例如:
这个式子如果我们自己来计算,可能会从0到n去遍历
的和。但如果向量化处理之后,我们可以得到
的另外一种表示方式:
非向量化实现:
向量化实现: