⭐对应笔记:正则化
在这个练习中,你将实现正则化的线性回归和正则化的逻辑回归。
这个数据包包含两组数据,一组用于线性回归,另一个用于逻辑回归。还包含一个名为"map_feature"的辅助函数,将用于逻辑回归。确保这个函数的m文件位于您计划编写代码的相同工作目录中。
本练习第一部分着重于正规线性回归和正规方程。加载数据文件"ex5Linx.dat"和"ex5Liny.dat",这对应你要开始的变量x和y。注意,在这个数据中,输入"x"是一个单独的特征,因此你可以将y作为x的函数绘制在二维图上:
x=load('ex5Linx.dat');
y=load('ex5Liny.dat');
figure
plot(x,y,'o');
从这个图上可以看出来,拟合直线可能过于简单。相反,我们将尝试对数据拟合一个高阶多项式,以捕捉更多点的变化。我们试试五阶多项式。我们的假设是:
这意味着有六个特征的假设,因为 x 0 , x 1 , . . . , x 5 x_0,x_1,...,x_5 x0,x1,...,x5都是我们回归的所有特征。注意,即使我们得到了一个多项式拟合,我们仍有一个线性回归的问题,因为假设在每个特征中都是线性的。
由于我们正在将一个五阶多项式拟合到一个只有7个点的数据集上,因此很可能会发生过拟合。为了防止这种情况发生,我们将在模型中使用正则化。回想一下,在正则化问题中,目标是最小化以下关于θ的成本函数:
式中,λ为正则化参数。正则化参数λ是对拟合参数的控制。随着拟合参数大小的增加,对代价函数的惩罚也会增加。这个惩罚取决于参数的平方以及λ的大小。另外,请注意,λ求和不包括 θ 0 2 θ_0^2 θ02。
现在,我们将使用正规方程找到模型的最佳参数。回想一下正则化线性回归的正规方程解是:
跟在 λ后的矩阵是一个左上角一个0和剩余对角线元素为1的对角(n+1)×(n+1)矩阵(记住,n是特征的数量)。向量 y和矩阵 X 对于非正则回归有相同的定义。使用这个方程,找出使用以下三个正则化参数 θ 的值: λ=0
,λ = 1
,λ = 10
当你实现你的程序时,请记住, X 是一个 m × ( n + 1 ) 矩阵,因为有m个训练样本和 n个特征,加上一个 x 0 = 1 x_0 = 1 x0=1的截距项。在提供给这个练习的数据中,你只是给出 x的一次方。你需要在你的向量 X中给出其它 x的平方,这意味着 X的第一列都是1,第二列是 x的一次方,第三列是 x的二次方,依次进行下去。可以使用以下命令:
x = [ones(m,1),x,x.^2,x.^3,x.^4,x.^5];
x = load('ex5Linx.dat');
y = load('ex5Liny.dat');
figure
plot(x,y,'o');
hold on
m = length(y);
x = [ones(m,1),x,x.^2,x.^3,x.^4,x.^5];
theta = zeros(6,3);
T = diag([0 1 1 1 1 1]);
lamda = [0,1,10];
for i = 1:3
theta(:,i) = inv(x'*x+lamda(i)*T)*x'*y;
end
x = linspace(-1,1,100)';
x = [ones(100,1),x,x.^2,x.^3,x.^4,x.^5];
plot(x(:,2), x*theta(:,1),'--r');
hold on
plot(x(:,2), x*theta(:,2),'--b');
hold on
plot(x(:,2), x*theta(:,3),'--g');
hold on
legend('Training Data','lamda = 0','lamda = 1','lamda = 10');
⭐通过查看这些图表,您可以得出关于正则化参数λ如何影响您的模型的什么结论?
在本练习的第二部分中,您将使用牛顿法实现正则化的逻辑回归。首先,将文件“ex5Logx.dat”和“ex5Logy.dat”加载到程序中。该数据集表示具有两个特征的逻辑回归问题的训练集。为了避免以后的混淆,我们将把包含在“ex5Logx.dat”中的两个输入特性称为u和v。所以在“ex5Logx.dat”文件中,第一列数字代表特征u,你将在横轴上绘制,第二个特征代表v,你将在纵轴上绘制。加载数据后,使用不同的标记绘制点,以区分两种分类。
x = load('ex5Logx.dat');
y = load('ex5Logy.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),'o');
我们现在将对这个数据拟合一个正则化的回归模型。回想一下,在逻辑回归中,假设函数是:
在这个练习中,我们将把x赋值为u和v的所有单项式(即多项式3项),直到第六次幂:
为了澄清这个符号:我们做了一个28个特征向量x,其中 x 0 = 1 , x 1 = u , x 2 = v , … … x 28 = v 6 x_0 = 1,x_1 = u,x_2 = v,……x_{28}=v^6 x0=1,x1=u,x2=v,……x28=v6。记住,u是“ex5Logx.dat”文件中数字的第一列,而v是第二列。从现在开始,我们将只把x的条目称为 x 0 , x 1 x_0,x_1 x0,x1等等,而不是它们的u和v的值。
为了避免枚举所有 x 项的麻烦,我们包含了一个辅助函数,“map_feature”,它将原始数据映射到特征向量。这个函数使用于单个训练示例,也适用于整个训练示例。为了使用这个函数,将"map_feature.m"放在你的工作目录中
x = map_feature(u,v)
这假设这两个原始特征被存储在名为“u”和“v”的列向量中。如果只有一个训练示例,每个列向量将是一个标量。该函数将输出一个存储在变量“x”中的新特性数组。当然,您可以为参数和输出使用任何您想要的名称。只要确保你的两个参数是相同大小的列向量。
在建立这个模型之前,回想一下我们的目标是最小化正则化逻辑回归的最小代价函数:
这看起来像是非正则化逻辑回归的成本函数,除了在最后有一个正则化项。我们现在将用牛顿的方法来最小化这个函数。回想一下,牛顿方法的更新规则是:
这与非正则化逻辑回归的规则相同。但是因为你现在正在实现正则化,梯度∇θ(J)和Hessian H有不同的形式:
如果你把 λ = 0 代入这些表达式,您将看到和非正则化逻辑回归有相同的公式,在这些公式中:
- x ( i ) x^{(i)} x(i)是你的特征向量,在这个练习中这是一个28×1的向量。
- ∇ θ J ∇_θJ ∇θJ是28×1的向量。
- x ( i ) ( x ( i ) ) T x^{(i)}(x^{(i)})^T x(i)(x(i))T是28×28的矩阵。
- y ( i ) y^{(i)} y(i)和 h θ ( x ( i ) ) h_θ ( x ^{( i )} ) hθ(x(i))是标量。
- λ/m后面的矩阵在海森公式中是一个左上角一个0和剩余对角线元素为1的对角28×28矩阵。
现在在这个数据集上使用如下的 λ值运行牛顿法:λ=0
,λ = 1
,λ = 10
打印每次迭代中的 J ( θ ) J ( θ ) J(θ) 值,为了确定牛顿法是否已经收敛。 J ( θ ) J ( θ ) J(θ) 不应该在使用牛顿法中的任何时候都减少,如果是,检查你是否正确定义了 J ( θ ) J ( θ ) J(θ) ,还要检查梯度和海森的定义,以确保正则化部分没有错误。
收敛后,用θ的值找出分类问题中的决策边界。决策边界定义为其中的直线
x = load('ex5Logx.dat');
y = load('ex5Logy.dat');
figure
pos = find(y); neg = find(y == 0);
plot(x(pos, 1), x(pos, 2), '+');
hold on;
plot(x(neg, 1), x(neg, 2), 'o');
u = x(:, 1); v = x(:, 2);
x = map_feature(u, v);
m = length(y);
lamda = 10; %lamda修改处
g = inline('1.0 ./ (1.0 + exp(-z))');
T = eye(28, 28); T(1, 1) = 0;
theta = zeros(28, 1);
EPS = 10^-6;
h = g(x * theta);
L(1) = 0;
L(2) = (1 / m) .* sum(-y .* log(h) - (1 - y) .* log(1 - h));
cnt = 2;
while abs(L(cnt) - L(cnt - 1)) > EPS
cnt = cnt + 1;
H = (1 / m) .* x' * diag(h) * diag(1 - h) * x + (lamda / m) * T;
theta_j = theta; theta_j(1, 1) = 0;
theta = theta - H \ ((1 / m) * x' * (h - y) + (lamda / m) * theta_j);
h = g(x * theta);
L(cnt) = (1 / m) .* sum(-y .* log(h) - (1 - y) .* log(1 - h)) + (lamda / (2 * m)) * sum(theta .* theta);
end
hold on
u = linspace(-1, 1.5, 200);
v = linspace(-1, 1.5, 200);
z = zeros(length(u), length(v));
for i = 1:length(u)
for j = 1:length(v)
z(j, i) = map_feature(u(i), v(j)) * theta;
end
end
z = z';
contour(u, v, z, [0, 0], 'LineWidth', 2);
figure;
plot(1:cnt - 1, L(2: cnt), 'o-')
norm(theta)
- 首先将原始的特征向量 x x x 映射到高维特征向量 m a p _ f e a t u r e ( u , v ) map\_feature(u,v) map_feature(u,v),然后利用逻辑回归分类器的梯度下降算法来拟合训练数据集,其中 l a m d a lamda lamda 是正则化系数。在拟合过程中,使用了代价函数 L L L,它包含了正则化项,并且 H H H 为 L L L 的 Hessian 矩阵,用于计算参数 θ \theta θ 的梯度方向。
g函数
为逻辑函数(sigmoid函数),T
为28x28的单位矩阵且将T的第一个元素设为0,`theta初始为28x1的零向量,EPS为精度要求(代价函数的值与上一次变化量不超过所设定的EPS,那么就认为模型已经收敛,跳出while循环)。- 在while循环里,用已知的theta来计算模型预测值h。L(1)为0,L(2)为初始代价函数的值,然后
用while循环不断更新theta并计算代价函数的值
,直至代价函数不再变化或达到精度要求。更新theta是通过计算Hessian矩阵H的逆矩阵乘上梯度的方式实现的。- 牛顿迭代法的核心在于求解Hessian矩阵的逆矩阵,将其乘上梯度得到参数的更新量。Hessian矩阵在逻辑回归中的具体定义是,在所有训练样本上的损失函数的二阶偏导数组成的矩阵。梯度是指代价函数对参数的偏导。
- 最后,通过画出分类边界图和代价函数的迭代过程来观察模型是否收敛以及代价函数的变化情况。norm(theta)则求解theta每个元素的平方和并返回值。
⭐️下图表示Grid 图与决策边界和损失函数与迭代次数关系
λ=0
λ=1
λ=10
⭐️λ如何影响结果?
从以上三张图可以看出惩罚越大,其精度、查准率和查全率越低,曲线会逼近于正则化项的圆形边界,但收敛速度会越快。对比λ取0、1、10的情况,某种程度上说,λ=1是比较合适的,既保证了精度、查准率和查全率相对较高,又提高了模型的泛化能力,一定程度上缓解了过拟合。