机器学习
在本练习中,您将实现线性回归并开始查看它对数据的影响。在开始此编程练习之前,我们强烈建议您观看视频讲座并完成相关主题的评论问题。
要开始练习,您需要下载入门代码并将其内容解压缩到您希望完成练习的目录。如果需要,在开始本练习之前,请使用Octave / MATLAB中的cd命令切换到此目录。
您还可以在课程网站的\ Environment Setup Instructions中找到安装Octave / MATLAB的说明。
本练习中包含的文件
ex1.m - Octave / MATLAB脚本,引导您完成练习
ex1 multi.m - Octave / MATLAB脚本,用于练习的后续部分
ex1data1.txt - 用于线性回归的数据集,带有一个变量
ex1data2.txt - 用于线性回归的数据集,多个变量
submit.m - 将解决方案发送到我们服务器的提交脚本
[?] warmUpExercise.m - Octave / MATLAB中的简单示例函数
[?] plotData.m - 显示数据集的函数
[?] computeCost.m - 函数to计算线性回归的成本
[?] gradientDescent.m - 运行梯度下降的函数
[y] computeCostMulti.m - 多个变量的成本函数
[y] gradientDescentMulti.m - 多个变量的梯度下降
[y] featureNormalize.m - 函数规范化特征
[y] normalEqn.m - 计算正规方程的函数
?表示你需要完成
y表示可选练习
在整个练习中,您将使用脚本ex1.m和ex1 multi.m。这些脚本为问题设置数据集,并调用您要编写的函数。您无需修改其中任何一个。您只需按照此分配中的说明修改其他文件中的功能。
对于此编程练习,您只需完成练习的第一部分即可使用一个变量实现线性回归。练习的第二部分是可选的,涵盖了具有多个变量的线性回归。
本课程中的练习使用Octave或MATLAB,这是一种非常适合数值计算的高级编程语言。如果您没有安装Octave或MATLAB,请参阅课程网站的\ Environment Setup Instructions中的安装说明。
在Octave / MATLAB命令行中,键入help后跟函数名称将显示内置函数的文档。例如,帮助图将显示绘图的帮助信息。有关Octave函数的更多文档,请参见Octave文档页面。可以在MATLAB文档页面找到MATLAB文档。
我们还强烈建议您使用在线讨论与其他学生讨论练习。但是,不要查看其他人编写的任何源代码或与他人共享您的源代码。
ex1.m的第一部分为您提供Octave / MATLAB语法和作业提交过程的练习。在le warmUpExercise.m中,您将找到Octave / MATLAB函数的大纲。通过以下代码修改它以返回5 x 5单位矩阵:
A = eye(5);
当你完成后,运行ex1.m(假设你在正确的目录中,在Octave / MATLAB提示符下键入\ ex1),你应该看到类似于以下内容的输出:
ans =
Diagonal Matrix
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
现在ex1.m将暂停,直到您按任意键,然后将运行代码的下一部分。如果您想退出,键入ctrl-c将在运行过程中停止程序。
完成部分练习后,您可以通过在Octave / MATLAB命令行输入submit来提交解决方案以进行评分。提交脚本将提示您输入登录电子邮件和提交令牌,并询问您要提交哪些文件。您可以从网页获取作业的提交令牌。
您现在应该提交您的解决方案。
您可以多次提交您的解决方案,我们将仅考虑最高分。
在本练习的这一部分中,您将使用一个变量实现线性回归,以预测食品卡车的行为。假设您是一家餐厅特许经营店的首席执行官,并正在考虑开设新店。该连锁店已在各个城市拥有卡车,您可以获得来自城市的人员和人口数据。
您希望使用此数据来帮助您选择要扩展到下一个城市。
文件ex1data1.txt包含线性回归问题的数据集。第一列是一个城市的人口,第二列是该城市的食品卡车。收益的负值表示损失。
已经设置了ex1.m脚本来为您加载此数据。
在开始执行任何任务之前,通过可视化来了解数据通常很有用。对于此数据集,您可以使用散点图来显示数据,因为它只有两个要绘制的属性(pro t和population)。(在现实生活中你会遇到的许多其他问题都是多维的,无法在二维图上绘制。)在ex1.m中,数据集从数据文件加载到变量X和y中:
data = load('ex1data1.txt'); %读取逗号分隔数据
X = data(:, 1); y = data(:, 2);
m = length(y); %训练样例数
接下来,该脚本调用plotData函数以创建数据的散点图。你的工作是完成plotData.m绘制情节;用以下代码填充文件:
plot(x, y, 'rx', 'MarkerSize', 10); % 绘制数据
ylabel('Profit in $10,000s'); % 设置y-轴标签
xlabel('Population of City in 10,000s'); % 设置x-轴标签
现在,当你继续运行ex1.m时,我们的最终结果应如图1所示,具有相同的红色\ x“标记和轴标签。
要了解有关plot命令的更多信息,可以在Octave / MATLAB命令提示符下键入help plot,或在线搜索绘图文档。(要将标记更改为红色\ x“,我们将”rx“选项与绘图命令一起使用,即绘图(…,[选项],…,`rx’);)
图1:训练数据的散点图
在这一部分中,您将使用梯度下降将线性回归参数添加到我们的数据集中。
线性回归的目标是最小化成本函数
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta)=\frac{1}{2 m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2} J(θ)=2m1i=1∑m(hθ(x(i))−y(i))2
其中假设h(x)由线性模型给出
h θ ( x ) = θ T x = θ 0 + θ 1 x 1 h_{\theta}(x)=\theta^{T} x=\theta_{0}+\theta_{1} x_{1} hθ(x)=θTx=θ0+θ1x1
回想一下,模型的参数是j值。这些是您将调整以最小化成本J()的值。一种方法是使用批量梯度下降算法。在批量梯度下降中,每次迭代都执行更新
θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_{j} :=\theta_{j}-\alpha \frac{1}{m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) x_{j}^{(i)} θj:=θj−αm1i=1∑m(hθ(x(i))−y(i))xj(i)
随着梯度下降的每个步骤,您的参数j更接近将实现最低成本J()的最佳值。
实现注意:我们将每个示例作为一行存储在Octave / MATLAB的X矩阵中。为了考虑截距项(0),我们在X中添加了一个额外的第一列并将其设置为全部。这允许我们将0视为另一个“特征”。
在ex1.m中,我们已经设置了线性回归的数据。在以下行中,我们为数据添加另一个维度以容纳0截距项。我们还将初始参数初始化为0,将学习率alpha初始化为0.01。
X = [ones(m, 1), data(:,1)]; % 将一列添加到x
theta = zeros(2, 1); % 初始化拟合参数
iterations = 1500;
alpha = 0.01;
当您执行梯度下降以学习最小化成本函数J()时,通过计算成本来监视收敛是有帮助的。在本节中,您将实现一个计算J()的函数,以便检查渐变下降实现的收敛性。
您的下一个任务是完成le computeCost.m中的代码,这是一个计算J()的函数。在执行此操作时,请记住变量X和y不是标量值,而是矩阵表示训练集中的示例的矩阵。
完成该功能后,ex1.m中的下一步将使用初始化为零运行computeCost,您将看到打印到屏幕的成本。
您应该会看到32.07的成本。
您现在应该提交您的解决方案。
接下来,您将在le gradientDescent.m中实现渐变下降。已经为您编写了循环结构,您只需要在每次迭代中提供更新。
在编程时,请确保您了解要优化的内容和正在更新的内容。请记住,成本J()由向量参数化,而不是X和y。也就是说,我们通过改变向量的值来最小化J()的值,而不是通过改变X或y。如果您不确定,请参阅本讲义中的公式和视频讲座。
验证梯度下降是否正常工作的一种好方法是查看J()的值并检查它是否随每一步减少。gradientDescent.m的启动代码在每次迭代时调用computeCost并打印成本。
假设您已正确实现了梯度下降和computeCost,则J()的值不应该增加,并且应该在算法结束时收敛到稳定值。
完成后,ex1.m将使用您的nal参数绘制线性t。结果应如图2所示:
您的最终值也将用于对35,000和70,000人的区域进行预测。请注意ex1.m中以下行使用矩阵乘法而不是显式求和或循环来计算预测的方式。这是Octave / MATLAB中代码矢量化的一个例子。
您现在应该提交您的解决方案。
predict1 = [1, 3.5] * theta;
predict2 = [1, 7] * theta;
在实现梯度下降时,请记住以下几点:
?Octave / MATLAB数组索引从一开始,而不是零。如果将0和1存储在名为theta的向量中,则值将为theta(1)和theta(2)。
?如果在运行时看到许多错误,请检查矩阵运算以确保添加和乘以兼容维的矩阵。
使用size命令打印变量的大小将有助于您进行调试。
?默认情况下,Octave / MATLAB将数学运算符解释为矩阵运算符。这是大小不兼容错误的常见来源。如果你不想要矩阵乘法,你需要添加\ dot“表示法来指定它到Octave / MATLAB。例如,A * B做矩阵乘法,而A. * B做元素乘法。
图2:使用线性回归训练数据t
为了更好地理解成本函数J(),您现在将在0和1值的2维网格上绘制成本。您不需要为此部分编写任何新代码,但您应该了解您编写的代码是如何创建这些代码的。
在ex1.m的下一步中,有一些代码设置为使用您编写的computeCost函数在值网格上计算J()。
% 将J_val初始化为0的矩阵
J_vals = zeros(length(theta0 vals), length(theta1 vals));
% 填写J_vals
for i = 1:length(theta0_vals)
for j = 1:length(theta1_vals)
t = [theta0 vals(i); theta1_vals(j)];
J vals(i,j) = computeCost(x, y, t);
end
end
执行这些行后,您将拥有一个J()值的二维数组。然后,脚本ex1.m将使用这些值使用surf和contour命令生成J()的曲面图和等高线图。这些图应该类似于图3:
图3:成本函数J()
这些图的目的是向您展示J()如何随0和1的变化而变化。成本函数J()是碗形的并且具有全局最小值。(这在等高线图中比在3D表面图中更容易看到)。该最小值是0和1的最佳点,并且梯度下降的每个步骤都移近该点。
如果您已成功完成上述材料,恭喜!您现在了解线性回归,并且应该能够在您自己的数据集上开始使用它。
对于本次编程练习的其余部分,我们包括以下可选练习。这些练习将帮助您更深入地了解材料,如果您能够这样做,我们也鼓励您完成这些练习。
在这一部分中,您将使用多个变量实现线性回归来预测房屋价格。假设你在卖房子,你想知道什么是好的市场价格。实现这一目标的一种方法是首先收集有关最近出售房屋的信息,并制定住房价格模型。
le ex1data2.txt包含俄勒冈州波特兰市的一套房价培训。第一列是房子的大小(平方英尺),第二列是卧室的数量,第三列是房子的价格。
已设置ex1 multi.m脚本以帮助您逐步完成此练习。
ex1 multi.m脚本将首先加载并显示此数据集中的一些值。
通过查看值,请注意房屋大小约为卧室数量的1000倍。
当特征数量级达到数量级时,首次执行特征缩放可以使梯度下降更快地收敛。
您的任务是完成featureNormalize.m中的代码,
•以便从数据集中减去每个要素的平均值。
•减去平均值后,另外按特征值\标准偏差对特征值进行缩放(除法)。
标准偏差是一种测量特定特征值范围内变化程度的方法(大多数数据点位于平均值的2个标准差内); 这是取值范围(max-min)的替代方法。在Octave / MATLAB中,您可以使用\ std“函数来计算标准偏差。例如,在featureNormalize.m内,数量X(:,1)包含训练集中x1(房屋大小)的所有值, 所以std(X(:,1))计算房屋大小的标准差。在调用featureNormalize.m时,对应于x0 = 1的1的额外列尚未添加到X(有关详细信息,请参阅ex1 multi.m)。
您将对所有功能执行此操作,并且您的代码应适用于所有大小的数据集(任意数量的功能/示例)。注意,矩阵X的每列对应于一个特征。
您现在应该提交您的解决方案。
实现注意:在对特征进行标准化时,重要的是存储用于标准化的值 - 用于计算的平均值和标准偏差。在从模型中学习参数后,我们经常想要预测以前从未见过的房屋价格。给定一个新的x值(起居室面积和卧室数量),我们必须首先使用我们之前从训练集计算出的平均值和标准差来标准化x。
以前,您在单变量回归问题上实现了梯度下降。现在唯一的区别是矩阵X中还有一个特征。假设函数和批量梯度下降更新规则保持不变。
您应该完成computeCostMulti.m和gradientDescentMulti.m中的代码,以实现具有多个变量的线性回归的成本函数和梯度下降。如果上一部分(单个变量)中的代码已经支持多个变量,那么您也可以在此处使用它。
确保您的代码支持任意数量的功能并且矢量化良好。您可以使用“size(X,2)”来确定数据集中存在多少个要素。
您现在应该提交您的解决方案。
实现注意:在多变量情况下,成本函数也可以用以下矢量化形式编写:
J ( θ ) = 1 2 m ( X θ − y ⃗ ) T ( X θ − y ⃗ ) J(\theta)=\frac{1}{2 m}(X \theta-\vec{y})^{T}(X \theta-\vec{y}) J(θ)=2m1(Xθ−y)T(Xθ−y)
其中:
X = [ − ( x ( 1 ) ) T − − ( x ( 2 ) ) T − ⋮ − ( x ( m ) ) T − ] y ⃗ = [ y ( 1 ) y ( 2 ) ⋮ y ( m ) ] X=\left[\begin{array}{c}{-\left(x^{(1)}\right)^{T}-} \\ {-\left(x^{(2)}\right)^{T}-} \\ {\vdots} \\ {-\left(x^{(m)}\right)^{T}-}\end{array}\right] \quad \vec{y}=\left[\begin{array}{c}{y^{(1)}} \\ {y^{(2)}} \\ {\vdots} \\ {y^{(m)}}\end{array}\right] X=⎣⎢⎢⎢⎢⎡−(x(1))T−−(x(2))T−⋮−(x(m))T−⎦⎥⎥⎥⎥⎤y=⎣⎢⎢⎢⎡y(1)y(2)⋮y(m)⎦⎥⎥⎥⎤
当您使用Octave / MATLAB等数值计算工具时,矢量化版本很有用。如果您是矩阵运算专家,您可以向自己证明这两种形式是等价的。
在本练习的这一部分中,您将尝试针对数据集尝试不同的学习率,并确定快速收敛的学习率。您可以通过修改ex1 multi.m并更改设置学习速率的代码部分来更改学习速率。
ex1 multi.m中的下一个阶段将调用您的gradientDescent.m函数,并以所选学习速率运行梯度下降约50次迭代。该函数还应返回向量J中J()值的历史记录。在最后一次迭代之后,ex1 multi.m脚本将J值与迭代次数进行对比。
如果您选择了一个良好范围内的学习率,您的情节看起来类似于图4.如果您的图表看起来非常不同,特别是如果您的J()值增加甚至爆炸,请调整您的学习率并重试。我们建议在对数刻度上尝试学习率的值,乘法步长约为前一值的3倍(即0.3,0.1,0.03,0.01等)。如果可以帮助您查看曲线中的整体趋势,您可能还需要调整正在运行的迭代次数。
图4:具有适当学习率的梯度下降的收敛性
实现注意:如果你的学习速度太大,J()可能会发散并“爆炸”,从而导致数值太大而无法进行计算机计算。在这些情况下,Octave / MATLAB将倾向于返回NaN。NaN代表“不是数字”,通常是由涉及?1和+1的未定操作引起的。
Octave / MATLAB提示:为了比较不同的学习学习如何评估一个收敛,有助于在同一个图上绘制J的几个学习率。在Octave / MATLAB中,这可以通过在图之间使用“保持”命令多次执行梯度下降来完成。具体来说,如果您尝试了三个不同的alpha值(您应该尝试更多的值)并将成本存储在J1,J2和J3中,您可以使用以下命令在同一个gure上绘制它们:
plot(1:50, J1(1:50), `b');
hold on;
plot(1:50, J2(1:50), `r');
plot(1:50, J3(1:50), `k');
参数“b”,“r”和“k”为图表指定了不同的颜色。
注意学习率变化时收敛曲线的变化。学习率很小,你应该知道梯度下降需要很长时间才能收敛到最佳值。相反,在学习率很高的情况下,梯度下降可能不会收敛甚至可能发散!
使用您找到的最佳学习速率,运行ex1 multi.m脚本以运行梯度下降,直到收敛到nal的nal值。接下来,使用此值来预测1650平方英尺和3间卧室的房屋价格。稍后您将使用值来检查正常方程的实现。进行此预测时,不要忘记将功能标准化!
您无需为这些可选(未评级)练习提交任何解决方案。
在讲座视频中,您了解到线性回归的封闭形式解决方案
θ = ( X T X ) − 1 X T y ⃗ \theta=\left(X^{T} X\right)^{-1} X^{T} \vec{y} θ=(XTX)−1XTy
使用这个公式不需要任何特征缩放,你将在一次计算中得到一个精确的解决方案:没有\ loop直到收敛“就像在梯度下降。
完成normalEqn.m中的代码以使用上面的公式进行计算。请记住,虽然您不需要扩展功能,但我们仍需要在X矩阵中添加1列,以获得截距项(0)。ex1.m中的代码会为您添加1的列到X.
您现在应该提交您的解决方案。
可选(未评级)练习:现在,一旦你找到使用这种方法,用它来预测一个1650平方英尺的房子,有3间卧室。您应该得到与使用具有梯度下降的模型t获得的值相同的预测价格(在第3.2.1节中)。
完成任务的各个部分后,请务必使用提交功能系统将您的解决方案提交给我们的服务器。以下是对此练习的每个部分进行评分的细分。
部分 | 提交的文件 | 分数 |
---|---|---|
热身练习 | warmUpExercise.m | 10点 |
计算一个变量的成本 | computeCost.m | 40点 |
一个变量的梯度下降 | gradientDescent.m | 50个点 |
总点数 | 100点 |
可选练习
部分 | 提交的文件 | 点 |
---|---|---|
特征规范化 | featureNormalize.m | 0分 |
计算 多个变量的成本 | computeCostMulti.m | 0个点 |
多个变量的梯度下降 | gradientDescentMulti.m | 0个点 |
正规方程 | normalEqn.m | 0个点 |
您可以多次提交解决方案,我们只考虑最高分数。