ML学习(四)———Matlab基础

1.基本操作

  • 计算数值
>> 5 + 6
ans = 11
>> 3 * 4
ans = 12
>> 1/3
ans = 0.3333
>> 2^6
ans = 64
  • 计算逻辑值
>> 1 == 2
ans = 0
>> 1 ~= 2 
ans = 1
>> 1 && 0
ans = 0
>> 1 || 0
ans = 1
  • 变量
>> a = 6
a = 6
>> a = 6;  %加上分号可以使变量不打印输出
>>
  • 打印变量
>> a = pi;
>> a       
a = 3.1416
>> disp(a)       %仅输出a的值
    3.1416
>> disp(sprintf("2 decimals : %0.2f",a))  %打印字符串(用c语言的格式)
2 decimals : 3.14
>> 
  • 建立矩阵和向量
>> A = [1 2;3 4;5 6]  %分号代表矩阵的换行
A =
     1     2
     3     4
     5     6
>> v = [1 2 3]     %表示行向量(1*3的矩阵)
v =
     1     2     3
>> v = [1;2;3]     %表示列向量(3*1的矩阵)
v =
     1
     2
     3
>> v = 1:0.1:2   %表示从1~2每隔0.1取数,得到的是一个行向量
v =
  181.0000    1.1000    1.2000    1.3000    1.4000    1.5000    1.6000    1.7000
  9111.8000    1.9000    2.0000
>> v = 1:6       %当然也可以不取间隔
v =
     1     2     3     4     5     6
  • 用特殊方法建立矩阵
>> ones(2,3)   %建立2*3的矩阵,元素全部为1
ans =
     1     1     1
     1     1     1
>> 2*ones(2,3)    %2*矩阵,元素全部为2
ans =
     2     2     2
     2     2     2
>> zeros(2,2)    %生成零矩阵
ans =
     0     0
     0     0
>> rand(1,3)    %生成0~1的随机矩阵
ans =
    0.8147    0.9058    0.1270
>> randn(1,3)   %生成高斯分布矩阵(正态分布)均值为0,标准差为1
ans =
    0.8622    0.3188   -1.3077
>> >> w = -6 + sqrt(10)*(randn(1,10000)); % 生成均值为-6,方差为1010000个数据的矩阵
>> hist(w)     %将这个矩阵用直方图的形式画出来
>> hist(w,50)  %50个竖条的直方图显示

在这里插入图片描述
在这里插入图片描述

>> eye(4)   %生成单位矩阵
ans =
     1     0     0     0
     0     1     0     0
     0     0     1     0
     0     0     0     1
>> eye(3)
ans =
     1     0     0
     0     1     0
     0     0     1

2.移动数据

  • 矩阵的大小
>> A = [1 2;3 4;5 6]
A =
     1     2
     3     4
     5     6
>> size(A)      %size()可以查看矩阵的大小
ans =
     3     2
>> s = size(A)   
s =
     3     2
>> size(s)        %size()本身返回的就是一个矩阵
ans =
     1     2
>> size(A,1)     %将返回A矩阵第一维度的大小(行数)
ans =
     3
>> size(A,2)     %将返回A矩阵第二维度的大小(列数)
ans =
     2
>> v = [1 2 3 4]
v =
     1     2     3     4
>> length(v)      %返回行向量的长度
ans =
     4
>> length(A)   %返回较大的维度长度3
ans =
     3
  • 加载文件中的数据
>> load('ex1data1.txt')   %使用load直接可以将文件中的数据读出来
>> who           %显示当前工作区的变量

您的变量为:

A         ans       ex1data1  s         v         

>> size(ex1data1)       %刚刚读的矩阵,查看长度
ans =
    97     2
>> whos   %查看当前工作区变量的详细信息
  Name           Size            Bytes  Class     Attributes

  A              3x2                48  double              
  ans            1x1                 8  double              
  ex1data1      97x2              1552  double              
  s              1x2                16  double              
  v              1x4                32  double              
