65.9K
CodeProject 正在变化。 阅读更多。
Home

机器学习 - 梯度下降

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.99/5 (40投票s)

2017年7月11日

CPOL

8分钟阅读

viewsIcon

74742

downloadIcon

740

学习机器学习和基于线性回归的梯度下降的基础知识的最佳实践。本文将逐步解释计算过程。

什么是机器学习

我决定准备并以一个有价值且在互联网上可能独一无二的系列来讨论机器学习算法。我声称,很少有资源能做到既简单又完整地讲解机器学习。

我想通过低级解释来阐述机器学习中的算法是如何工作的,而不是仅仅一瞥高层概念。我相信这种方式可以拓宽我们的视野,并为我们正确应用它们做好准备。因为对漂亮的算法只有高层次的、肤浅的理论是毫无用处的,反之,如果我们知道这些算法底层发生了什么,就能帮助我们更恰当地使用它们。

为了更好地理解机器学习,我先简单介绍一下机器学习的整个故事。

机器学习是计算机科学的一个分支,它从模式识别和人工智能中扩展而来。它的含义源于计算机能够借助训练数据(即过去发生的样本数据)来学习预测现象,并通过特定条件来预测事件的结果。这种学习过程有两种不同的方式,一种是监督学习,另一种是无监督学习。

监督学习就像在老师的指导下教孩子们识字,而无监督学习就像孩子通过反复试验独自尝试走路,他会明白如何正确地行走。更具体地说,在监督学习中,我们倾向于对物体进行分类;而在无监督学习中,我们实际上并不知道我们在寻找什么,我们只是研究和观察一些物体,并尝试根据它们的相似性将它们聚类。

分类

分类 – 监督学习:假设一位父亲向他的儿子展示一只狗,然后如果儿子看到另一品种的狗,他就能认出这是一只狗,尽管品种不同。目标很明确:儿子看到一些狗,他父亲告诉他“这是狗”,然后他将来就能识别出狗——即使颜色、品种或大小不同。

聚类

聚类 – 无监督学习:但现在情况不同了,一位父亲带儿子去动物园,给他看各种动物,但没有告诉他它们的名称。所以他儿子只能在脑海中根据颜色、大小等对各种动物进行分类。如果将来他看到一种动物,它与他在动物园笼子里看到的某种动物相似,他就能说“这种动物——虽然我不知道名字——与我在动物园看到的那些动物相似。”所以这里的目标是让儿子将新动物与他现在看到的其他动物进行聚类。

监督学习有 f(X) = y,并且每个特征都有对应的值;而在无监督学习中只有 (X),而不知道其 f(X)。

结果:因此,最终我们会遇到两种不同类型的问题需要解决

监督学习 – 分类:根据过去的数据,其中有一个特定的输出值——目标变量或因变量,称为“Y”,对应一个或多个特征或自变量,称为“X”或“X1, X2, …., Xn”。例如,有一组患者信息数据,我们想知道患者是否会患癌症;或者根据过去的价格变化,预测某个物体在不久的将来的价格。

线性回归

在某些问题中,我们对“Y”的值没有限制,例如价格预测;但在其他问题中,例如当我们想知道一名患者患癌症的概率时,我们必须给出一个介于零和一之间的结果。

  • Y = aX + b
  • Y 是目标值,因变量,输出
  • a 是回归系数,斜率
  • X 是自变量,特征,输入
  • b 是常数

我决定让一切都遵循 KISS 原则 = 保持简单愚蠢 (Keep It Simple Stupid)

因此,我自行设计了一个小数据集,我们可以轻松地进行学习,然后您可以访问我的 github,根据斯坦福大学安德鲁·吴(Andrew NG)的机器学习课程的真实教程数据集进行学习。单击此处了解有关该课程的更多信息。

