山东大学机器学习(实验三内容)——正则化
1. 描述
在这个练习中,你将实现正则化的线性回归和正则化的逻辑回归。
2. 数据
首先,下载data3.zip和从压缩文件中提取文件。这个数据包包含两组数据,一组用于线性回归(ex3Linx.dat和ex3Liny.dat),另一个用于逻辑回归(x3Logx.dat和ex3Logy.dat)。还包含一个名为"map_feature"的辅助函数。将用于逻辑回归。确保这个函数的m文件位于您计划编写代码的相同工作目录中。
3. 正则化线性回归
本练习第一部分着重于正规线性回归和正规方程。加载数据文件"ex3Linx.dat"和"ex3Liny.dat"。在你的程序中,这对应你要开始的变量x和y。注意,在这个数据中,输入"x"是一个单独的特征,因此你可以将y作为x的函数绘制在二维图上(你可以自己尝试):从这个图上可以看出来,拟合直线可能过于简单。相反,我们将尝试对数据拟合一个高阶多项式,以捕捉更多点的变化。
我们试试五阶多项式。我们的假设是
h _ { \theta } ( x ) = \theta _ { 0 } + \theta _ { 1 } x + \theta _ { 2 } x ^ { 2 } + \theta _ { 3 } x ^ { 3 } + \theta _ { 4 } x ^ { 4 } + \theta _ { 5 } x ^ { 5 } \tag{1}
这意味着有六个特征的假设,因为x_0,x_1,\dots,x_5是我们回归的所以特征。注意,即使我们得到了一个多项式拟合,我们仍有一个线性回归的问题因为每个特征的假设都是线性的。
由于我们将一个5阶多项式拟合到一个只有7个点的数据集,因此很可能出现过拟合。为了防止这种情况,我们将在模型中使用正则化。回想一下正则化问题,目标是最小化关于\theta的代价函数
J ( \theta ) = \frac { 1 } { 2 m } \left[ \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) ^ { 2 } + \lambda \sum _ { j = 1 } ^ { n } \theta _ { j } ^ { 2 } \right] \tag{2}

其中\lambda是正则化参数。正则化参数\lambda是控制在你的拟合参数。随着拟合参数的增大,对成本函数的惩罚也会增大,这个点球是依赖于参数的平方以及\lambda的大小。同时,求和后\lambda不包括\theta_0^2。
现在,我们将使用正规方程找到模型的最佳参数。回想一下正则化线性回归的正规方程解是
\theta = ( X ^ { T } X + \lambda \left[ \begin{array} { c c c c } { 0 } & { } & { } \\ { } & { 1 } & { } \\ { } & { } & { \ddots } & { } \\ { } & { } & { } & { 1 } \end{array} \right] ) ^ { - 1 } X ^ { T } \vec { y }
跟在\lambda后的矩阵是一个左上角一个0和剩余对角线元素为1的对角(n+1)×(n+1)矩阵(记住,n是特征的数量)。向量y和矩阵X对于非正则回归有相同的定义。
使用这个方程,找出使用以下三个正则化参数\theta的值
- \lambda=0
- \lambda=1
- \lambda=10
当你实现你的程序时,请记住,X是一个m \times (n+1)矩阵,因为有m个训练样本和n个特征,加上一个x_0 = 1的截距项。在提供给这个练习的数据中,你只是给出x的一次方。你需要在你的向量X中给出其它x的平方,这意味着X的第一列都是1,第二列是x的一次方,第三列是x的二次方,依次进行下去。你可以使用Matlab/Octave命令如下
x = [ones(m,1),x,x.^2,x.^3,x.^4,x.^5];
AI写代码
显示在不同\lambda时\theta的值。同时,画出不同\lambda对应的多项式图像。例如,如果\lambda=0会得到和图2类似。从这些结果中,你能了解正则化参数\lambda是如何影响你的模型的吗?

4. 正则化逻辑回归
在练习的第二部分中,你将使用牛顿方法实现正则逻辑回归。首先,在你的程序中加载文件ex3Logx.dat和ex3Logy.dat。该数据表示具有两个特征的逻辑回归问题的训练集。为了避免后面的混淆,我们将引用"ex3Logx.dat"中包含的两个输入特性作为u和v。所以在"ex3Logx.dat"文件中,第一列的数字代表特征u,在横轴上绘制,第二列特征代表v,在纵轴上绘制。
加载数据后,使用不同的标记绘制点,以区分两种分类。Matlab/Octave中的命令为
x = load('ex3Logx.dat');
y = load('ex3Logy.dat');
figure
%Find the indices for the 2 calsses
pos = find(y == 1); neg = find(y == 0);
plot(x(pos,1),x(pos,2),'+');
hold on
plot(x(neg,1),x(neg,2),'+');
AI写代码
绘制完图片后,应该是这样的:

现在我们将为这些数据拟合一个规范化的回归模型。回想一下,在Logistic回归中,假设函数为
h _ { \theta } ( x ) = g \left( \theta ^ { T } x \right) = \frac { 1 } { 1 + e ^ { - \theta ^ { T } x } } = P ( y = 1 | x ; \theta )
在这次练习中,我们将分配x的所有单项(即多项式计算)的u和v的6次方:
x = \left[ \begin{array} { c } { 1 } \\ { u } \\ { v } \\ { u ^ { 2 } } \\ { u v } \\ { v ^ { 2 } } \\ { u ^ { 3 } } \\ { \vdots } \\ { u v ^ { 5 } } \\ { v ^ { 6 } } \end{array} \right]
为了澄清这个符号,我们做了一个28个特征的向量x,其中x_0=1,x_2=v,\dots,x_{28}=v^6。记住,u是在"ex3Logx.dat"中的第一列数字,v是第二列。从现在开始,我们把x的元素记作x_0,x_1等等,而不是它们的值用u和v表示。
为了避免枚举所有x项的麻烦,我们包含了一个Matlab/Octave辅助函数,名为"map_feature",它将原始数据映射到特征向量。这个函数使用于单个训练示例,也适用于整个训练示例。为了使用这个函数,将"map_feature.m"放在你的工作目录中
x = map_feature(u,v)
AI写代码
假设这两个原始特征存储在名为"u"和"v"的列向量中。如果只有一个训练示例,那么每个列向量都是标量。函数将输出存储在"x"中的新的特征数组。当然,您可以为参数和输出使用任何你想要的名称。只要确保两个参数是相同大小的列向量即可。
在建立这个模型之前,回想一下我们的目标是最小化正则化逻辑回归的最小代价函数:
J ( \theta ) = - \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left[ y ^ { ( i ) } \log \left( h _ { \theta } \left( x ^ { ( i ) } \right) \right) + \left( 1 - y ^ { ( i ) } \right) \log \left( 1 - h _ { \theta } \left( x ^ { ( i ) } \right) \right) \right] + \frac { \lambda } { 2 m } \sum _ { j = 1 } ^ { n } \theta _ { j } ^ { 2 }
注意,这看起来像非正则逻辑回归的成本函数,除了最后有一个正则项。现在我们用牛顿法求这个函数的最小值。回想一下牛顿方法的更新规则是
\theta ^ { ( t + 1 ) } = \theta ^ { ( t ) } - H ^ { - 1 } \nabla _ { \theta } J
这与练习4中用于非正则逻辑回归的规则相同,但因为你现在实现正则化,梯度\nabla_\theta J和海森矩阵H 有不同的形式
\nabla _ { \theta } J = \left[ \begin{array} { c } { \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) x _ { 0 } ^ { ( i ) } } \\ { \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) x _ { 1 } ^ { ( i ) } + \frac { \lambda } { m } \theta _ { 1 } } \\ { \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) x _ { 2 } ^ { ( i ) } + \frac { \lambda } { m } \theta _ { 2 } } \\ { \vdots } \\ { \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) x _ { n } ^ { ( i ) } + \frac { \lambda } { m } \theta _ { n } } \end{array} \right] \tag{3}
H = \frac { 1 } { m } \left[ \sum _ { i = 1 } ^ { m } h _ { \theta } \left( x ^ { ( i ) } \right) \left( 1 - h _ { \theta } \left( x ^ { ( i ) } \right) \right) x ^ { ( i ) } \left( x ^ { ( i ) } \right) ^ { T } \right] + \frac { \lambda } { m } \left[ \begin{array} { c c c c } { 0 } & { } & { } \\ { } & { 1 } & { } \\ { } & { } & { \ddots } & { } \\ { } & { } & { } & { 1 } \end{array} \right] \tag{4}
注意,如果你把\lambda = 0代入这些表达式,您将看到和非正则化逻辑回归有相同的公式,在这些公式中,
- x^{(i)}是你的特征向量,在这个练习中这是一个28×1的向量。
- \nabla_\theta J是28×1的向量。
- x^{(i)}(x^{(i)})^T和H是28×28的矩阵。
- y^{(i)}和h_\theta(x^{(i)})是标量。
- \frac{\lambda}{m}后面的矩阵在海森公式中是一个左上角一个0和剩余对角线元素为1的对角28×28矩阵。
现在在这个数据集上使用如下的\lambda值运行牛顿法
a. \lambda = 0(这是和非正则化线性回归相同的例子)
b. \lambda = 1
c. \lambda = 10
打印每次迭代中的J(\theta)值,为了确定牛顿法是否已经收敛。J(\theta)不应该在使用牛顿法中的任何时候都减少,如果是,检查你是否正确定义了J(\theta),还要检查梯度和海森的定义,以确保正则化部分没有错误。
收敛后,用\theta的值找出分类问题中的决策边界。决策边界定义为其中的直线
P ( y = 1 | x ; \theta ) = 0.5 \quad \Longrightarrow \quad \theta ^ { T } x = 0
在此处绘制决策边界比在线性回归中绘制最佳拟合曲线更为棘手。您需要通过绘制轮廓来绘制\theta^Tx = 0线的隐含性。这可以通过在表示原始u和v输入的点网格上\theta^Tx值,然后绘制\theta^Tx值为零的线来完成。使用以下代码在\theta的不同值下绘制决策边界。
% Define the ranges of the grid
u = linspace (-1 , 1.5 , 200);
v = linspace (-1 , 1.5 , 200);
% Initialize space for the values to be plotted
z = zeros (length (u) , length (v)) ;
% Evaluate z = theta*x over the grid
for i = 1 : length (u)
for j = 1 : length (v)
% Notice the order of j , i here!
z (j,i) = map_feature (u(i) , v(j))*theta ;
end
end
% Because of the way that contour plotting works
% in Matlab , we need to transpose z , or
% else the axis orientation will be flipped!
z = z '
% Plot z = 0 by specifying the range [0 , 0]
contour (u , v , z , [0 , 0] , ' LineWidth ' , 2)
AI写代码
最后,因为有28个元素\theta,我们不会提供一个解决方案中的元素比较。相反,使用norm(\theta)来计算\theta的L2范数,检查它的标准解决方案。\lambda是如何影响结果的?