>> clear(v)   %删除变量,不加指定则删除全部变量
>> v = ex1data1(1:10)  %取前10个元素
v =
  186.1101    5.5277    8.5186    7.0032    5.8598    8.3829    7.4764    8.5781
  9106.4862    5.0546
>> save v.mat v    %将v矩阵中的数据存到文件v.mat中去
  • 这里存储文件时是以二进制格式存储的,因为数据量可能比较大,所以进行了压缩,如果想让人看懂存储的内容可使用下面的方法
>> save v.txt v -ascii
  • 操作矩阵中的数据
>> A
A =
     1     2
     3     4
     5     6
>> A(3,2)  %取A矩阵中第三行第二列的元素
ans =
     6
>> A(2,:)   %取A矩阵中第二行的所有元素
ans =
     3     4
>> A(:,2)   %取第二列的所有元素
ans =
     2
     4
     6
>> A([1 3],:)    %取A矩阵第一行和第三行的所有元素
ans =
     1     2
     5     6
>> A(:,2) = [10 15 20]  %取出元素之后其实可以对其进行赋值
A =
     1    10
     3    15
     5    20
>> A = [A,[100;150;200]] %在A矩阵后面追加一列
A =
     1    10   100
     3    15   150
     5    20   200
>> A(:)    %把A矩阵的所有元素放到一个列向量中
ans =
     1
     3
     5
    10
    15
    20
   100
   150
   200
>> A = [1 2;3 4;5 6];
>> B = [11 12;13 14;15 16];
>> C = [A,B]     %将两个矩阵拼接到一起
C =
     1     2    11    12
     3     4    13    14
     5     6    15    16
>> C = [A;B]      %分号表示换行,B矩阵放在A矩阵的下面
C =
     1     2
     3     4
     5     6
    11    12
    13    14
    15    16

3.计算数据

  • 矩阵之间的运算
>> A = [1 2;3 4;5 6];
>> B = [11 12;13 14;15 16];
>> C = [1 1;2 2]
C =
     1     1
     2     2
>> A * C     %A与C进行矩阵相乘
ans =
     5     5
    11    11
    17    17 
>> A .* B      %'.*'代表矩阵中对应元素相乘
ans =
    11    24
    39    56
    75    96
>> A .^ 2     %'.'代表对矩阵中的所有元素,乘方
ans =
     1     4
     9    16
    25    36
>> v = [1 2 3] 
>> v = 1 ./ v    %取v矩阵的倒数
v =
    1.0000    0.5000    0.3333
>> log(v)     %对v取log运算
ans =
         0   -0.6931   -1.0986
>> exp(v)      %对v取e^v次方运算
ans =
    2.7183    1.6487    1.3956
>> abs([-1;-2;3])  %对矩阵取绝对值运算
ans =
     1
     2
     3
>> -v          %对矩阵取相反数
ans =
   -1.0000   -0.5000   -0.3333
>> v = [1;2;3];
>> v = v + ones(length(v),1) %将v中所有元素+1,先构造一个和v维度相同的矩阵(元素全为1),再把他们相加
v =
     2
     3
     4
>> v = v +1     %实际上用+号就可以实现
v =
     3
     4
     5
>> A'      %一个撇号是求矩阵的转置
ans =
     1     3     5
     2     4     6
  • 对矩阵的函数操作
>> a = [-0.2 9.8 4.5 8 2.0]
a =
   -0.2000    9.8000    4.5000    8.0000    2.0000
>> val = max(a)   %求矩阵的最大值
val =
    9.8000 
>> [val index] = max(a)    %求矩阵的最大值并返回他的下标索引
val =
    9.8000
index =
     2
>> a < 3     %拿a中的所有元素和3比较返回结果
ans =
  1×5 logical 数组
   1   0   0   0   1
>> find(a<3)   %返回满足条件的元素在a中的索引
ans =
     1     5
>>A = magic(3)  %幻方矩阵,每一行每一列包括对角线元素之和相等
 A =
     8     1     6
     3     5     7
     4     9     2