这个数据集基于学生的学习时间和他们取得的成绩之间的关系。我们根据上述数据绘制一张图表,并将学习时间分配给横轴,成绩分配给纵轴。您会看到一个学生学习时间越长,他就能取得更好的成绩。因此,查看这张图表后,我们想预测如果一个学生学习 8 小时,他的成绩会是多少?

梯度下降

我们需要一条蓝色线来确定成绩随学习时间变化的趋势。Y 和 X 是数据集值,我们只需要 a、b 值来绘制蓝色线或“预测线”。无论我们多么精确,有时都无法避免或很难在没有误差的情况下绘制预测线。机器学习中的误差率是不可避免的;但我们应该找到最佳的 a、b 并最小化误差率以获得准确的输出。

实际值(黑星)与蓝色线上的预测值(黄星)之间的垂直距离称为“预测误差”或“成本”。为了计算预测误差;我们必须减去预测误差 = Y实际 – Y预测,其中 Y预测 = aX + b

由于数据集中有多个记录,我们需要将上述公式推广为

平方误差和 (SSE) = ½ 求和 (Y实际Y预测)2

但我们需要尽可能地最小化 SSE,我们在高中数学中学过,应该对公式进行微分使其最优。因为我们有两个变量,所以需要两次微分。因为我们处理的是 a 和 b,所以需要进行偏微分。在基于“a”的偏微分中,SSE 中的其他变量如“X”、“Y”和“b”应保持不变。

在深入研究上述数据集之前,我们需要对值进行标准化——归一化或缩放,以便具有相同的范围和/或方差。因为学习时间在 (2,7) 之间,而成绩在 (50,70) 之间,所以它们的尺度存在差异,这使得比较它们变得困难。

第一步是根据 Ө = [a, b] 计算“成本函数”,这些“a”和“b”是我们随机选择的值。

  1. 随机选择 Ө = [a, b],a 为斜率,b 为截距。
  2. 计算“成本函数”。
  3. 计算 Ө = [a, b] 的“梯度下降”。
    1. a = a - r*∑ ∂SSE/∂a,r 是学习率
      • ∂SSE/∂a = -(Y-Yp)X
    2. b = b - r*∑ ∂SSE/∂b
      • ∂SSE/∂b = -(Y-Yp)
  4. 再次计算“成本函数”成本函数
  5. 比较新的成本函数值是否小于之前的值;如果“是”,则方向正确,继续。
  6. 重复步骤 3 至 5,直到找到最佳值。

** r 是学习率,即学习的速度,成本函数应该在每次迭代中递减并收敛。如果每次重复使用不同的 a、b 时成本函数都下降,那么我们就选择了合适的 r。

使用 MATLAB 代码

我使用的是 MATLAB R2012a (7.17.0.739)

1. 开始调用函数 "executegd.m";

首先是 "executegd.m",我从这里调用了所有函数。在第一部分,我从 *data.txt* 加载了非常简单的文本数据。然后,我使用上面提到的公式对数据进行了标准化。然后,我根据新的坐标绘制了点。然后,我假设 a=0,b=0,计算了“成本函数”,然后我开始使用“梯度下降”和学习率为 r=0.01,迭代 1500 次来计算最佳的 a、b。

clear ; close all; clc

%% ======================= Part 1: Load Data ==============================
% Load Data
fprintf('Plotting Data ...\n')
data = load('data.txt');

%% ======================= Part 2: Standardize Data =======================
% Standardize Data
data = standardizeData(data);
X = data(:, 1);
y = data(:, 2);
m = length(y); % number of training examples

%% ======================= Part 3: Plotting ===============================
% Plot Data
plotData(X, y);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% =================== Part 4: Prediction Error - Copmute Cost ============
fprintf('Running Gradient Descent ...\n')

X = [ones(m, 1), data(:,1)]; % Add a column of ones to x
theta = zeros(2, 1); % initialize fitting parameters

% Some gradient descent settings
iterations = 1500;
alpha = 0.01;

% compute and display initial cost
predictionError(X, y, theta)

