机器学习学习笔记week2

4 多变量线性回归

4.1 多维特征

目前为止,我们探讨了单变量/特征的回归模型,现在我们对房价模型增加更多的特征,例如房间数楼层等,构成一个含有多个变量的模型,模型中的特征为 ( x 1 , x 2 , … , x n ) (x_1,x_2,\ldots,x_n) (x1,x2,,xn)
在这里插入图片描述
增添更多特征后,我们引入一系列新的注释:

n n n 代表特征的数量
x ( i ) x^{(i)} x(i) 代表 i i i 个训练实例,是特征矩阵中的第 i i i 行,是一个向量(vector)。

例:
在这里插入图片描述
x j ( i ) x^{(i)}_j xj(i)代表特征矩阵中 i i i 行的第 j j j 个特征,也就是第 i i i 个训练实例的第 j j j 个特征。
在这里插入图片描述
支持多变量的假设 h h h 表示为:在这里插入图片描述
这个公式中 n + 1 n+1 n+1 个参数和 n n n 个变量,为了使得公式能够简化一些,引入 x 0 = 1 x_0=1 x0=1,则公式转化为:
在这里插入图片描述
此时模型中的参数是一个 n + 1 n+1 n+1 维的向量,任何一个训练实例也都是 n + 1 n+1 n+1 维的向量特征矩阵 X X X 的维度是 m ∗ ( n + 1 ) m * (n+1) m(n+1)

公式可以简化为:
在这里插入图片描述
其中上标 T T T 代表矩阵转置

4.2 多变量梯度下降

与单变量线性回归类似,在多变量线性回归中,我们也构建一个代价函数,则这个代价函数是所有建模误差的平方和,即:
在这里插入图片描述
在这里插入图片描述
其中:
在这里插入图片描述
多变量线性回归模型如下。为了简化,我们加入 X 0 = 1 X_0 = 1 X0=1,参数 θ \theta θ 为一个 n + 1 n+1 n+1 维向量 vector。算法会同步更新每一个 θ j ( j = 0 到 n ) \theta_j (j = 0到n) θj(j=0n)

我们的目标和单变量线性回归问题中一样,是要找出使得代价函数最小的一系列参数。 多变量线性回归的批量梯度下降算法为:
在这里插入图片描述
即:
在这里插入图片描述
求导数后得到:
在这里插入图片描述
n > = 1 n>=1 n>=1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们开始随机选择一系列的参数值,计算所有的预测结果后,再给所有的参数一个新的值,如此循环直到收敛。

代码示例:

1、计算代价函数
在这里插入图片描述
Python 代码:

def computeCost(X, y, theta):
    inner = np.power(((X * theta.T) - y), 2)
    return np.sum(inner) / (2 * len(X))

4.3 梯度下降法实践1-特征缩放

多维特征问题中,帮助梯度下降算法更快地收敛,特征需要具有相近的尺度(similar scale),这就需要我们进行 特征缩放Feature Scaling

假设两个特征房屋尺寸的值为 0-2000 平方英尺,而房间数量的值为 0-5对应的代价函数等高线图会显得很扁(skewed elliptical shape),梯度下降算法需要非常多次的迭代才能收敛(左图)

把房屋尺寸除以2000,房屋数量除以5,尝试将所有特征的尺度都尽量缩放到 -1 到 1 之间,得到了近乎圆形的等高线(右图)
在这里插入图片描述
尺度也不是必须要 -1 到1,但是范围不能很大,也不能很小
在这里插入图片描述
最简单的方法是均值归一化(Mean normalization)

x i = x i − μ i s i x_i = \frac{x_i-\mu_i}{s_i} xi=sixiμi ,其中 μ i \mu_i μi 是平均值, s i s_i si 是标准差。

在这里插入图片描述

4.4 梯度下降法实践2-学习率

为保证梯度下降算法正确运行,可以绘制 迭代次数 iteration numbers代价函数的图表观测算法在何时趋于收敛(左边)

还有一些自动测试是否收敛的方法 (automatic convergence test),例如使用阈值 ε(右边)。因为阈值的大小很难选取,还是左侧的图表比较好

