作业任务项一:逻辑回归分类
代码如下:
data=load('E:\研究生\机器学习\吴恩达机器学习python作业代码\code\ex2-logistic regression\ex2data1.txt');
x=data(:,[1,2]);
y=data(:,3);
neg=find(y==0);
pos=find(y==1);
figure(1);
plot(x(pos,1),x(pos,2),'k+','linewidth',2,'markersize',7);
hold on
plot(x(neg,1),x(neg,2),'ko','markerfacecolor','y','markersize',7);
xlabel('Exam 1 score');
ylabel('Exam 2 score');
legend('Admitted','Not admitted');
其中data中第一第二列为-1到1的数,第三列为标签1和0 。
使用find函数找出y=0的列序号和y=1的列序号,并以第一列为x坐标,第二列为y坐标在图中标出,其中markerfacecolor是标记的颜色,markersize是标记的大小。最后得到图1如下所示:
图1 原始数据图像 |
---|
接下来首先要创建代价函数并进行测试,代价函数测试部分代码如下:
m=length(y);
X=[ones(m,1),x];
initial_theta=zeros(size(X,2),1);
[J,grad]=costFunction(X,y,initial_theta);
fprintf('Cost at initial theta (zeros): %f\n',J);
fprintf('Expected cost (approx): 0.693\n');
fprintf('Gradient at initial theta (zeros): \n');
fprintf(' %f \n', grad);
fprintf('Expected gradients (approx):\n -0.1000\n -12.0092\n -11.2628\n');
test_theta=[-24;0.2;0.2];
[J,grad]=costFunction(X,y,test_theta);
fprintf('\nCost at test theta: %f\n', J);
fprintf('Expected cost (approx): 0.218\n');
fprintf('Gradient at test theta: \n');
fprintf(' %f \n', grad);
fprintf('Expected gradients (approx):\n 0.043\n 2.566\n 2.647\n');
首先对x和theta进行初始化,由于
θ
0
\theta_0
θ0的存在,使得x需要在最左边加一列为1的列向量。theta是和x的列数相同的,因为
θ
n
\theta_n
θn对应
x
n
x_n
xn。
最后进行两部分验证,第一部分为初始化theta为0时的代价和梯度,第二部分为初始化theta不为0时的代价和梯度。
如果测试验证该部分正确后,应当把验证部分注释掉以加快运算速度。
其中costFunction.m如下:
function [J,grad]=costFunction(x,y,theta)
m=length(y);
J=0;
grad=zeros(size(theta));
J=1/m*(-y'*log(sigmoid(x*theta))-(1-y)'*log(1-sigmoid(x*theta)));
grad=1/m*x'*(sigmoid(x*theta)-y);
end
首先是逻辑回归模型的假设是: h θ ( x ) = g ( θ T X ) h_\theta(x)=g(\theta^TX) hθ(x)=g(θTX),其中 X X X为特征向量而 g g g为逻辑函数,其中常用的Sigmoid function,公式为: g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+e−z1。
sigmoid.m代码如下:
function g=sigmoid(z)
g=zeros(size(z));
g=1./(1+exp(-z));
end
该模型的输出在0到1之间。对于分类问题我们需要输出0或1,我们可以预测:
当
h
θ
>
=
0.5
h_\theta>=0.5
hθ>=0.5时,预测
y
=
1
y=1
y=1。
当
h
θ
<
0.5
h_\theta<0.5
hθ<0.5时,预测
y
=
0
y=0
y=0。
逻辑回归的代价函数公式为:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
[
y
(
i
)
l
o
g
(
h
θ
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
l
o
g
(
1
−
h
θ
(
x
(
i
)
)
)
]
J(\theta)=-\frac{1}{m}\sum_{i=1}^m[y^{(i)}log(h_\theta(x^{(i)}))+(1-y^{(i)})log(1-h_\theta(x^{(i)}))]
J(θ)=−m1∑i=1m[y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x(i)))]
求得梯度公式为:
∂
∂
θ
j
J
(
θ
)
=
1
m
∑
i
=
1
m
[
h
θ
(
x
(
i
)
)
−
y
(
i
)
]
x
j
(
i
)
\frac{\partial}{\partial \theta_j}J(\theta)=\frac{1}{m}\sum_{i=1}^m[h_\theta(x^{(i)})-y^{(i)}]x_j^{(i)}
∂θj∂J(θ)=m1∑i=1m[hθ(x(i))−y(i)]xj(i)
fminunc高级优化函数部分如下:
options=optimset('GradObj','on','MaxIter',400);
[theta,cost]=fminunc(@(theta)(costFunction(X,y,theta)),initial_theta,options);
fprintf('Cost at theta found by fminunc: %f\n', cost);
fprintf('Expected cost (approx): 0.203\n');
fprintf('theta: \n');
fprintf(' %f \n', theta);
fprintf('Expected theta (approx):\n');
fprintf(' -25.161\n 0.206\n 0.201\n');
其中options为优化函数的选项,第一项GradObj和On是设置梯度目标参数为打开,第二项MaxIter是设置最大迭代次数。@(theta)(costFunction(X,y,theta))是指向以theta为未知数的方程costFunction,在给予初始theta和options以后,高级优化算法会自动选择学习速率 α \alpha α,可以把它看做是不用预设 α \alpha α的梯度下降。
绘图部分如下:
plot_x=[min(X(:,2)),max(X(:,2))];
plot_y=-1./theta(3)*(theta(1)+theta(2)*plot_x);
hold on
plot(plot_x,plot_y);
axis([30 100 30 100]);
legend('Admitted','Not admitted','Decision boundary');
hold off
由于两点确定一条直线,因此选择横坐标的最大值和最小值两点,赋给plot_x,同时根据公式
h
θ
(
x
)
=
θ
0
+
θ
1
x
1
+
θ
2
x
2
h_\theta(x)=\theta_0+\theta_1x_1+\theta_2x_2
hθ(x)=θ0+θ1x1+θ2x2可得:
x
2
=
−
1
θ
2
(
θ
0
+
θ
1
x
1
)
x_2=-\frac{1}{\theta_2}(\theta_0+\theta_1x_1)
x2=−θ21(θ0+θ1x1)
其中
x
2
x_2
x2就是plot_y。将两点绘制于图中形成直线,设置横纵坐标均为30到100,得到图2如下:
图2 二分类图像 |
---|
预测部分如下:
predict1=sigmoid([1,45,85]*theta);
fprintf('For a student with scores 45 and 85, we predict an admission probability of %f\n', predict1')
fprintf('Expected value: 0.775 +/- 0.002\n\n')
p=predict(theta,X);
fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100);%double(p==y)相同为1不同为0
fprintf('Expected accuracy (approx): 89.0\n');
其中double(p==y)是相同为1不同为0,再计算平均值,得到最后的预测准确率。
作业任务项二:正则化的逻辑回归分类
代码如下:
data=load('E:\研究生\机器学习\吴恩达机器学习python作业代码\code\ex2-logistic regression\ex2data2.txt');
x=data(:,[1,2]);
y=data(:,3);
neg=find(y==0);
pos=find(y==1);
figure(2);
plot(x(pos,1),x(pos,2),'k+','linewidth',2,'markersize',7);
hold on
plot(x(neg,1),x(neg,2),'ko','markerfacecolor','y','markersize',7);
xlabel('Microchip Test 1');
ylabel('Microchip Test 2');
legend('y=1','y=0');
首先先将原始数据图像画出来,方法和二元逻辑回归分类相同。结果如图3所示:
图3 原始数据图像 |
---|
下面进行数据处理部分,代码如下:
m=length(y);
X=mapFeature(x(:,1),x(:,2));
initial_theta=zeros(size(X,2),1);
lambda=1;
[J,grad]=costFunctionReg(X,y,initial_theta,lambda);
options=optimset('GradObj','on','MaxIter',400);
[theta,cost]=fminunc(@(theta)(costFunctionReg(X,y,theta,lambda)),initial_theta,options);
通过高级优化方法找到最优theta和得到此时的代价函数,然后进入绘图部分。
其中mapFeature.m如下:
function out=mapFeature(x1,x2)
degree=6;
out=ones(size(x1(:,1)));
for i=1:degree
for j=0:i
out(:,end+1)=(x1.^(i-j)).*x2.^(j);
end
end
degree为需要得到的x的次数,此处采用两两搭配的形式,当degree=6时:
x 1 0 x 2 1 x_1^0x_2^1 x10x21 | x 1 1 x 2 0 x_1^1x_2^0 x11x20 | |
---|---|---|
x 1 0 x 2 2 x_1^0x_2^2 x10x22 | x 1 1 x 2 1 x_1^1x_2^1 x11x21 | x 1 2 x 2 0 x_1^2x_2^0 x12x20 |
… | … | … |
x 1 0 x 2 6 x_1^0x_2^6 x10x26 | … | x 1 6 x 2 0 x_1^6x_2^0 x16x20 |
然后令out初始化为一个全为1的列向量,按照表格上的顺序从左到右,从上到下依次生成列向量,附在out的后面,最后out生成一个第一列为1,其余列为x1和x2相组合的向量。
costFunctionReg.m如下:
function [J,grad]=costFunctionReg(x,y,theta,learningrate)
J=0;
m=length(y);
grad=zeros(size(theta));
theta_1=[0;theta(2:end)];
reg=learningrate/(2*m)*theta_1'*theta_1;
J=1/m*(-y'*log(sigmoid(x*theta))-(1-y)'*log(1-sigmoid(x*theta)))+reg;
grad=1/m*x'*(sigmoid(x*theta)-y)+learningrate/m*theta_1;
其中代价函数后加上了正则项,目的是为了不让假设函数
h
θ
(
x
)
h_\theta(x)
hθ(x)过拟合,其公式改变如下:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
[
y
(
i
)
l
o
g
(
h
θ
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
l
o
g
(
1
−
h
θ
(
x
(
i
)
)
)
]
+
λ
2
m
∑
j
=
1
n
θ
j
2
J(\theta)=-\frac{1}{m}\sum_{i=1}^m[y^{(i)}log(h_\theta(x^{(i)}))+(1-y^{(i)})log(1-h_\theta(x^{(i)}))]+\frac{\lambda}{2m}\sum_{j=1}^n\theta_j^2
J(θ)=−m1i=1∑m[y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x(i)))]+2mλj=1∑nθj2
当
λ
\lambda
λ取值较大的时候,为了使得到
m
i
n
J
(
θ
)
minJ(\theta)
minJ(θ),此时需要消除
λ
\lambda
λ带来的影响,使
θ
j
\theta_j
θj很小,接近于0 。
而当
λ
\lambda
λ取值较小的时候,此时
θ
j
\theta_j
θj可以变动较大,可以很好地拟合数据,使得
J
(
θ
)
J(\theta)
J(θ)很小,但是容易发生过拟合,无法正确预测训练集外的数据,因此
λ
\lambda
λ取值不宜过大也不宜过小。
值得注意的是,正则项只对
θ
j
(
j
=
1
,
2
,
.
.
.
,
n
)
\theta_j(j=1,2,...,n)
θj(j=1,2,...,n),而不对常数项
θ
0
\theta_0
θ0有效。因此过度正则化导致结果会是一个常数。
绘图部分如下:
hold on
u=linspace(-1,1.5,50);
v=linspace(-1,1.5,50);
z=zeros(length(u),length(v));
for i=1:length(u)
for j=1:length(v)
z(i,j)=mapFeature(u(i),v(j))*theta;
end
end
z=z';
contour(u,v,z,[0,0],'linewidth',2);
根据训练集的值域划分网格,由于两个数据都是在-1到1.5之间,因此划分网格为50*50 ,然后为每个网格交叉点创建一个z矩阵,用于存放网格点上的数据。将每个网格点的坐标代入到mapFeature之中并乘上theta得到该点的预测值,汇总在z中。由于z是用u为纵坐标,v为横坐标算的,而投影时选择u为横坐标,v为纵坐标,因此z需要进行转置。
最后得到分类图像如下图4所示:
图4 正则化二分类图像 |
---|