本次练习对应的基础知识总结 → \rightarrow →线性回归。
本次练习对应的文档说明和提供的MATLAB代码 → \rightarrow → 提取码:wg3s 。
在本次练习的单变量线性回归这一部分中,我们将使用一个变量实现线性回归,以预测食品卡车的利润。假设你是一家餐饮连锁店的首席执行官,并且正在考虑在不同的城市开设新的门店。该连锁店已经在各个城市开了新的分店,并且你有城市的利润和人口数据。你想使用此数据来帮助你选择要扩展到的下一个城市。 文件ex1data1.txt包含我们线性回归问题的数据集。第一列是城市的人口,第二列是该城市的餐车的利润,利润的负值表示亏损。已经设置了ex1.m脚本来加载此数据。
在开始任何任务之前,通过可视化了解数据通常很有用。对于题目中给的数据集,可以使用散点图来可视化数据,因为它只有两个属性可以绘制(利润和人口)。 在ex1.m中,数据集从数据文件加载到变量X和y中:
data = load('ex1data1.txt'); % read comma separated data X = data(:, 1); y = data(:, 2); m = length(y); % number of training examples接下来,脚本调用plotData函数创建数据的散点图。我们需要完成plotData.m绘制图,修改文件并填写以下代码:
plot(x, y, 'rx', 'MarkerSize', 10); % Plot the data %MarkerSize 表示点的大小,rx表示红色的叉 ylabel('Profit in $10,000s'); % Set the y−axis label xlabel('Population of City in 10,000s'); % Set the x−axis label当继续运行ex1.m时,最终结果应如图1所示,带有相同的红色“ x”标记和轴标签。
图1 训练数据散点图在这一部分中,我们将使用梯度下降将线性回归参数 θ 拟合到我们的数据集中。
线性回归的目标是最小化代价函数 J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta)=\frac{1}{2m}\sum_{i=1}^{m} (h _{\theta}(x^{(i)})-y^{(i)})^{2} J(θ)=2m1i=1∑m(hθ(x(i))−y(i))2
假设函数 h θ ( x ) hθ(x) hθ(x)由线性模型 h θ ( x ) = θ T x = θ 0 + θ 1 x h_{\theta }(x)=\theta ^{T}x=\theta _{0}+\theta _{1}x hθ(x)=θTx=θ0+θ1x 给出。 模型的参数 θ j \theta _{j} θj是需要被调整,从而使代价 J ( θ ) J(θ) J(θ)最小化的值。一种方法是使用批处理梯度下降算法(batch gradient descent algorithm)。在批次梯度下降中,每次迭代都会执行更新 θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) ( s i m u l t a n e o u s l y u p d a t e θ j f o r a l l j ) \theta _{j}:=\theta _{j}-\alpha \frac{1}{m}\sum_{i=1}^{m} (h _{\theta}(x^{(i)})-y^{(i)})x_{j}^{(i)} \ _{}\ _{} (simultaneously\ _{}\ _{}update\ _{}\ _{}θ_{j}\ _{}\ _{}for\ _{}\ _{}all\ _{}\ _{}j) θj:=θj−αm1i=1∑m(hθ(x(i))−y(i))xj(i) (simultaneously update θj for all j)
随着梯度下降的每一步,参数 θ j θ_{j} θj将接近最佳值,从而实现代价 J ( θ ) J(θ) J(θ)的最低。
在ex1.m中,我们已经设置了用于线性回归的数据。在下面的几行中,考虑到截距项 θ 0 θ_{0} θ0,我们在数据中添加另一个维度。我们还将初始参数初始化为0,将学习率 α α α初始化为0.01。
X = [ones(m, 1), data(:,1)]; % Add a column of ones to x theta = zeros(2, 1); % initialize fitting parameters iterations = 1500; alpha = 0.01;当我们执行梯度下降来最小化代价函数 J ( θ ) J(θ) J(θ)时,通过计算代价来监控收敛是有帮助的。在本节中,我们将实现一个计算 J ( θ ) J(θ) J(θ)的函数,以便可以检查梯度下降实现的收敛性。 我们的下一个任务是完成文件computeCost.m中的代码,该文件是一个计算 J ( θ ) J(θ) J(θ)的函数。 完成computeCost.m时需要填写以下代码:
h = X*theta - y; J = 1/(2*m) * sum(h.^2);一旦完成该函数,ex1.m中的下一步将使用初始化为零的 θ θ θ运行一次calculateCost,然后我们将看到打印在屏幕上的成本,应该为32.07。 运行ex1.m得到的结果如下:
With theta = [0 ; 0] Cost computed = 32.072734 Expected cost value (approx) 32.07 With theta = [-1 ; 2] Cost computed = 54.242455 Expected cost value (approx) 54.24接下来,我们将在gradientDescent.m文件中实现梯度下降。题目给出的代码中已经编写了循环结构,我们只需要在每次迭代中为 θ θ θ提供更新。 在编程时,要明确代价 J ( θ ) J(θ) J(θ)是由向量 θ θ θ而不是 X X X和 y y y来参数化。 验证梯度下降是否正常工作的一种好方法是查看 J ( θ ) J(θ) J(θ)的值,并检查其每一步是否在减小。 gradientDescent.m的起始代码在每次迭代时都调用computeCost并打印成本。如果我们正确实现了梯度下降和computeCost,则 J ( θ ) J(θ) J(θ)的值将永远不会增加,并且应在算法结束时收敛为稳定值。 完成gradientDescent.m时需要填写以下代码:
theta = theta - alpha/m*X'*(X*theta - y);完成后,ex1.m将使用最终参数来绘制线性拟合。结果如图2所示。 θ θ θ的最终值还将用于预测35,000和70,000人区域的利润。
图2 线性回归拟合的训练数据利用使代价 J ( θ ) J(θ) J(θ)最小时的 θ θ θ来预测35,000和70,000人区域的利润,结果如下所示:
For population = 35,000, we predict a profit of 2913.325861 For population = 70,000, we predict a profit of 44607.163473为了更好地理解代价函数 J ( θ ) J(θ) J(θ),我们将在 θ 0 θ_{0} θ0和 θ 1 θ_{1} θ1的二维网格值上绘制代价函数曲线。在ex1.m的下一步中,设置了使用我们之前编写的computeCost函数在网格值上计算 J ( θ ) J(θ) J(θ)的代码。
% initialize J vals to a matrix of 0's J vals = zeros(length(theta0 vals), length(theta1 vals)); % Fill out 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 ( θ ) J(θ) J(θ)值的二维数组。然后,脚本ex1.m将使用这些值通过surface 和 contour 命令生成 J ( θ ) J(θ) J(θ)的曲面和等高线图,如图3所示。
图3 代价函数 J ( θ ) J(θ) J(θ)这些图的目的是向我们展示 J ( θ ) J(θ) J(θ)如何随 θ 0 θ_{0} θ0和 θ 1 θ_{1} θ1的变化而变化。代价函数 J ( θ ) J(θ) J(θ)是碗形的,并且具有全局最小值。该最小值是 θ 0 θ_{0} θ0和 θ 1 θ_{1} θ1的最佳点,并且梯度下降的每一步都在靠近该点。
在这一部分中,我们将使用多个变量实现线性回归以预测房屋价格。假设你正在出售房屋,并且想知道一个好的市场价格。一种方法是首先收集最近有关出售房屋的信息,并建立房屋价格模型。 文件ex1data2.txt包含某地区房屋价格的训练集。第一列是房屋的大小(以平方英尺为单位),第二列是卧室的数量,第三列是房屋的价格。 已经设置了ex1_multi.m脚本来帮助我们逐步完成此练习。
ex1_multi.m脚本将首先从此数据集中加载并显示一些值。通过查看这些值,可以发现房屋大小约为卧室数量的1000倍。当特征相差一个数量级时,首先执行特征缩放可以使梯度下降收敛更快。 我们的任务是完成featureNormalize.m中的代码,首先从数据集中减去每个要素的平均值,减去平均值后,然后再将特征值除以它们各自的“标准偏差”。 完成featureNormalize.m时需要填写以下代码:
for i=1:size(X,2) mu(i)=mean(X(:,i));%求X每一列的均值 sigma(i)=std(X(:,i));%求X每一列的标准差 X_norm(:,i)=(X_norm(:,i)-mu(i))/sigma(i); %归一化处理X=(X-mean)/standard deviation end之前我们是在单变量回归问题上实现梯度下降的,现在唯一的区别是矩阵 X X X中有多于一个的特征,假设函数和批量梯度下降更新规则保持不变。我们应该在computeCostMulti.m和gradientDescentMulti.m中完成代码,以实现具有多个变量的线性回归的成本函数和梯度下降。 完成computeCostMulti.m时需要填写以下代码:
J = 1/(2*m) * (X*theta - y)'* (X*theta - y);完成gradientDescentMulti.m时需要填写以下代码:
theta = theta - alpha/m*X'*(X*theta - y);运行ex1_multi.m可以得到 α = 0.1 α=0.1 α=0.1时的梯度下降收敛如图4所示。
图4 学习率为 α = 0.1 α=0.1 α=0.1时的梯度下降收敛学习率为 α = 0.1 α=0.1 α=0.1时得到的最优参数 θ θ θ和预测1650平方英尺、3间卧室的房屋售价结果如下:
Running gradient descent ... Theta computed from gradient descent: 340412.659574 110631.050279 -6649.474271 Predicted price of a 1650 sq-ft, 3 br house (using gradient descent): $293081.464335我们还可以通过修改ex1_multi.m并更改设置学习率的代码尝试不同的学习率,并找到快速收敛的学习率。建议以对数刻度尝试学习率 α α α的值,常取的值有0.3、0.1、0.03、0.01等。
通过求解,我们可以得到正规方程的解为 θ = ( X T X ) − 1 X T y \theta=(X^{T}X)^{-1}X^{T}y θ=(XTX)−1XTy 。 使用此公式不需要任何特征缩放,并且我们将在一次计算中获得确切的解决方案:在梯度下降中没有“直到收敛”的循环。完成normalEqn.m中的代码以使用以上公式计算 θ θ θ。需要注意的是虽然无需缩放特征,但我们仍然需要在 X X X矩阵中添加一列1元素使得具有截距项( θ 0 θ_{0} θ0)。 完成normalEqn.m时需要填写以下代码:
theta = inv(X'*X)*X'*y;使用正规方程在学习率为 α = 0.1 α=0.1 α=0.1时得到的最优参数 θ θ θ和预测1650平方英尺、3间卧室的房屋售价结果如下:
Solving with normal equations... Theta computed from the normal equations: 89597.909543 139.210674 -8738.019112 Predicted price of a 1650 sq-ft, 3 br house (using normal equations): $293081.464335可以发现使用梯度下降和正规方程得到的最优参数 θ θ θ虽然有所不同,但是和预测1650平方英尺、3间卧室的房屋售价结果是相同的。