在这里插入图片描述
随着迭代次数增加,代价函数应该呈下降趋势如果上升或者频繁升降,说明 α 取得太大,可能导致不能收敛。如果 α 取值太小,算法会运行的很慢,但还是下降的,通常会迭代很多次后收敛
在这里插入图片描述
学习率可以尝试如下值: α = 0.001 , 0.003 , 0.01 , 0.03 , 0.1 , 0.3 , 1 , 3 , 10 \alpha = 0.001,0.003,0.01,0.03,0.1,0.3,1,3,10 α=0.001,0.003,0.01,0.03,0.1,0.3,1,3,10
在这里插入图片描述

4.5 特征和多项式回归

不一定非要用已有特征,可以创造新的特征,例如:面积 = 长 * 宽。这时二次函数变成了单变量函数
在这里插入图片描述
h θ ( x ) = θ 0 + θ 1 × f r o n t a g e + θ × d e p t h h_\theta(x) = \theta_0+\theta_1\times frontage + \theta\times depth hθ(x)=θ0+θ1×frontage+θ×depth
在这里插入图片描述
h θ ( x ) = θ 0 + θ 1 x h_\theta(x) = \theta_0+\theta_1x hθ(x)=θ0+θ1x

线性回归并不适用于所有数据,有时我们需要曲线来适应我们的数据

二次方程模型:

h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 2 h_\theta(x) = \theta_0+\theta_1x_1+\theta_2x_2^2 hθ(x)=θ0+θ1x1+θ2x22

三次方程模型:

h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 2 + θ 3 x 3 3 h_\theta(x) = \theta_0+\theta_1x_1+\theta_2x_2^2+\theta_3x_3^3 hθ(x)=θ0+θ1x1+θ2x22+θ3x33

因为实际生活中,随着房屋面积上升、房价不可能减小,而二次曲线会先上升后下降选择三次方模型,引入另外的变量替换高次幂,将其转换为线性回归模型
在这里插入图片描述
通常我们需要先观察数据然后再决定准备尝试怎样的模型。 另外,我们可以令: x 2 = x 2 2 , x 3 = x 3 3 x_2=x_2^2,x_3=x_3^3 x2=x22,x3=x33,从而将模型转化为线性回归模型

为了和曲线拟合的更好,还可以使用 平方根 square root
在这里插入图片描述
注:如果我们采用多项式回归模型,在运行梯度下降算法前,特征缩放非常有必要

4.6 正规方程

(1)正规方程的思想:假设代价函数 J(Θ) 的偏导数等于0,求解方程,得到使代价函数 J(Θ) 最小的参数 Θ。即求曲线的最低点(切线斜率为0)

最简单的情况,只有一维,代价函数是二次曲线:
在这里插入图片描述
如果有 n n n 个特征,则 θ \theta θ n + 1 n+1 n+1 维。针对代价函数 J ( θ ) J(\theta) J(θ) 的每一项 J ( θ j ) J(\theta_j) J(θj) ,设其偏导数为 0 。通过数学方法求解方程,得到使代价函数 J ( θ j ) J(\theta_j) J(θj) 最小的 θ j \theta_j θj
在这里插入图片描述
正规方程是通过求解下面的方程来找出使得代价函数最小的参数的: ∂ ∂ θ j J ( θ j ) = 0 \frac{\partial}{\partial\theta_j}J(\theta_j)=0 θjJ(θj)=0

(2)假设训练集特征矩阵为 X X X(包含 x 0 = 1 x_0 = 1 x0=1),训练集结果为向量 y y y ,则利用正规方程解出向量 θ = ( X T X ) − 1 X T y \theta=(X^TX)^{-1}X^Ty θ=(XTX)1XTy 。 上标 T T T 代表矩阵转置,上标 − 1 -1 1 代表矩阵的逆。设矩阵 A = X T X A=X^TX A=XTX ,则: ( X T X ) − 1 = A − 1 (X^TX)^{-1}=A^{-1} (XTX)1=A1 ,则解 θ \theta θ 可以通过公式求出:

θ = ( X T X ) − 1 X T y \theta=(X^TX)^{-1}X^Ty θ=(XTX)1XTy

例子,四个数据:
在这里插入图片描述
即:
在这里插入图片描述

θ \theta θ 为:
在这里插入图片描述
在 Octave 中,正规方程写作:

