斯坦福机器学习(1-3)
大概3年前,自己写了一个聊天机器人起,对计算机技术产生了兴趣。过去三年一直在学一些计算机的基本功。现在到了一家需要算法的公司,那么也算回到自己的初心,现在开始再续前缘。
目前的计划是20年的最后2个月把吴恩达老师的机器学习和深度学习都过一遍。
这篇博客是为了自己日后复习使用,所以如果没看过课的小伙伴直接阅读可能会读不懂。
第一周知识点
什么是监督学习,非监督学习
监督学习-回归,分类
非监督学习-聚类,非聚类。
什么是代价函数
机器学习的本质,是找到一个预测模型,这个模型可以是一个复杂的函数,也可以是个简单的线性函数。那么我们通过很多的数据去训练,本质上就是要知道这个函数的系数是怎么样的。
训练的本质,就是找到最合适的系数使得它离我们给的数据的偏差最小。
这边这个偏差就是机器学习中的代价函数的意义。
我们在第一周的作业里用的梯度下降就是在最小化这个代价函数J
image.png
这里的损失函数的目标,就是使得模型的预测值和真实值尽可能的一样。所以有如上式子,除以的系数是为了在之后梯度求导的时候方便,其实并不影响其他。
什么是梯度下降
下图是函数系数和代价函数的关系。我们可以看出,我们每次朝着该图的切面方向走,可以最快的走到谷底,就是代价函数的最低点。
我们可以一开始随意的设定当前的位置就是任取2个THETA,随后每次微调,直到走到最低点。
这里面有个步伐大小的选择,这里是个步子太大跨过最低点和步子太小算的很慢之间的trade off。
如何算出微调值呢?
这个就是对代价函数求偏导得到。
image.png
有了上述的知识,我们就可以攻克掉第一周的作业。
tmp = theta;
for j = 1:length(theta)
tmp(j) = tmp(j) - sum((X * theta - y) .* X(:,j)) * alpha / m;
end
theta = tmp;
这里要记得同时更新好所有的theta,不要用算到一般的theta去计算下一层的theta,会有问题。
那么在算误差的时候,式子也十分直接。
inner = ((X * theta) - y) .^ 2;
J = sum(inner) / (2 * m);
第二周知识点
特征归一
我们的初始数据有些开始会很大,有些开始会很小。为了不让过大的数据占主导因素。我们需要对所有特征做归一化或者标准化处理。这样可以更好的加速梯度下降算法。
image.png
如果你对处理后的数据范围有严格要求,那肯定是归一化,个人经验,标准化是ML中更通用的手段,如果你无从下手,可以直接使用标准化;如果数据不为稳定,存在极端的最大最小值,不要用归一化。在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,标准化表现更好;在不涉及距离度量、协方差计算的时候,可以使用归一化方法。
细心的小伙伴发现了,如果数据分布是无法用一条直线来完美拟合该怎么办呢
这里就需要用到多项式回归,我们可以通过引入更多的高次项系数去组合。
这样的函数可以有更好的任意性,而不像线性函数只能是一条直线。它带来的问题是,引入了更多的特征,并且如果数据量不大的话,可能会有过拟合的问题。
另外就像菲波那切数列一样,我们可以用迭代的方法去求得,当然也有公式法可以一步到位。
有些情况下,我们可以使用公式法,直接找到斜率为0的位置。从而一步到位得到最小的系数. 还有一个优势是不用标准化特征。
image.png
公式为
theta = pinv(X' * X) * X' * y
如果发现矩阵没有逆的话?
一般有2种解法
- 当特征向量的维度过多时(如,m <= n 时)
- 有冗余的维度,比如一个特征用了米,一个特征用了厘米
第三周知识点
这周我们来到了分类问题,也就是用一个函数区分这个数据是A类还是B类。
- 邮件是垃圾邮件还是非垃圾邮件;
- 网上交易是的欺骗性(Y or N);
- 肿瘤是恶性的还是良性的。
理解用线性回归为何不适合这种训练
那么为了解决分类问题,这里引入了sigmoid的函数,是可以把所有值都映射进0到1的一个函数。
image.png
这里如果用了线性回归中的代价函数,则会用函数非突,造成梯度下降只能得到局部最小。为了解决这个问题,这里也引入了新的代价函数。
image.png
了解分类问题的三种高级优化方法-共轭梯度,BFGS, L-BFGS
多分类问题,可以转变化K个分类问题,随后取概率最高的那类
解决过拟合的手段:
- 减少特征数量。 2. 正则化
知道过拟合,欠拟合 和 lambda的关系
如果要在正规方程里,求解正则化的方程下的系数
image.png
那么第三周的作业点,其实就是实现分类下的代价函数和梯段下降算法。其中作业里的框架已经帮你搭建好了。
我们只需要分别实现不带正则化的部分,和加上正则化的部分。再加上一行如何使用模型的代码即可。
下面是用正则化去求代价函数和梯队的方法。
grad = ones(size(theta)) * lambda;
h = sigmoid(X * theta); % 100, 1
theta(1) = 0;
tmp = lambda / (2 * m) * (theta' * theta);
J = tmp + (y' * log(h) + (1 - y)' * log(1 - h)) / -m;
grad(1) = 0;
grad = (grad .* theta + X' * (h - y)) / m;
总结
在前3周的学习中,我们掌握了回归和分类的监督机器学习算法。
了解到,我们需要给出特征,然后根据这些特征去在大量数据下求出最优的系数。最优就是这些系数使得数据和预测模型间的误差最小。
那么误差的算法就是代价函数,我们多次在作业中实现。
另外为了找到最优,我们会使用梯度下降的算法,这样我们需要对代价函数求关于theta的偏导,那么也就是我们在作业里多次实现的grad
有了这2个值,我们可以自己实现迭代的梯度下降,自己选取学习率
for iter = 1:num_iters
tmp = theta;
for j = 1:length(theta)
tmp(j) = tmp(j) - sum((X * theta - y) .* X(:,j)) * alpha / m;
end
theta = tmp;
J_history(iter) = computeCostMulti(X, y, theta);
end
也可以用函数库来帮我们找到最优的学习率的高级梯度下降算法。
initial_theta = zeros(size(X, 2), 1);
% Set regularization parameter lambda to 1 (you should vary this)
lambda = 1;
% Set Options
options = optimset('GradObj', 'on', 'MaxIter', 400);
% Optimize
[theta, J, exit_flag] = ...
fminunc(@(t)(costFunctionReg(t, X, y, lambda)), initial_theta, options);
最后我们会得到一组在特征值上的theta,然后可以用它来为我们未来的数据做预测。
p = round(sigmoid(X * theta));
除了上述的基本功之外,我们还掌握了归一化标准化的优化技巧。以及解决过拟合的正则化技巧。
mu = mean(X)';
sigma = std(X)';
for i = 1:length(mu)
X_norm(:,i) = (X(:,i) - mu(i)) / sigma(i);
end