>> [r,c] = find(A>=7)  %寻找A中大于等于7的元素索引,行和列
r =
     1
     3
     2
c =
     1
     2
     3
>> sum(a)    %对矩阵中的元素求和
ans =
   24.1000
>> prod(a)    %对矩阵中的元素相乘
ans =
 -141.1200
>> floor(a)    %向下取整
ans =
    -1     9     4     8     2
>> ceil(a)      %向上取整
ans =
     0    10     5     8     2
>> A
A =
     8     1     6
     3     5     7
     4     9     2
>> max(A,[],1)   %取每一列的最大值,1代表是第一维度
ans =
     8     9     7
>> max(A,[],2)   %取每一行的最大值
ans =
     8
     7
     9
>> max(max(A))  %取A矩阵所有元素的最大值
ans =
     9
>> max(A(:))  %或者先将矩阵A转化为列向量,在取最大值
ans =
     9
>> sum(A,1)  %求A每一列的和
ans =
    15    15    15
>> sum(A,2) %求A每一行的和
ans =
    15
    15
    15
>> A .* eye(3)   %将单位矩阵与A中的元素相乘得到对角线的元素
ans =
     8     0     0
     0     5     0
     0     0     2
>> sum(sum(A .* eye(3)))  %求对角线元素的和
ans =
    15
>> pinv(A)    %求逆矩阵
ans =
    0.1472   -0.1444    0.0639
   -0.0611    0.0222    0.1056
   -0.0194    0.1889   -0.1028
>> temp = pinv(A);
>> A*temp     %发现这就是单位矩阵
ans =
    1.0000   -0.0000    0.0000
    0.0000    1.0000   -0.0000
   -0.0000    0.0000    1.0000

4.数据绘制

  • 有时需要绘制数据的图像以便更好地观察我们的算法是否出现错误,或者更好的检验我们的想法的正确性,我们需要将数据可视化,这点很重要。
>> t = [0:0.01:0.98]; 
>> y1 = sin(2*pi*4*t);
>> plot(t,y1);   %用plot就可以画出对应的sin函数图像
>> y2 = cos(2*pi*4*t);
>> hold on;     %在同一界面上画图像
>> plot(t,y2,'r');   %画出cos的函数图像,用red
>> xlabel('time');    %设置x轴坐标
>> ylabel('value');   %设置y轴坐标
>> legend('sin','cos');  %设置标识
>> title('my plot');   %设置标题
>> print -dpng 'myplot.PNG';  %将图像保存为PNG格式

在这里插入图片描述

>> figure(1); plot(t,y1);  %对图像进行标号这样每个图象一个界面
>> figure(2); plot(t,y2);
>> subplot(1,2,1);    %将界面分为1*2的区域,用第一块区域
>> plot(t,y1);     %第一块区域画y1的图像
>> subplot(1,2,2);    %用第二块区域
>> plot(t,y2);      %第二块区域画y2的图像
>> axis([0.5 1 -1 1]);   %设置图像的横纵坐标范围

在这里插入图片描述

>> A = magic(5)  %5*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; %执行了三个命令,用有灰度的图像来画矩阵,并显示灰度表

在这里插入图片描述

>> imagesc(magic(15)),colorbar,colormap gray;%打印15*15的幻方矩阵

在这里插入图片描述

5.控制语句:if,for,while语句

>> v = zeros(10,1)
>> for i = 1:10,  %i = 1:10,之后把v(i)的值变为2的i次方
     v(i) = 2^i;
   end            %注意结束的时候加上end
>> v
v =
           2
           4
           8
          16
          32
          64
         128
         256
         512
        1024
>> i = 1;
>> while true,    %while循环
     v(i) = 999;  %设置v(i)的值为999
     i = i + 1;
     if i == 6,  %当i=6时跳出循环
        break;
     end
  end
>> v
v =
         999
         999
         999
         999
         999
          64
         128
         256
         512
        1024
  • 定义函数
    创建一个sqrt_test.m文件,在里面输入以下内容:
function y = sqrt_test(x) %y是返回值,x为传入的参数
    y = x^2
end

之后在控制台中cd 到文件所处目录,调这个函数执行命令

>> sqrt_test(5);
y =
    25

matlab的函数还可以有多个返回值,比如将上面的函数改一下:

function [a,b] = sqrt_test(x)
    a = x^2
    b = x^3
end
>> [a,b] = sqrt_test(5);
a =
    25
b =
   125

下面用matlab实现代价函数的定义,并且用简单的数据集检验是否正确,数据集如下:
在这里插入图片描述
我们定义的代价函数如下:

function J = costFunctionJ(X,y,theta)
    m = size(X,1);       %数据集的个数
    predictions = X*theta;    %假设函数预测的结果矩阵
    sqrErrors = (predictions - y) .^ 2;   %与实际值得误差
    J = 1/(2*m) * sum(sqrErrors);     %计算代价函数
end

下面我们在终端中调用这个函数:

>> X = [1 1;1 2;1 3];
>> Y = [1;2;3];
>> X
X =
     1     1
     1     2
     1     3
>> Y
Y =
     1
     2
     3
>> theta = [0;1]
theta =
     0
     1
>> costFunctionJ(X,Y,theta)  %theta0=0,theta0=1刚好拟合,故代价函数为0
ans =
     0
>> theta = [0;0]
theta =
     0
     0
>> costFunctionJ(X,Y,theta)
ans =
    2.3333

6.向量化

  • 下面通过几个例子来说明向量化的代码会更加简单明了。

  • 首先我们先写一个计算假设函数的function,前面我们已经知道假设函数的公式如下:
    h ( x ) = ∑ j = 1 n θ j x j h(x) = \sum_{j=1}^n\theta_jx_j h(x)=j=1nθjxj
    那么正常来写求假设函数的matlab代码就是:

function pre = prediction(X,theta)
    pre = 0.0;
    n = size(X,1);
    for j = 1:n,
        pre = pre + theta(j) * X(j)
    end;
end

而我么前面也推到过,假设函数还可以写成向量的形式:

h ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + . . . + θ n x n = [ θ 0 , θ 1 . . . θ n ] ∗ [ x 0 x 1 x 2 . . . x n ] h(x)=\theta_0+\theta_1x_1+\theta_2x_2+...+\theta_nx_n=[\theta_0,\theta_1...\theta_n]*\begin{bmatrix}x_0\\x_1\\x_2\\...\\x_n\end{bmatrix} h(x)=θ0+θ1x1+θ2x2+...+θnxn=[θ0,θ1...θn]x0x1x2...xn
= θ T X =\theta^TX =θTX
这样我们的函数就可以使用matlab提供的线性代数库来求解了,可以大大减少代码量:

function pre = prediction(X,theta)
   pre = theta' * X;  % ' 代表矩阵的转置
end
  • 再比如说我们前面所讨论的的梯度下降的更新公式:
    θ n = θ n − α 1 m ∑ i = 1 m ( h θ ( x i ) − y i ) x n ( i ) \theta_n=\theta_n-\alpha\frac1m\sum_{i=1}^m(h_\theta(x_i)-y_i)x_n^{(i)} θn=θnαm1i=1m(hθ(xi)yi)xn(i)
    这里我们也是假设θ为一个列向量,那么更新之后的θ就等于原来的列向量θ 减去 a/m(实数)* ((h(x)(假设函数列向量) - y(数据集y列向量))*X(特征值矩阵))
    下面是更新theta值的matlab代码:
function Theta = UpdateTheta(X,Y,theta,alpha)
    m = size(X,1);
    Error = X * theta - Y;
    deta = alpha/m * (X' * Error);
    Theta = theta - deta;
end

由此可见,使用向量化可以使代码大大减小,相对于之前写的python实现更加简单,并且对于特征值较多的也可以避免使用for循环,使用矩阵运算还可以提高运算速度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值