pinv(X'*X)*X'*y

注:对于那些不可逆的矩阵(通常是因为特征之间不独立,如同时包含英尺为单位的尺寸和米为单位的尺寸两个特征,也有可能是特征数量大于训练集的数量),正规方程方法是不能用的

(3)梯度下降和正规方程的比较

梯度下降正规方程
需要选择学习率 α \alpha α不需要
需要多次迭代一次运算得出
当特征数量 n n n 大时也能较好适用需要计算 ( X T X ) − 1 (X^TX)^{-1} (XTX)1 如果特征数量 n n n 较大则运算代价大,因为矩阵逆的计算时间复杂度为 O ( n 3 ) O(n^3) O(n3) ,通常来说当 n n n 小于10000 时还是可以接受的
适用于各种类型的模型只适用于线性模型,不适合逻辑回归模型等其他模型

在这里插入图片描述
总结:

1、特征变量的数目 n 不大的时候,推荐使用正规方程。

2、n 比较大的时候(例如10000),考虑梯度下降。

3、某些算法(例如分类算法中的逻辑回归)不能使用正规方程法,只能使用梯度下降。

当我们讲到分类算法,像逻辑回归算法,我们会看到,实际上对于那些算法,并不能使用正规方程法。对于那些更复杂的学习算法,我们将不得不仍然使用梯度下降法。因此,梯度下降法是一个非常有用的算法,可以用在有大量特征变量的线性回归问题。或者我们以后在课程中,会讲到的一些其他的算法,因为正规方程法不适合或者不能用在它们上。但对于这个特定的线性回归模型,正规方程法是一个比梯度下降法更快的替代算法。所以,根据具体的问题,以及你的特征变量的数量,这两种算法都是值得学习的。

正规方程的python实现:

import numpy as np
 def normalEqn(X, y):
   theta = np.linalg.inv(X.T@X)@X.T@y #X.T@X等价于X.T.dot(X)
   return theta

4.7 正规方程及不可逆性

当矩阵 X T X X^TX XTX 不可逆怎么办? 不可逆的问题很少发生,即使发生,使用 p i n v ( ) pinv() pinv() 也能正常算出结果

---
pinv()pseudo-inverse伪逆即使 singular degenerate 也能算出来逆矩阵
inv()inverse逆引入了先进的数值计算的概念

两种情况可能导致不可逆

1、有冗余特征 redundant features,即特征值线性相关(例如 x1 = 常数 * x2)

解决:删除冗余特征

2、特征维数 n ≤ 数据规模 m (例如10个样本适应100+1个参数)

解决:删除特征,或者使用线性代数中的正则化 regularization方法
在这里插入图片描述
首先,看特征值里是否有一些多余的特征,像这些 x 1 x_1 x1 x 2 x_2 x2 是线性相关的,互为线性函数。同时,当有一些多余的特征时,可以删除这两个重复特征里的其中一个,无须两个特征同时保留,将解决不可逆性的问题。因此,首先应该通过观察所有特征检查是否有多余的特征,如果有多余的就删除掉,直到他们不再是多余的为止,如果特征数量实在太多,我会删除些用较少的特征来反映尽可能多内容,否则我会考虑使用正规化方法。 如果矩阵 X ′ X X'X XX 是不可逆的,(通常来说,不会出现这种情况),如果在Octave里,可以用伪逆函数 p i n v ( ) pinv() pinv() 来实现。这种使用不同的线性代数库的方法被称为伪逆。即使 X ′ X X'X XX 的结果是不可逆的,但算法执行的流程是正确的。总之,出现不可逆矩阵的情况极少发生,所以在大多数实现线性回归中,出现不可逆的问题不应该过多的关注 X T X X^TX XTX 是不可逆的

在这里插入图片描述

5 Octave教程

5.1 基本操作

(1)简单运算

不等于符号的写法是这个波浪线加上等于符号 ( ~= ),而不是等于感叹号加等号( != ):

1 == 1    %  判断相等
1 ~= 2    %  判断不等
1 && 0     %  求逻辑与
1 || 0     %  求逻辑或
xor(1, 0)   % 求异或

简化命令行:

PS1('>> ');

分号 semicolon 不打印结果:

 >> a = 3;  %semicolon supressing output

浮点数的输出:

>> a = pi;
>> a
a =  3.1416
>> disp(a);
3.1416
>> disp(sprintf('2 decimals: %0.2f', a))
2 decimals: 3.14
>> disp(sprintf('6 decimals: %0.6f', a))
6 decimals: 3.141593

控制输出格式的长短:

>> format long
>> a
a =  3.141592653589793
>> format short
>> a
a =  3.1416

(2)向量和矩阵

>> A = [1 2; 3 4; 5 6]
1   2
3   4
5   6
>> A = [1 2;
3 4;
5 6]
1   2
3   4
5   6
>> v = [1 2 3]
1   2   3
>> v = [1; 2; 3]
1
2
3

通过步长生成行向量:

>> v = 1:0.1:2
v =
Columns 1 through 4:
1.0000    1.1000    1.2000    1.3000
Columns 5 through 8:
1.4000    1.5000    1.6000    1.7000
Columns 9 through 11:
1.8000    1.9000    2.0000
>> v = 1:6   
1   2   3   4   5   6

全是1, 或者全是0 的矩阵:

>> v = ones(2,3)
1   1   1
1   1   1
>> v = ones
v =  1
>> v = ones(3)
1   1   1
1   1   1
1   1   1
>> v = 2*ones(2,3)
2   2   2
2   2   2
>> w = zeros(1,3)
0   0   0

使用eye() 函数生成单位矩阵:

>> I = eye(6)
1   0   0   0   0   0
0   1   0   0   0   0
0   0   1   0   0   0
0   0   0   1   0   0
0   0   0   0   1   0
0   0   0   0   0   1

矩阵大小:

>> A = [1 2; 3 4; 5 6]
1   2
3   4
5   6
>> sz = size(A) % 矩阵大小
3   2
>> size(sz)      
1   2
>> size(A,1)  % 矩阵行数
ans =  3
>> size(A,2)  % 矩阵列数
ans =  2
>> length(A)   % length输出矩阵最大维的大小
ans =  3

获取元素:

>>  A = [1 2; 3 4; 5 6; 7 8; 9 10];
>> A(3,2)    % 获取一个元素
6
>> A(2, :)    % 获取一行元素,冒号指所有列
3   4
>> A([1 3], :)     % 返回 13 两行的元素
1   5
2   6
>>  A(2:4, :)     % 返回 234 三行元素(注意和上一个的区别) 
3   4
5   6
7   8
>>  A(2:3)    % 这里很奇怪,是从上到下依次返回
3   5
>>  A(2:5)
3   5   7   9
>>  A(1:10)
1    3    5    7    9    2    4    6    8   10    

矩阵转置:

21> A'
ans =
1   3   5
2   4   6
22> (A')'
ans =
1   2
3   4
5   6

(3)矩阵赋值和拼接

矩阵赋值:

>> A(:,2) = [10; 11; 12]  % 给A的第二列赋值
A =
1   10
3   11
5   12

扩充矩阵:

>> A = [A , [100; 101; 102]]  % 给矩阵添加一列
A =
1    10   100
3    11   101
5    12   102
>> A = [A ; [100 101 102]]  % 给矩阵添加一行
A =
1    10   100
3    11   101
5    12   102
100   101   102

矩阵转换成列向量:

>> A(:)    % 冒号含义很特殊,将A中所有元素都放于一个列向量中
ans =
1
3
5
100
10
11
12
101
100
101
102
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]        
% “横”着连接
1    2   11   12
3    4   13   14
5    6   15   16
>> C = [A, B]       
% “横”着连接
C =
1    2   11   12
3    4   13   14
5    6   15   16
>> C = [A; B]      
% “竖”着连接
C =
1    2
3    4
5    6
11   12
13   14
15   16

(4)随机数

取随机数,定义维度,随机数大小总在0到1之间:

>> w = rand(3,3)
w =
0.19782   0.42514   0.10275
0.83117   0.66312   0.37967
0.27300   0.92920   0.62790

生成一个一行三列的 高斯随机分布 :

>> w = randn(1,3)
w =
-0.025352   0.023321   1.729415

生成一个一行10000列,均值为6的高斯随机分布矩阵:

>> w = - 6 + sqrt(10) * (randn(1,10000));

使用hist()函数展示直方图:

hist(w)

在这里插入图片描述
生成50个条的直方图:

hist(w, 50) 

在这里插入图片描述

5.2 移动数据

pwd 指令:得到Octave默认路径;
cd 指令:change direction 即改变路径,自己指定路径,但路径名中不要包含汉字
ls 指令:列出默认路径中包含的所有路径或者文件
load test.dat :加载文件中的数据到test变量中
load(‘test.dat’) :同上
test :显示test变量里的数据内容
who/whos :列出目前Octave工作空间中包含的所有变量
clear test :删除工作空间的变量test
V = test(1 : 10) :取test中的前十个赋值给变量v
save hello.mat V :将变量V保存在hello.mat文件中,注意当再次加载进来时,变量的名称仍然是V 而非文件名hello
save hello.txt V -ascii:存为可以看的 txt 文件

从文件中加载数据到变量:

>> ls              % 查看路径下的文件
Directory of D:\myc_learn\machine_learning\code\week2
[.]             [..]            featuresX.dat   priceY.dat
2 File(s)            658 bytes
2 Dir(s)  770,788,524,032 bytes free
>> load featuresX.dat      % 使用load 加载房屋特征文件
>> featuresX           % 打印featuresX
featuresX =
2343      3
4343      6
2222      3
1245      2
2345      5
2234      2
2123      6
 ... ...
>> size(featuresX)    % 矩阵大小
ans =
47    2
>> load('priceY.dat')  % 加载文件
>> size(priceY)
ans =
47    1

使用who 和whos 查看都有哪些变量:

>> who
Variables in the current scope:
A          ans        featuresX  priceY     sz
>> whos
Variables in the current scope:
Attr Name           Size                     Bytes  Class
==== ====           ====                     =====  =====
     A              3x2                         48  double
     ans            1x2                         16  double
     featuresX     47x2                        752  double
     priceY        47x1                        376  double
     sz             1x2                         16  double
Total is 151 elements using 1208 bytes

删除变量:

>> clear featuresX
>> who
Variables in the current scope:
A       ans     priceY  sz

保存变量到文件:

>> V = priceY(1:10)        % 将priceY的前10个元素赋值给V
V =
3048
4702
6069
5001
6321
3274
2183
4205
8270
7704
>> save hello.mat V        % 将V保存到文件hello.dat中
>> clear V            % 清除变量V
>> whos                % 查看都有哪些变量
Variables in the current scope:
Attr Name        Size                     Bytes  Class
==== ====        ====                     =====  =====
     A           3x2                         48  double
     ans         1x2                         16  double
     priceY     47x1                        376  double
     sz          1x2                         16  double
28 Total is 57 elements using 456 bytes

保存的 hello.mat 是二进制格式。 如果保存成 dat 格式,文件中数据如下:
在这里插入图片描述
从文件中加载回变量V:

>> load hello.mat
>> whos
Variables in the current scope:
Attr Name        Size                     Bytes  Class
==== ====        ====                     =====  =====
     A           3x2                         48  double
     V          10x1                         80  double
     ans         1x2                         16  double
     priceY     47x1                        376  double
     sz          1x2                         16  double
Total is 67 elements using 536 bytes
>> V
V =
3048
4702
6069
5001
6321
3274
2183
4205
8270
7704

保存成可以看的 txt 文件:

save hello.txt V -ascii

在这里插入图片描述
因为用到房屋价格数据,干脆用Octave生成了一些随机数,粘贴进了文件 priceY.dat 里:

A   = 10000 * rand(1,47)    % 生成470-1的随机数,并且乘以10000
disp(sprintf('%0.0f\n',A))   % 打印成整数形式

5.3 计算数据

(1)矩阵相乘

矩阵相乘 矩阵点乘:

> A = [1 2; 3 4; 5 6]
> C = [1 1 ; 2 2]
> A * C    % 矩阵相乘
5    5
1   11
17   17  
    
B =
11   12
13   14
15   16
> A .* B   % 矩阵点乘 各元素逐一相乘
11   24
39   56
75   96

A .^ 2      % 每个元素取平方
1 ./ A       % 取倒数 

(2)向量计算

最大值:

> a = [1 15 2 0.5]
> val = max(a)
val =  15
> [val, ind] = max(a)    % ind 返回最大值位置
val =  15
ind =  2

向量逻辑判断:

a < 3      % 对每个元素进行逻辑判断
1  0  1  1
find(a < 3)  % 在上面进行逻辑判断的基础上,返回结果为真的索引
1   3   4

向量常用函数:

sum(a)     % 所有元素求和
prod(a)    % 所有元素相乘

floor(a)    % round down 向下取整
ceil(a)     % round up 向上取整
round(a)     % 四舍五入

std(a)      % 求标准差
mean(a)      % 求平均值 
abs([-1;2;-3])   % 取绝对值

log(v)            % 取log
exp(v)            % 取e为底的指数, e=2.71828

向量运算:

> v
1
2
3
> -v
-1
-2
-3
> v + ones(length(v), 1)
2
3
4
> ones(3,1)
1
1
1
> v + ones(3,1)
2
3
4
> v + 1
2
3
4

(3)矩阵最大值

随机矩阵中的最大值:

>> rand(3)
0.64927   0.22644   0.61599
0.87125   0.68797   0.60553
0.69778   0.25321   0.12596
>> max(rand(3), rand(3))  % 随机矩阵中的最大值
0.51841   0.89632   0.75562
0.21897   0.68484   0.75206
0.97807   0.73515   0.75578

求矩阵的行最大值、列最大值:

>> A
8   1   6
3   5   7
4   9   2
>> max(A)    % 返回每一列的最大值
8   9   7
>> max(A,[],1)  % 返回每一列的最大值
8   9   7
>> max(A,[],2) % 返回每一行的最大值
8
7
9

两种求矩阵中所有元素最大值的方法:

>> max(max(A))
ans =  9
>> max(A(:)) 
ans =  9

(4)矩阵相乘

A = magic(3)% 生成一个magic squares。其行、列、对角线 元素和等于同一个数
[r,c] = find(A>=7)%返回符合条件元素的行坐标和列坐标
sum(A,1)% 矩阵每一列相加
sum(A,2)% 矩阵每一行相加
A .* eye(9)% 矩阵主对角线的值
sum(sum(A .* eye(9)))% 主对角线求和
flipud(eye(9))% 次对角线的值
sum(sum(A .* flipud(eye(9))))% 次对角线求和
> A = magic(3) 
8   1   6
3   5   7
4   9   2
> [r,c] = find(A>=7) % 返回符合条件元素的行坐标和列坐标
r =
1
3
2
c =
1
2
3     %(1,1)(3,2)(2,3)三个元素>=7

矩阵列相加,行相加:

>> A = magic(9)
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)        % 矩阵每一列相加
369   369   369   369   369   369   369   369   369
>> sum(A,2)       % 矩阵每一行相加
369
369
369
369
369
369
369
369
369   

