Coursera 斯坦福吴恩达机器学习课程笔记 (1)
学习一周后的课程内容在短时间内难以记住, 于是乎制作了一份学习笔记用于巩固知识. 如果在过程中涉及侵权行为, 告知我一声, 我会立刻删除并表示歉意.
同时禁止任何形式的转载行为 如需使用 请提前与本人联系 422892137@qq.com 若发现任何侵权行为 请凭借已掌握的知识产权相关知识进行处理
第一周:基础概念和介绍
对机器学习的理解
目前关于机器学习尚无统一的定义。最直观的理解是让计算机无需编写详尽而完整的代码即可通过“自主学习”完成特定任务的能力(Arthur Samuel于1959年提出)。然而这样的描述仍较为抽象。一个更为直观的例子是:假设有一个computer program针对给定的任务T,在积累了一定数量的经验E的基础上,并通过适当的方法测量P后,能够自主学习并提升P的效果。
举个例子:
下棋的过程包括观察玩家下的棋局属于类别E;当达到目标状态即为成功;而完成目标所需的时间指标为P。为了实现这一目标, 机器需利用类别E的数据来实现成功任务, 并通过不断优化P来提升性能
spam. 让用户对邮件进行标签化处理(特别是针对垃圾邮件)属于E类任务,并将其标记为P类任务。
机器学习算法:
supervised learning
对于output我们有明确的理解,并期望通过input获得充足的标注信息以实现准确的结果预测。例如,在预测未来十年澳大利亚兔子种群数量变化趋势时, 我们希望得到的是一个具体的数值结果。
常见的是回归问题以及分类问题(需要注意的是分类问题不仅可以是二元(0,1)类别的),具体实例如癌症诊断中的肿瘤预测等
unsupervised learning
对于输入数据我们没有标签信息因此无法预判这些数据可能有多少个类别。例如对100篇论文进行分类分析同样无法预知这些论文可能被划分为多少类别唯一的可行方法是将具有相同关键词或其他相似特征的文章归为一类。其他相关领域的实例还包括基因测序技术等
cocktail party problem
在party中布置了两台话筒设备,分别用于主讲和副机,并且在设备旁边播放(BGM)音乐。如何操作电脑来实现将人声与(BGM)音乐区分开来呢?就可以利用无监督学习的方法。
others: reinforcement learning, recommender systems
线性回归
我们将数据分为两类:训练集和验证集
训练数据集被用来训练模型,并根据特定的评估标准(如交叉验证等)来选择合适的模型。而验证集则被用来评估其性能。
训练数据集被用来训练模型,并根据特定的评估标准(如交叉验证等)来选择合适的模型。而验证集则被用来评估其性能。
cost function
distance metric 是 fitted-observed 之间的差值计算方式, 通过最小化 cost function, 优化模型得以实现
m 为训练集数据个数,平方和是为了消除差之间的互相抵消。
以符号J(θ₀, θ₁)表示下述形式,并将其定义为squared error criterion;此指标被称为squared error criterion,在回归分析中最为常用作损失函数的指标
例子:对于简单一元线性回归 y = θ0+θ1x, J(0)就是y = 0

在简单的一元线性回归问题中,其左侧为模型h_θ(x),右侧对应的是目标函数J(θ₀, θ₁)。通过分析可以看出,在该凸函数最低点位置即存在目标函数J(θ₀, θ₁)的整体最小值点(即最佳拟合参数组)。一旦确定参数组θ₀和θ₁的具体数值,则可唯一确定最佳拟合模型h_�theta(x)。

注意:基于简单一元线性回归的独特性质,在优化目标函数J的情况下,J的整体最小值与局部最小值实际上是相同的,这属于特殊情况.通常我们在实际应用中只能找到一个局部极小点,如图所示,在右侧的位置就是整体最低点,然而我们的建模过程往往从左侧较高的位置开始,因此在神经网络领域这是一个显著的问题,这是因为初始点的选择通常是随机进行的

