吴恩达机器学习Coursera-week2
Multivariate Linear Regression
Multivariate Features
当我们的线性回归函数中有多个变量的时候,或者说我们的样本中有多个features的时候,那么我们就称作多变量线性回归(Multivariate Linear Regression)。本小节主要讲了一些符号表示notation,如下:
notation
通常x(i)表示的是一个vector,这个vector中的数据是第i行的样本的features
之后,我们的假设h就变成了如下形式:
hypothesis
通常,我们还会假设x0为1,这时就可以如下形式表示假设:
hypothesis
通过这种方式,我们的θT就是一个1x(n+1)的矩阵,而x(i)就成了一个(n+1) x 1 矩阵(或者说vector),这样它们就可以方便的相乘。所以通常我们都会把x0设为1,并放入到x的vector当中。
Gradient Descent For Multiple Variables
多变量梯度下降其实跟之前的梯度下降非常类似,只不过原先只需求解θ0和θ1,现在我们需要求解θ0....θn
看下多变量情况下的梯度下降求解过程:
multiple variable gradience decent
更简洁的表示形式如下:
gradient decent
直觉上理解下这个公式,我们这个梯度下降的求解过程就是要寻找J(θ)的最小值,也就是要去找h(θ)与y之间距离最小的函数,而这个公式中的在求解合适的θ时,除了计算h(x) 与y的差,还会乘上一个权重,这个权重就是xj,不同的θj,其下降的幅度是受其权重,也就是xj影响的。这里是我的理解,如有不对,请指正。
再给出一个单变量和多变量梯度下降的对比:
compare gradient decent
Feature Scaling
首先理解一下范围(scale)的概念,这个是指某个特征的取值范围,比如样本的房屋尺寸,假设尺寸范围是从10-2000,那么其scale就是(10-2000)
而当多个feature其取值范围差距特别大时,梯度下降会非常慢,如下图左边的图:
当我们如图右所示除以一个数值,使得特征值的范围限定在一个较小的区间时(本例是限定在0,1区间),那么梯度下降就会非常迅速。
这就引入了一个新的概念Feature Scaling(有人翻译做特征缩放),Feature Scaling就是要调整feature对应的取值范围(注意计算的时候,每个样本的feature value都需要做对应的调整),从而可以加速梯度下降。直观上理解就是把原本极为陡峭崎岖的山头改成了平缓的山头,这样下山更快。
通常我们可以更一般化的使用mean normalization(有人翻译做均值归一化)的方式进行Feature Scaling,如下:
mean normalization
其中μ表示mean(均值,就是我们通常说的平均值)
S可以用(max - min)这个范围值,也可以使用标准差σ(standard deviation).
关于均值,标准差的概念请参考《统计学基础一》
根据目前的理解,做一个脑图表示下不同feature scaling
feature scaling
目前在网上看到的资料有所不同,其两种归一化方法,一种叫min-max Scaling,其减的不是均值而是最小值,然后再除以最大值和最小值之差;另外一种是叫Z-score standardization,就是标准差那种方式。具体可以参考这篇文章。另外需要注意的是,在预测的时候,输入数据需要做同样的处理,即使用同样的均值和标准差
Learning Rate
这节课Andrew主要讲了他是如何选择learning rate的。
之前的课其实已经讲过当learning rate 𝑎过大的时候可能会导致J(θ)越来越大,或者过小的时候,导致梯度下降的非常慢。这里重点讲了怎么去debug,Andrew是通过J(θ)与迭代次数(No. of iterations)之间的函数图来判断𝑎取值是否合理,如下图是一个正常的梯度下降时,J(θ) 和No. of iteration的关系图:
J(θ) and NO of iterations
这幅图的纵坐标是J(θ)的值,横坐标是迭代次数。也就展示了随着迭代次数的增长,J(θ)有没有下降。
Andrew提到我们也可能通过一个自动化的方法来测试是否收敛,如下图:
auto test convergence
但是,找到一个合适的threshold是非常难的,因此,Andrew还是建议使用关系图的方式来看learning rate是否合适。
当𝑎过大时,其关系图可能如下图所示:
not correct learning rate
Andrew给出的建议是通常会选取一系列的值,每个值都是倍数关系,比如10倍,然后再去测试,找到那个边界的𝑎值,通常可以选取能够收敛的最大的𝑎值,或者找一个𝑎,让其小于不能收敛的那个𝑎边界值,通常可以找到比较好的𝑎
Features and Polynomial Regression
这一小节主要将了一个概念叫Feature Choice
, 所谓Feature Choice,即我们对待一个feature,实际可以通过不同的方式来使用它,比如房屋尺寸,假设我们的初始Feature是frontage和depth,我们可以直接使用它们作为Feature,但也许会使用它们的乘积size。当我们选择不同的数据的使用方式时,也许我们会取得更好的效果。
同样是size,我们可以使用size的平方,或者立方,或者1/2次方。通过不同的方式使用size,也就是所谓的Feature Choice。通过使用更好的Feature Choice,我们的h(x)可以更好的拟合实际情况,Andrew课堂上讲到会有自动获取合适算法的方法,不过此小节还未讲到。
另外,当使用不同的feature choice时,scale范围可能会差距非常大,所以Feature Scaling就会变得非常重要,如下图所示:
polynomial regression
关于polynomial的解释,引用自wiki:
In mathematics, a polynomial is an expression consisting of variables (also called indeterminates) and coefficients, that involves only the operations of addition, subtraction, multiplication, and non-negative integer exponents of variables
在我们的例子中,size就是variable, θ就是coeficient,也就是我们通常说的parameters,且variable的指数只能是正整数,在我们的例子中只有平方和立方
视频中Andrew说到可以通过算法自动选择feature choice,即选择是否使用平方还是立方或者其它,但是这里没有讲具体是什么算法
Computing Parameters Analytically
Normal Equation
此小节Andrew主要讲了另外一种最小化J(θ)的方法,就是normal equation
。normal equation的想法主要是基于微积分的知识,即当我们想要求一个使得J(θ)最小时的参数,只需要设其导数为0,然后通过这个公式来求解θ,如下图所示:
最重要的是通过下边这个方程求出对应的θj:
set derivative to zero
...
部分实际是求导,然后代入等于0的方程,在计算出θ值,注意这里是针对每个θj都需要类似的计算。最终,我们可以得到如下方程,这个就是
normal function
normal equation
其中,X代表的是包含x(0)样本的矩阵,y是样本输出的vector,如下图所示:
normal equation
在Octave中,如果要计算上述的normal equation,可以使用如下方式:
pinv(x'*x)*x'*y
normal equation的方式和梯度下降的方式相比较,各有适用的场景,其比较如下表所示:
compare of normal equation and gradient decent
总的来说,normal equation适用于Feature数量较少时(一般不超过10000),而且只适用于特定的算法(如线性回归算法),其好处是无需花费时间去选择learning rate,也不需要做feature Scaling,也不用迭代,对于n比较小的情况,可以非常快速的计算出θ。而梯度下降适用于几乎所有的算法,而且对于n比较大时,它的时间复杂度要好于normal equation,所以很多情况下我们还是会使用梯度下降
Normal Equation Noninvertibility
上节我们已经知道了normal equation如下:
normal equation
但是,我们也知道并不是所有的矩阵都存在逆矩阵(Singular and degenerate matrix是不可逆的)
当我们使用octave做计算的时候,其提供了两种类型:一种以pinv,即所谓pseudo-inverse;另一种是inv。其中pinv无论矩阵是否可逆都可以给出正确答案。
一般来说,没有逆矩阵,可能是出现了如下两种情况:
- 重复的feature。比如房屋尺寸x1 使用了平方米,x2使用了平方英尺,实际上是一个feature,它们之间存在确定的关系。这种情况会导致矩阵不可逆。
- feature太多。当feature特别多的时候,以至于n>m,这时也可能出现不可逆的矩阵。这种情况下,我们可以delete some features or use "regularization"
Octave/Matlab Tutorial
Basic Operations
基本数值运算
此小节主要讲了Octave的一些基本用法,包含基本的加减乘除运算,还有逻辑运算等。这里只说下跟其它编程语言不同的地方:
- 次方运算
2^6 %在其它程序语言中这个^符号可能代表异或运算,但在Octave中代表次方运算,本例是2的6次方
64
- 非等判断式
1 ~= 2 %其它程序语言一般使用!=, 而Octave使用~=
1
- 格式化输出
a = pi; %带有分号,可以使得不输出a的结果
disp(sprintf("5 decimal: %0.5f", a)); % 类似C语言的格式化输出
5 decimal: 3.14159
矩阵
- 基本操作
x = [1 2 3; 3 2 1]
x =
1 2 3
3 2 1
- 初始为0的矩阵
zeros = zeros(2, 3)
- 初始为1的矩阵
one_matrix = ones(3, 2) %生成一个3x2的数值为1的矩阵
one_matrix =
1 1
1 1
1 1
- 初始为随机值的矩阵
r = rand(2, 3) % 生成一个2 x 3的矩阵,数值为分布在0~1之间的随机数
r =
0.34653 0.74572 0.80101
0.65980 0.17789 0.93653
randn(3, 5) % 这里生成的是一个3 x 5矩阵,矩阵中的数值符合高斯分布,且平均值为0
ans =
-1.5018775 -0.1022936 1.6814589 -0.4514752 -0.5400882
-0.5453408 0.6493006 -1.1760725 -0.3327142 -1.2632034
-0.0028388 -0.3264883 -1.5950108 -0.3917801 1.5848447
- 单元矩阵identity matrix
i = eye(4) % 生成一个4x4单元矩阵
i =
Diagonal Matrix
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
- 特定步长的一维矩阵
x = 1: 6 % 通过: 来表示从1到6的范围,默认步长为1
x =
1 2 3 4 5 6
x = 1:0.5:6 % 步长为0.5
x =
Columns 1 through 10:
1.0000 1.5000 2.0000 2.5000 3.0000 3.5000 4.0000 4.5000 5.0000 5.5000
Column 11:
6.0000
Moving Data Around
此小节主要讲了如何从文件中load数据到内存并赋值给变量,以及如何将相应的数据保存到文件中;以及如何切割、组合矩阵等常用的Octave指令
- load and save data
load filename.dat %将filename.dat中的数据赋值给与文件名同名的变量filename,并且是一个矩阵
y = [1; 2; 3; 4; 5]
save filename.mat y; %将y矩阵存储到filename.mat文件当中,以二进制的形式存储
save textfile.txt y -ascii; %这里是以ASC2的编码存储为文本文件
- 常用指令
%size 返回一个1 x 2矩阵表明某个矩阵的维数
%length 返回longer dimension,一般用于vector
who %可以查询当前namespace有什么变量
whos %可以查询当前namespace的所有变量,并列出更详细的信息
clear y%用于清除当前namespace中特定variable或者全部variables
x = zeros(4, 5);
size(x)
ans =
4 5
length(x)
ans = 5
- 分割与组合
y = priceY(1:2) %取priceY vector中1~10项item
y= A(1,2) % 这里A是一个matrix,注意区别,这里中间是逗号,是取index为1,10的item的值
y = A(2, :) % 获取A matrix中第二行的所有element
A = [1, 2, 3; 2 3 4; 4 5 6];
A = [A, [2; 3; 1]] %注意这里是逗号,或者空格
A =
1 2 3 2
2 3 4 3
4 5 6 1
B = [A; [3 3 3 3]] %注意这里是分号
B =
1 2 3 2
2 3 4 3
4 5 6 1
3 3 3 3
Computing on data
- 常见的矩阵计算
A * B
A + B
1 ./ A %句点符号表示针对每一个element进行计算,这里是说1 除以每个element of A
log(A) % 取A的对数
exp(A) % 取e为底的指数
abs(A) % 取绝对值
- max
A = [1; 3; 5; 7; 9];
max(A)
ans = 9
[val, ind] = max(A) % 这里通过此种方式即返回最大值value,也返回其对应的index
val = 9
ind = 5
% 另外,如果A是一个矩阵,那么max返回的是column的最大值,即A如果是一个mxn的矩阵,那么会返回n个最大值
octave:60> A = magic(3)
A =
8 1 6
3 5 7
4 9 2
octave:61> max(A) % 这等价于max(A, [], 1)
ans =
8 9 7
% 我们也可以取row wide的最大值
octave:62> max(A, [], 2)
ans =
8
7
9
- 逻辑运算
find(A < 5) %element逐个比较,返回符合条件的element的index
ans =
1
2
- 其它函数
% prod 是所有元素的乘积
A = [1; 3; 5; 7; 9];
prod(A)
ans = 945
% sum 是所有元素的和
sum(A)
ans = 25
% floor, ceil 是所有元素分别取floor或者ceil值
A = [0.6, 1.3, 2.2, 3.8];
floor(A)
ans =
0 1 2 3
ceil(A)
ans =
1 2 3 4
Plotting Data
octave:1> t = [0:0.01:0.98];
octave:2> y1 = sin(2 * pi *4 *t);
octave:3> plot(t, y1); %第一个参数是横坐标是一个1x99 matrix,第二个参数是纵坐标也是一个1x99 matrix
画出的图如下:
sin
其它常用命令:
hold on; % 将不同函数画在同一个图上的时候使用
xlabel("time");
ylabel("value");
legend("sin", "cos");
title("my plot");
print -dpng 'myPlot.png';
close;
subplot(1, 2, 1); % 将图分成1 x 2维的格子,这里先取第一个格子作图
axis([1, 2, -1, 1]);
a = magic(9);
imagesc(a), colorbar, colormap gray; % 此处是三个命令先后执行,可以生成如下所示的图形
gray.png
Control Statements
控制语句
Octave的控制语句类似shell脚本,即每个控制块都需要end;
来结尾.
与其它语言稍有不同的是for循环如下:
% for循环使用类似python range的手法,只不过换成了等号
for i = (1:10), v(i)=i ^ 2; end; %注意在v(i)=i^2; 这句后边分号.
定义函数
我们可以在同名文件中定义函数,如下:
%文件名为:squareThisNumber.m
function y = squareThisNumber(x) % y is return value, x is parameter, squareThisNumber is function name
y = x ^ 2;
之后我们可以在该文件的同一个目录下引用该function
squareThisNumber(5);
25
我们也可以将该目录添加进Octave path当中,这样不论在什么目录下,Octave都可以搜索到该文件和函数。
addpath("filepath");
Vectorization
此小节是这周课程的难点所在,关键是要理解怎么样向量化vectorization的。
先看下h(x)的向量化
hyposis
可以看出当我们使用向量来计算的时候,可以非常简单。注意这里是针对一个样本的计算。
然后我们来看下梯度下降时,如何向量化
gradient decent
vectorized之后的公式如下:
vectorized gradient decent
注意:X为大写,表示样本的mx(n+1)阶矩阵,θ和y均为向量,θ为n+1阶,y为m阶。