矩阵主对角线的值:

>> A .* eye(9)  % 矩阵主对角线的值
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

矩阵次对角线的值:

>> flipud(eye(9))    % 次对角线的值
0   0   0   0   0   0   0   0   1
0   0   0   0   0   0   0   1   0
0   0   0   0   0   0   1   0   0
0   0   0   0   0   1   0   0   0
0   0   0   0   1   0   0   0   0
0   0   0   1   0   0   0   0   0
0   0   1   0   0   0   0   0   0
0   1   0   0   0   0   0   0   0
1   0   0   0   0   0   0   0   0
>> sum(sum(A .* flipud(eye(9))))  % 次对角线求和
ans =  369    

5.4 绘制数据图

(1)绘制曲线

1、画一个sin曲线

>> t = [0:0.01:0.98];
>> y1 = sin(2 * pi * 4 * t);
>> plot(t,y1);

在这里插入图片描述
2、画一个cos曲线

>> y2 = cos(2 * pi * 4 * t);
>> plot(t,y2);

在这里插入图片描述
3、将两个曲线合并在一起

>> plot(t,y1);
>> hold on
>> plot(t,y2,'r');

在这里插入图片描述
4、给图像添加信息

>> xlabel('time')    % X轴标签
>> ylabel('value')   % Y轴标签
>> legend('sin','cos')  % 添加曲线名称
>> title('my plot')  % 添加标题

