山东大学机器学习(实验一内容)——线性回归
1. 描述
初始练习将包含线性回归练习。
这些练习已经被系统地用Matlab进行了广泛测试。
但它们也应该在Octave环境中运行,并称为'免费版的Matlab'。
如果有人选择使用Octave作为开发环境,则需要安装Image处理包(其中在Windows系统上可以选择此选项)来执行相关操作。
该软件包可通过官方网站上的Octave Forge获取Linux版本。
2.线性回归
回顾一下
3. 2D线性回归
我们从一个极为简单的案例入手,在其中n = 1.首先下载data1.zip文件,并解压其中的ex1x.dat和ex1y.dat文件。这些数据集记录了多个不同年龄儿童的身高测量数据(单位:米),样本涵盖了从两岁到八岁的男孩群体。每个样本由特定年龄x^{(i)}与其对应的身高y^{(i)}组成,在我们的数据集中共有50个这样的训练样本。通过建立线性回归模型(基于梯度下降算法),我们可以预测不同年龄下的儿童身高,在Matlab或Octave环境中运行时,默认情况下会加载并处理这些训练数据。
x = load ( ' ex1x . dat ' ) ;
y = load ( ' ex1y . dat ' ) ;
该系统将负责我们专门用于n=1的监督学习任务的训练集功能(除x₀=1外的所有输入样本x均属于二维实数空间R²)。 为了帮助您更好地操作Matlab / Octave软件包,请运行以下代码以生成并可视化您的训练数据集(并标注坐标轴)
figure % open a new figure window
plot (x , y , ' o ' ) ;
ylabel ( ' Height in meters ' )
xlabel ( 'Age in years ' )
您应该看到一系列类似于图1的数据点。

绘制数据
在执行梯度下降之前,在每个示例中添加x_0=1作为截距项。 在Matlab或Octave中进行该操作时,请使用命令
m = length ( y ) ; % store the number of training examples
x = [ ones (m, 1 ) , x ] ; % Add a column of ones to x
从这一点开始,从这一点开始,您需要记住训练数据中的年龄值实际上位于x的第二列。 这在以后绘制结果时很重要。
我们为这个问题实现了线性回归。 线性回归模型在这种情况下是
h_{\theta}(x) = \theta^Tx=\sum_{i=0}^1 \theta_i x_i = \theta_0+ \theta_1x_1
(1)使用\alpha = 0.07的学习率实施梯度下降。初始化参数\theta = \vec{0}(i.e.,\theta_0 = \theta_1 = 0),并从该初始起点开始一次梯度下降迭代。 记录第一次迭代后得到的\theta_0和\theta_1的值。
(2)继续运行梯度下降以进行更多迭代,直到\theta收敛为止(这将总共需要大约1500次迭代)。收敛后,记录你得到的最终值\theta_0和\theta_1,根据\theta,将你的算法中的直线绘制在与训练数据相同的图表上.绘图命令看起来像这样:
hold on % Plot new data without clearing old plot
plot ( x ( : , 2 ) , x*theta , '-' ) % remember that x is now a matrix
% with 2 columnsand the second
% column contains the time info
legend( ' Training data ' , ' Linear regression ' )
请注意,在大多数机器学习问题中,x都是一个非常高的维度,因此我们无法直接绘制hθ(x)曲线,但在本例中我们只有一个特征,因此可以通过绘制该图来为我们提供一个良好的思路来验证我们的计算结果。(3)最后,我们希望利用所学的假设来进行一些预测.用您的模型来进行预测这两个3.5岁和7岁的男孩的身高.
4.理解J(\theta)
为了深入理解梯度下降的作用并展示参数\theta \in R^2与J(\theta)之间的关系,在这一问题中我们将J(\theta)制作成3D表面图。(当应用学习算法时在处理高维数据的情况下(如通常情况下)我们无法直接绘制或直观地展示J(\theta)因为这些方法过于复杂或者难以操作;但在本例中由于我们仅使用了二维空间中的参数(即\theta \in R^2)因此我们可以绘制出J(\theta)的图形以更好地理解线性回归的过程)选择最佳视角以观察曲面图的最佳位置。)
J_vals = zeros (100 , 100) ; % initialize Jvals to
% 100*100 matrix of 0's
theta0_vals = linspace (-3 , 3 , 100) ;
theta1_vals = linspace (-1 , 1 , 100) ;
% 对于linespace(x1,x2,N),其中x1、x2、N分别为起始值、终止值、元素个数。
for i = 1 : length (theta0_vals)
for j = 1 : length (theta1_vals )
t = [theta0_vals(i); theta1_vals(j)] ;
J_vals(i,j) = %% YOUR CODE HERE %%
end
end
% Plot the surface plot
% Because of the way meshgrids work in the surf command , we
% need to t ranspose J_vals before calling surf , or else the
% axes will be flipped
Jval_s = Jval_s'
figure ;
surf(theta0_vals,theta1_vals,J_vals)
xlabel ('\theta_0 ');ylabel('\theta_1')