%% =================== Part 5: Gradient descent ===========================
% run gradient descent
theta = gradientDescent(X, y, theta, alpha, iterations);

% print theta to screen
fprintf('Theta found by gradient descent: ');
fprintf('%f %f \n', theta(1), theta(2));

% Plot the linear fit
hold on; % keep previous plot visible
plot(X(:,2), X*theta, '-')
legend('Training data', 'Linear regression')
hold off % don't overlay any more plots on this figure

2. 标准化 "standardizeData.m"

function [stdata] = standardizeData(data)
%Standardize Data

X = data(:, 1);
Y = data(:, 2);
m = length(Y); % number of training examples
stdata = zeros(m, 2); % initialize fitting parameters

% StdDev = SQRT( sum[(X-mean)^2/(n-1)]  )
meanX = mean(X);
stdX = std(X);

for i = 1:m
   
    X(i) = ((X(i) - meanX)/stdX);
end

%Standardize(X) = X-mean /Std(X)

meanY = mean(Y);
stdY = std(Y);

for i = 1:m
   
    Y(i) = ((Y(i) - meanY)/stdY);  
end

 stdata(:, 1)= X(:);
 stdata(:, 2)=Y(:);

3. 绘图 "plotData.m"

function plotData(x, y)

figure; % open a new figure window

plot(x,y,'rx','MarkerSize',10);
ylabel('Profit');
xlabel('Population');

end

然后你应该点击“Enter”。

4. 计算“成本函数” "predictionError.m"

function J = predictionError(X, y, theta)
%COMPUTECOST Compute cost for linear regression
%   J = COMPUTECOST(X, y, theta) computes the cost of using theta as the
%   parameter for linear regression to fit the data points in X and y

% Initialize some useful values

m = length(y); % number of training examples
%theta = zeros(2, 1); % initialize fitting parameters

% You need to return the following variables correctly

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta
%               You should set J to the cost.

J=1/(2*m)*sum((X*theta - y).^2);

% =========================================================================

end

5. 计算 theta(a, b),它通过梯度下降构建了最佳预测线,"gradientDescent.m"

function [theta] = gradientDescent(X, y, theta, alpha, num_iters)
%GRADIENTDESCENT Performs gradient descent to learn theta
%   theta = GRADIENTDESENT(X, y, theta, alpha, num_iters) updates theta by
%   taking num_iters gradient steps with learning rate alpha

% Initialize some useful values
%m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

m = length(y); % number of training examples

for iter = 1:num_iters

    if iter == 1
        J_history(iter) = predictionError(X, y, theta);
 
    elseif iter > 1
        A=X(:,2);
        B=-(y-(X*theta));
        C=B'*A;

        DefSSEb = sum(B);
        DefSSEa = sum(C);

        bold=theta(1,1);
        aold=theta(2,1);

        theta(1,1) = (bold - (alpha*(DefSSEb/m)));
        theta(2,1) = (aold - (alpha*(DefSSEa/m)));

        J_history(iter) = predictionError(X, y, theta);
   end
 
end

theta = theta(:);
end

关注点

我发现机器学习非常令人兴奋,我决定从事这项工作。

梯度下降是学习机器学习的第一步,也是最重要的一步。正如总结的那样,机器学习就是“获取数据并处理数据,然后返回结果,这就是它的预测”。

因此,100% 会发生误差,目标是使用机器进行预测——由于数据庞大,机器可以更快地做到这一点——但通过观察误差并尝试通过梯度下降来选择更好的预测。

梯度下降的故事在线性回归(只有一个 X)中不会在这里结束,你将在多变量和神经网络中遇到它。

最后,我强烈建议您在 coursera.org 注册机器学习课程

& 使用我的 github 作为作业指南

反馈

欢迎您随时对本文发表任何反馈;很高兴看到您的意见和对本代码的投票。如果您有任何问题,请随时在此处向我提问。

© . All rights reserved.