在这里插入图片描述
5、保存到文件

>> print -dpng 'myPlot.png'
>> ls
Directory of D:\myc_learn\machine_learning\code\week2
[.]             5.m             hello.dat       myPlot.png
[..]            featuresX.dat   hello.txt       priceY.dat
>> close

6、绘制多张图

绘制多张图,需要指定将哪个曲线放在哪个图中。否则会一直绘制在当前窗口,覆盖之前的图形

>> figure(1); plot(t,y1);  
% 在figure1中绘制

>> figure(2); plot(t,y2);  
% 在figure2中绘制

7、将两个图显示在一张图片中

>> subplot(1,2,1);  % 将图片划分为两个格子,访问第一个格子
>> plot(t,y1)    % 画第一个图像
>> subplot(1,2,2);  % 访问第二个格子
>> plot(t,y2)    % 画第二个图像

在这里插入图片描述
8、改变坐标轴范围

>> axis([0.5 1 -1 1])

在这里插入图片描述
点击一下第一张图片,再运行一下上面那行代码,图变为:

在这里插入图片描述
9、清空和关闭图片

>> clf    % 清空
>> close   % 关闭

(2)绘制可视化矩阵

1、生成矩阵图

根据矩阵的值生成图像,不同的颜色对应矩阵中不同的值