Gradient descent (不止用于线性回归)
commonly employed method for optimization. Once the gradient descent algorithm identifies the optimal solution, it ceases its search upon identifying the optimal solution. This is somewhat akin to a person who is so idle as to keep searching for better solutions all day and every day, but in reality, programs are more constrained, akin to someone who can be so carefree as to endlessly seek better solutions only within certain boundaries.
该算法类似于一个下山的过程。假设从左侧山顶出发,在红色方向向下滚动(此过程即为通过求导后从当前位置减去梯度与学习率的乘积—见公式)。在这里的学习率即代表每次迭代步长的大小;显然这样的成本更高)。同样地,在右侧山顶出发的话,则有可能抵达右侧的一个局部最优解;或者也可能抵达左侧另一个局部最优解(取决于行走的具体方向)。当然这些情况都需要较高的计算成本

这几个宛如狗爬的字是: repeat until convergence
α即是上文所述的学习率参数(learning rate)。为了保证优化过程的有效性,在选择学习率参数时必须格外谨慎。若选择过小,则可能导致优化进度缓慢甚至停滞不前;若选择过大,则可能造成迭代过程不稳定(嗯……试想一步跨得太远可能会错过最低点),最终在凸函数优化中容易陷入较大的误差状态。
值得注意的是,在这里区分两种不同的标识符:" := "与" = "代表不同的概念。其中" := "表示赋值操作符,在这种情况下" a := a + 1 "的意思是将" a + 1 "的结果赋值给变量" a ";而" = "则是用于比较运算符,在这种情况下" a = a + 1 "这样的等式在数学上是不可能成立的。
请注意,在这里θ₀和θ₁应该被同时更新。也就是说,在寻找优化解的过程中我们需要同时计算这两个参数的值。这与逐个单独处理其中一个并将其最优结果代入下一个参数来求取其最优解的方法是不同的。我们应当避免前者的做法以确保算法能够收敛到真正的优化解。

【上图是现抄课件,本人无版权,感谢coursera, 斯坦福和吴恩达爸爸,侵删】
Batch
Every time gradient descent operates, it employs all the training examples.
第二周 多元线性回归
如果要把model写成hθ(x)=θ^TX的话,x0=1
Feature Scaling
旨在确保各covariate之间的权重更为均衡。例如,在一组收入数据中(收入数据跨度从2,000至10,000),年龄数据仅覆盖2至3岁,在建模时容易导致收入权重对模型结果产生过大的影响;而实际上年龄才是主要的covariate变量。此外,在采用二次或更高阶模型时,特征缩放的作用变得更加显著:如图所示,在存在较大量纲差异的数据中(如图所示),其cost function往往呈现出不规则形状(如图所示),不利于梯度下降算法快速收敛至局部最优解;而将数据标准化至同一量级或相近范围,则能显著改善这一问题(如图所示)。

那么如何定义一个有效的特征缩放呢?并非越狭窄或越精确越好,在给定特征留出一定的灵活性是一个合理的选择。例如,在-1至+1之间是一个合理的选择,在-0.001至+0.001之间则显得过于狭窄;同样地,在-1至+1之间的选择也会带来一些限制。当然,并非所有的区间都需要对称性。
Mean Normalisation
用x-mean替代x,对x0=1无效。

P.S. 吴恩达爸爸好帅啊,声音好温柔~~~~花痴一下
确保gradient descent正确运行
(1)绘制一个J(θ)最小值随迭代次数变化的曲线图会更加直观。由于J(θ)表现出单调递减并最终收敛的特点,在图表中我们可以清晰地观察到其变化趋势。为了确定步长参数α是否过大或过小(类似于判断饥饿感或饱腹感),建议在范围[0.001,1]内进行尝试,并通过观察不同α值下的表现情况来选择最合适的一个。
(2)自动收敛检验:当J(θ)减少的程度低于设定的一个阈值C龙时(音译),迭代过程即被终止。然而确定一个合适的阈值并非易事因此他更倾向于通过图表来观察变化情况
例子:
对于下图左边两种情况,很可能是α太大了,一次跨的幅度太大

Normal Equation (思想应该是同statistical learning的GLS)