你可以预期获得与图2相似的效果。
如果你在Matlab或Octave中操作,
你可以借助轨道工具从多个视角重新审视该图形。
了解该3D曲面与其数值之间的相互作用机制如何?
请解释梯度下降过程中如何确定初始参数θ₀和θ₁?
通过波纹线和轮廓分析方法来深入理解其几何特性。
备注:在Matlab中的冲浪函数surf(x,y,z)中,默认情况下若输入向量x、y,则将绘制由这些向量确定的网格线,默认显示为等间距线段。因此,在计算过程中,默认使用网格点坐标(x_j, y_i)作为输入参数来计算对应的z值。该规则同样适用于其他类型的轮廓绘制函数。我们可以根据需求引入不同类型的间隔序列,在空间维度上采用等间距序列,在对数维度上采用几何级数序列以此来控制生成网格的数量及其分布模式。作为学习实践,在本次作业中可以尝试应用这两种不同的参数设置方案,并根据实际效果选择更适合当前场景的配置方式来进行绘图优化。
5.多元线性回归
我们现在看一个更复杂的情况,其中每个训练数据包含多个特征。下载data1.zip,并从zip文件解压缩文件(ex2x.dat和ex2y.dat)。这是俄勒冈州波特兰市的一套房价培训,其中输出y是价格,输入x是生活区域卧室的数量。有m = 47个训练样例。
看一下输入x(i)的值,并注意生活区域大约是卧室数量的1000倍。 这种差异意味着预处理输入将显著提高梯度下降的效率。
在你的程序中,按标准偏差和比例缩放两种类型的输入将他们的方法设定为零。在Matlab / Octave中,这可以用
sigma = std ( x ) ;
mu = mean( x ) ;
x ( : , 2 ) = ( x ( : , 2 ) - mu( 2 ) ) . / sigma ( 2 ) ;
x ( : , 3 ) = ( x ( : , 3 ) - mu( 3 ) ) . / sigma ( 3 ) ;
5.1 使用J(θ)选择学习率
目前恰如其分地到了选择学习率\alpha的时候。这一部分旨在通过选定合适的参数范围来确定一个合理的学习速率,在这个范围内即从0.001到10之间进行探索。
您将通过进行初始选择,运行梯度下降、观察成本函数,并相应地调整学习率。回想起在等式(2)中定义的成本函数。成本函数也可以以下面的矢量化形式写成
J(\theta) = \frac{1}{2m}(X\theta - \vec{y})^T(X\theta - \vec{y})
其中
\vec{y} = \left[ \begin{matrix} y^{(1)} \\ y^{(2)}\\ \vdots \\ y^{(m)} \end{matrix} \right] ,X = \left[ \begin{matrix} 1 &x_1^{(1)} & x_2^{(1)} &\cdots &x_n^{(1)}\\ 1 & x_1^{(2)} &x_2^{(2)} &\cdots &x_n^{(2)} \\ \vdots & \vdots & \vdots &x_j^{(i)} &\vdots \\ 1& x_1^{(m)} &x_2^{(m)} &\cdots &x_1^{(1)} \end{matrix} \right] = \left[ \begin{matrix} (x^{(1)})^T \\ (x^{(2)})^T \\ \vdots \\ (x^{(m)} )^T \end{matrix} \right]
当您使用Matlab / Octave等数值计算工具时,矢量化版本非常有用且高效。 如果您熟悉矩阵,您可以证明这两种形式是等价的
在上一个练习中,您在\theta_0和\theta_1的网格上计算出了J(\theta),现在使用当前梯度下降阶段的\theta计算J(\theta)。单步执行多个阶段后,您将看到J(\theta)随着迭代的进展而变化。
现在,以初始学习速率运行梯度下降约50次迭代。 在每次迭代中,计算J(\theta)并将结果存储在矢量J中。在最后一次迭代之后,将J值绘制为迭代次数。 在Matlab / Octave中,步骤看起来像这样:
theta = zeros ( size ( x ( 1 , : ) ) ) ' ; % initialize fitting parameters
alpha = %% Your initial learning rate %%
J = zeros (50 , 1 ) ;
for num_iterations = 1:50
J ( num_iterations ) = %% Calculate your cost function here %%
theta = %% Result of gradient descent update %%
end
% now plot J
% technically , the first J starts at the zero-eth iteration
% but Matlab/Octave doesn ' t have a zero index
figure ;
plot ( 0 : 49 , J ( 1 : 50 ) , '-' )
xlabel ( 'Number of iterations ' )
ylabel ( ' Cost J ' )
如果你选择了一个很好的范围内的学习率,你的图应该是如下图这样的。
[

](https://imgchr.com/i/iKFKIK)
如果您的图形呈现出显著差异性特征,请特别注意:当损失函数J(θ)出现明显上升或急剧扩大情况时,请及时调整学习率参数,并重新运行测试。我们推荐依次尝试α值为下一最小值的三倍倍数关系(具体数值包括:0.01、0.03、0.1以及更大的如前所述)。此外,在观察训练过程中的曲线趋势时,请考虑适当调节运行周期的数量以获取更全面的数据反馈。为了系统性地分析不同学习率对模型收敛性的影响效果,请建议在同一坐标系中绘制多个不同α对应的损失函数曲线。在Matlab/Octave环境下实现这一目标可采用以下步骤:首先初始化并运行梯度下降算法;其次重复该过程若干次;最后将每次运行所得损失函数结果进行记录并可视化展示。
plot ( 0 : 49 , J1 ( 1 : 50 ) , 'b-' ) ;
hold on ;
plot ( 0 : 49 , J2 ( 1 : 50 ) , ' r-' ) ;
plot ( 0 : 49 , J3 ( 1 : 50 ) , 'k-' ) ;
最后的参数’b-’,'r-'和’k-'为图表指定了不同的绘图样式。键入
help plot
Matlab / Octave命令行以获取有关打印样式的更多信息。
回答下列问题
- 随着学习率的变化,观察成本函数的变化。当学习率太小时会发生什么?太大了?
- 使用您找到的最佳学习率,运行梯度下降直到收敛找到
(a)\theta的最终值
(b)1650平方英尺和3间卧室的房屋预计价格。
进行此预测时,请不要忘记扩展功能!