>> 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)

在这里插入图片描述
2、显示颜色条

>> colorbar

在这里插入图片描述
或者直接使用下面的一行代码:

>> imagesc(magic(5)), colorbar;

3、生成灰度图

>> imagesc(A), colorbar, colormap gray;

在这里插入图片描述
生成一个15行15列灰度图

>> imagesc(magic(15)),colorbar,colormap gray;

在这里插入图片描述
以 imagesc(magic(15)),colorbar,colormap gray; 为例。

这种几个逗号隔开的命令一起运行的方式,叫做逗号连接函数调用 comma chaining of function calls 或 comma chaining commands 。

比如赋值操作可以写成:a=1, b=2, c=3;

(3)散点图

plot(x,y,'rx', 'MarkerSize', 10);
xlabel('Population of City in 10,000s');
ylabel('Profit in $10,000s');
title('POPULATION AND PROFIT');

在这里插入图片描述
图像绘制在Octave官方文档的 15.2.1 Two-Dimensional Plots ,图形属性设置在15.3.3.4 Line Properties。

如果想设置某个属性,直接写属性名,后面跟一个值。plot (x, y, property, value, …)

例如 plot (x, y, ‘linewidth’, 2, …);
在这里插入图片描述

5.5 控制语句: for, while, if 语句