Octave: pinv() = inverse X' == x transfer
对于normal equation, feature scaling是不必要的
但是如果X^TX是不可逆的呢(singular/degenerate)?
(1) 造成不可逆的原因(这同时也是我们检查原因的顺序):
a. features高度相关,比如x和x^2
b. feature数量过多(例如feature的数量已超越数据规模),这种情况在学习过程中尚未遇到过, 应该是极为罕见的
i. 这里可以删掉一些features,
ii. 或者use regularization(之后会讲到)
**
**
Gradient Descent vs. Normal Equation
| Gradient Descent | Normal Equation |
|---|---|
| 需要选择α | 不需要选择α |
| 需要多次迭代 | 计算一次到位 |
| 当n很大的时候 also works well [当features太多(>=10000),吴恩达的选择] | 需要计算(XTX)-1 |
|---|---|
| 当n很大,收敛很慢 | |
| 适用范围更广 | 对linear regression效果很好 |
——n为features的数量,不是数据的数量(m)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------代码部分 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Octave command line
a = 3; %semicolon supressing output 不显示输出结果
~= 为不等号
xor(1,0)或门
c = (3>=1);
c =1 (True)
pi = π
a = pi 结果: a = 3.1416
a = pi; 结果:无输出
Octave 的print 很像C语言:
disp(sprintf('2 decimals: %0.2f', a)) 结果:2 decimals: 3.14
format long/short 显示不同位数
A[1 2; 3 4; 5 6] 注意用空格而不是逗号
v = 1:0.1:2 生成一个从1-2的差值为0.1的 11*1矩阵(第一二列都是1)
ones(2,3) 生成一个2*3的全为1的矩阵
zeros() 同理
rand(1,3)随机数(不过我觉得应该不是完全随机的,还是有seed的)
randn(2,3) 生成正态分布矩阵
sqrt(10)*randn(1,1000)就相当于R的rnorm(1000,sqrt(10))了
eye(4) 生成一个4*4的元矩阵
help eye 出解释
size(Matrix) 返回结果是一个[行 列]的 1*2矩阵
length(Matrix/Vector) 返回行数
pwd显示当前路径
常见命令与linux同
load featuresX,dat = load('featuresX.dat')
who 显示当前环境下的变量
whos 给出detail
clear featuresX 清除
save hello.mat v; 将变量v存放入环境hello.mat
save hello.txt v -ascii 将该文件以ASCII形式存储
A(2,3)第二行第三列
A(2,:)第二行
A(:,2)第二列
:与R的space同
A .*B 是A矩阵和B矩阵的每个element各自相乘(前提是AB矩阵维度相同)
A .^2 是A矩阵每个element各自平方(看来.?是用于矩阵element的专门的操作)
A' 转置
pinv(A) 逆矩阵
[val, ind] = max(a) 找出向量a中的最大值并给出其index
max(A) 会给出每一列中的最大值 = max(A,[],1) 每列最大值
max(A,[],2) 每行最大值
这里类似R用1表示列,2表示行
a = [1 15 2 0.5]
a <3
ans = 1 0 1 1
find(a <3)
ans = 1 3 4
A .* eye(9) 出去从左到右对角线保留,其余值全部为0
plot(x,y, 'r')——r 为红色
xlabel('') ylabel('') legend('','') title('')
这里能分别添加我觉得Octave是将这些变量全部存储然后保持运行
print -dpng 'myplot.png'存储
figure(1): plot(t,y1); 赋值,打开新窗口
clf; 清除所有figure
subplot(1,2,1); 把plot分割成1:2 grid, 获取第一个element
subplot(1,2,2);
——这两步合起来相当于 par(mfrow=c(1,2))
for i = 1:10,
v(i) = 2^i;
end;
while i <=5,
v(i) =100;
i = i+1;
end;
while true,
v(i) =999;
i = i+1;
if(i>10|| i ==10),
beark;
**end;
**
end; 注意两个end
addpath('') 添加路径,这样不在此路径下也可以使用function
Vectorization (能使代码运行快得多)
将连乘、连加等形式转化为矩阵的思维
比如

通常我会使用for循环逐个相加这些数值。然而,在这种情况下矩阵运算能够提供一个更为高效的方法来解决这个问题
cost function也可以这样处理