1、for 循环 通过 index 访问列向量

>> v = zeros(10,1)
v =
0
0
0
0
0
0
0
0
0
0
>> for i = 1 : 10,
     v(i) = 2 ^ i;
   end;
>> v
v =
2
4
8
16
32
64
128
256
512
1024

2、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

3、while 循环访问列向量

>> i = 1;
>> while i <= 5,
     v(i) = 100;
     i = i + 1;
   end;
>> v
v =
100
100
100
100
100
64
128
256
512
1024

4、while(true) 和 break

>> 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

5、if else 语句

>> 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

6、自定义函数 function

定义函数 squareThisNumber(x),内容如下:

function y = squareThisNumber(x)
  y = x^2;
endfunction

将函数保存为squarethisnumber.m,注意此时是小写。

这时候调用函数 squareThisNumber(2) 提示找不到函数

>> squareThisNumber(2);
error: 'squareThisNumber' undefined near line 1 column 1
>>
>> ls
[.]                         featuresX.dat               priceY.dat
[..]                        hello.dat                   squarethisnumber.m

将文件命名为函数一致squareThisNumber.m(大小写也一致),这时候调用函数成功

>> ls
[.]                         featuresX.dat               priceY.dat
[..]                        hello.dat                   squareThisNumber.m
>> squareThisNumber(2);
>> a = squareThisNumber(2);
>> a
a =  4

这说明:Octave 是大小写敏感的,文件名必须和函数名大小写一致。

7、多个返回值的函数

Octave 函数有和其他语言不一样的地方是可以返回多个值。定义方法squareAndCubeThisNumber(x)如下:

function [y1, y2] = squareAndCubeThisNumber(x),
  y1 = x ^ 2;
  y2 = x ^ 3;
endfunction

调用:

>> a = squareAndCubeThisNumber(2)  % 接受了第一个返回值
a =  4
>> [a, b] = squareAndCubeThisNumber(2)  % 接受两个返回值
a =  4
b =  8

8、更复杂的函数

保存下面的函数到costFunctionJ.m中

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, size of rows
  predictions = X * theta; % predictions of hapothesis on all m examples
  sqrErrors = (predictions - y) .^ 2; % squared errors .^ 指的是对数据中每个元素平方 
  J = 1 / (2 * m) * sum(sqrErrors); 
endfunction

在这里插入图片描述
针对上边的数据集初始化矩阵。调用函数,计算代价函数的值。

>> X = [1 1; 1 2 ; 1 3];
>> y = [1;2;3];
>> theta = [0;1];      % Θ为0,1  h(x)=x  此时完全拟合数据,代价函数的值为0
>> j = costFunctionJ(X,y,theta)
j = 0

5.6 向量化

下面是向量化的小例子,如果将所有u(j) 、所有v(j)、所有w(j)都看成列向量,则公式变为为向量加法 u = 2v + 5w

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有时我们使用几十或几百个特征量来计算线性回归,当使用向量化地实现线性回归,通常运行速度就会比 for 循环快的多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值