吴恩达机器学习笔记-梯度下降+线性回归+正规方程+逻辑回归+正则化(带matlab程序)

线性回归模型

在这里插入图片描述二元函数线性回归

在这里插入图片描述
多元函数线性回归
在这里插入图片描述

梯度下降公式

在这里插入图片描述

注意:如果多个变量的话要最后统一赋值(左边对右边错)
在这里插入图片描述

代码

void C拟合直线View::OnLinearRegression()
{
	// TODO: 在此添加命令处理程序代码

	st0 = 0; st1 = 0;//初始化seita
	float af = 0.00001;//设置学习率

	float st0_old = st0+1, st1_old = st1+1;
	double V_sum_sum = 0, V_sum_sum_old = 20000000;
	double  V_sum_0 = 0, V_sum_1 = 0;
	while (fabs(st0_old - st0)>0.0001||fabs(st1_old - st1)>0.0001)//判断条件 st0 st1变化不超过一个数
//	while (fabs(V_sum_sum_old - V_sum_sum)>100)
	{
		V_sum_0 = 0;
		V_sum_1 = 0;
		V_sum_sum = 0;
		V_sum_sum_old = V_sum_sum;
		for (int i = 0; i < count; i++)
		{
			V_sum_0 += st0 + st1*mPoint[i].x - mPoint[i].y;
			V_sum_1 += (st0 + st1*mPoint[i].x - mPoint[i].y)*mPoint[i].x;
			V_sum_sum += (st0 + st1*mPoint[i].x - mPoint[i].y)*(st0 + st1*mPoint[i].x - mPoint[i].y);
		}

		st0_old = st0 ; st1_old = st1;
		st0 = st0 - af*100*V_sum_0 / count;
		st1 = st1 - af*V_sum_1 / count;

	}
	b = st0;//a,b是输出直线的两个参数y=a*x+b
	a = st1;


}

运行结果
在这里插入图片描述

正规方程

核心是求出令代价函数每个偏导为0的参数
在这里插入图片描述
公式:
在这里插入图片描述在这里插入图片描述

正规方程与梯度下降法的优缺点

梯度下降法正规方程
需要选择学习率α不需要选择学习率α
需要多次迭代不需要多次迭代,一次就能计算出来
特征量很多的时候也能运行很好 (十万个特征量)特征量很多时(XTX)-1 计算量过多(计算时间是特征量的3次方)十万级别为大概分界

matlab程序

p=[1,3;2,5;3,9;30,10;60,30;80,47;50,18]%输入点
n=3 %拟合的线公式最高次数 y=st(1)+st(2)*x^1+st(3)*x^2+...+st(n+1)*x^n
x= []
y=[]
for ii=1:size(p,1)
    xx=[1]
    for iii=1:n-1
        xx=[xx,p(ii,1).^iii]
    end
    x=[x;xx]
    y=[y;p(ii,2)]
end

%{
x=[
    1,p(1,1),p(1,1).^2,p(1,1).^3;
    1,p(2,1),p(2,1).^2,p(2,1).^3;
    1,p(3,1),p(3,1).^2,p(3,1).^3;
    1,p(4,1),p(4,1).^2,p(4,1).^3;
    ]

y=[p(1,2);p(2,2);p(3,2);p(4,2);]
%}


st=(((x')*x)^-1)*(x')*y %正规方程公式

i=[0:100]
j=[0]
 for iii=1:n
       j=j+st(iii).*(i.^(iii-1))
 end
%j=st(1)+st(2).*i+st(3).*(i.^2)%+st(4).*(i.^3)
plot(p(:,1),p(:,2),'o')
hold on
plot(i,j)

结果
在这里插入图片描述

逻辑回归

本质是将线性回归的结果通过logistic函数转换到0-1之间,同时,logistic函数还能使得代价函数成为一个凸函数,从而可以使用梯度下降公式,寻找最低点

代价函数与cost

在这里插入图片描述

Cost函数

在这里插入图片描述在这里插入图片描述
简化后的代价函数
在这里插入图片描述
一对多分类时

在这里插入图片描述

matlab代码

其中添加了学习率的pd控制并限幅,有一定的效果

pt_1=[1,1;3,3;2,4;4,5;7,-1;4,9;6,4]%输入正点
pt_0=[1,4;6,8;7,8;9,5;0,-1;6,-3;8,-2;9,0;4,11]%输入负点

plot(pt_0(:,1),pt_0(:,2),'or',pt_1(:,1),pt_1(:,2),'+b')%画出点
hold on

%分别计算正负点的个数
n_1=size(pt_1,1)
n_0=size(pt_0,1)

%分别为正点和负点的矩阵后面添加1的标志
pt_1=[pt_1 ,ones(n_1,1)]
pt_0=[pt_0 ,zeros(n_0,1)]

%将所有点放到一个矩阵中,并计算所有点的个数
pt=[pt_1;pt_0]
m=size(pt,1)


n=8  %设置要拟合的曲线公式的最高次数 a+b*x+c*y+d*x^2+e*x*y+f*y^2 此时,n为2

%定义xy矩阵,存放所有特征变量值和标定的结果
x=[]
y=[]

% 计算xy矩阵
% 格式 x为:
% [   1      , 1      , 1      , 1     ,...1     ;
%     x1     , x2     , x3     , x4     ,...,xm;
%     y1     , y2     , y3     , y4     ,...,ym;
%     x1^2   , x2^2   , x3^2   , x4^2   ,...,ym^2;
%     x1*y1...
%     y1^2...
%     .
%     .
%     y1^n...                                      ]
%     
% y为:
% [    y1,y2,y3...ym    ]
for ii=1:m
    
    xx=[]
    for j=0:n
        for iii=0:j
            xx=[xx;(pt(ii,1).^iii).*(pt(ii,2).^(j-iii))]
        end      
    end
%   xx=[1;pt(ii,1);pt(ii,2);pt(ii,1).^2;pt(ii,1).*pt(ii,2);pt(ii,2).^2;pt(ii,1).^3;(pt(ii,1).^2).*pt(ii,2);pt(ii,1).*(pt(ii,2).^2);pt(ii,2).^3]
     
    x=[x,xx]
    y=[y,pt(ii,3)]
end


%定义学习率 af=[0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01];
af_1=ones((n+2)*(n+1)/2,1)*0.0001
af=af_1

%初始化特征值st=[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0];
st=ones((n+2)*(n+1)/2,1)*0
st_old=st+1%上一个特征值,为了判断梯度下降结束条件和引入学习率pd控制需要

sum=[0]%公式中间变量
s_1=-ones(1,n_1)%存储所有正点在当前特征值st下的值,为了判断是否分类成功用
s_0=ones(1,n_0)%同上



%while(max(s_0(:))>-4|min(s_1(:))<4|max(st_old-st)>0.00001|max(st-st_old)>0.00001)%分类成功且st变化小于某个数
while(max(s_0(:))>-1000|min(s_1(:))<1000)%是否分类成功
%while(max(st_old-st)>0.00001|max(st-st_old)>0.00001)%st变化小于某个数

   st_old=st;
   for ii=1:46600%每次迭代计算多次
       
       %梯度下降公式,
       sum=((1+ exp(-st'*x)).^(-1)-y)*x'/m;
       st=st-sum'.*af;
   end
   
   %计算正负点带入当前特征值st后的结果,如果一个所有值大于0,一个所有值小于0,则分类成功
   s_1=[ones(1,n_1)];%;pt_1(:,1)';pt_1(:,2)';(pt_1(:,1)').^2;(pt_1(:,1)').*(pt_1(:,2)');(pt_1(:,2)').^2;(pt_1(:,1)').^3;(pt_1(:,1)').^2.*(pt_1(:,2)');(pt_1(:,1)').*(pt_1(:,2)').^2;(pt_1(:,2)').^3];
   s_0=[ones(1,n_0)];%;pt_0(:,1)';pt_0(:,2)';(pt_0(:,1)').^2;(pt_0(:,1)').*(pt_0(:,2)');(pt_0(:,2)').^2;(pt_0(:,1)').^3;(pt_0(:,1)').^2.*(pt_0(:,2)');(pt_0(:,1)').*(pt_0(:,2)').^2;(pt_0(:,2)').^3];
   for j=1:n
        for iii=0:j
            s_1=[s_1;(pt_1(:,1)'.^iii).*(pt_1(:,2)'.^(j-iii))];
            s_0=[s_0;(pt_0(:,1)'.^iii).*(pt_0(:,2)'.^(j-iii))];
        end      
   end
   s_1=st'*s_1
   s_0=st'*s_0 
   st
    
   af=af_1+abs(st-st_old)*0.04;%引入学习率af的pd控制
   af=af.*(af<af_1*5)+2*af_1.*(af>=af_1*5);%学习率af限幅,大于af初始值的多少倍的话就是给这个值
end



%ellipsefig1(st(4),st(6),st(5),st(2),st(3),st(1));

%绘制图像,本来是二元多次函数的曲线图像,但是没找到合适的函数,
%通过采用绘制二元多次函数在一点范围内的三维图,设置z轴范围比如-1到1之间显示,从俯视图可以勉强看到曲线的形状
[x, y] = meshgrid(-10:0.05:20); % 步长可以适当地增大, 
a=2
z=st(1)
for j=1:n
    for iii=0:j
         z=z+ st(a)*(x.^(iii)).*(y.^(j-iii));
         a=a+1
    end
end
%z = 3*x.^2+3*y.^2+3*x.*y+1-3*x-3*y;
%mesh(x, y, z)
surf(x, y, z)%显示三维图像
axis([-10 20 -10 20 -0.001 0.001])%限制z轴
view([-0.1,89.9])%设置观察角度,稍微倾斜一下曲线比较清晰


图像

在这里插入图片描述

线性回归的正则化

目的是解决过拟合问题,通过减少特征个数或者令某些特征量非常小,

通过下图方法可以使得指定特征值变的非常小
在这里插入图片描述

代价函数如下
在这里插入图片描述

梯度函数如下
在这里插入图片描述正则化的正规方程如下

在这里插入图片描述在这里插入图片描述
代码

p=[1,3;11,9;25,9;39,10;50,20;60,37;70,40;80,57]%;90,60]%输入点
n=7  %拟合的线公式最高次数 y=st(1)+st(2)*x^1+st(3)*x^2+...+st(n+1)*x^n
x= []
y=[]
for ii=1:size(p,1)
    xx=[1];
    for iii=1:n-1
        xx=[xx,p(ii,1).^iii];
    end
    x=[x;xx];
    y=[y;p(ii,2)];
end

%{
x=[
    1,p(1,1),p(1,1).^2,p(1,1).^3;
    1,p(2,1),p(2,1).^2,p(2,1).^3;
    1,p(3,1),p(3,1).^2,p(3,1).^3;
    1,p(4,1),p(4,1).^2,p(4,1).^3;
    ]

y=[p(1,2);p(2,2);p(3,2);p(4,2);]
%}


lbd=1000000;%正则化的系数 
e=eye(n,n);%计算单位矩阵
e(1,1)=0;



st=(((x')*x)^-1)*(x')*y %正规方程公式
st_z=(((x')*x+lbd*e)^-1)*(x')*y %正则化后的正规方程公式


i=[0:100];
j=[0];
 for iii=1:n
       j=j+st(iii).*(i.^(iii-1));
 end
%j=st(1)+st(2).*i+st(3).*(i.^2)%+st(4).*(i.^3)
plot(p(:,1),p(:,2),'ok')
hold on
plot(i,j,'r')

i=[0:100];
j=[0];
 for iii=1:n
       j=j+st_z(iii).*(i.^(iii-1));
 end
 plot(i,j,'b')
 
 axis([0,100,0,100])

运行结果对比

红色未正则化,蓝色正则化
在这里插入图片描述

逻辑回归的正则化

代价函数
在这里插入图片描述梯度下降函数
在这里插入图片描述
程序

pt_1=[1,1;3,3;2,4;4,6;7,1;4,0;7,2]%输入正点
pt_0=[1,7;6,8;7,8;9,5;0,-1;6,-3;8,-2;9,0;4,11]%输入负点

plot(pt_0(:,1),pt_0(:,2),'or',pt_1(:,1),pt_1(:,2),'+b')%画出点
hold on

%分别计算正负点的个数
n_1=size(pt_1,1)
n_0=size(pt_0,1)

%分别为正点和负点的矩阵后面添加1的标志
pt_1=[pt_1 ,ones(n_1,1)]
pt_0=[pt_0 ,zeros(n_0,1)]

%将所有点放到一个矩阵中,并计算所有点的个数
pt=[pt_1;pt_0]
m=size(pt,1)


n=6  %设置要拟合的曲线公式的最高次数 a+b*x+c*y+d*x^2+e*x*y+f*y^2 此时,n为2

%定义xy矩阵,存放所有特征变量值和标定的结果
x=[]
y=[]

% 计算xy矩阵
% 格式 x为:
% [   1      , 1      , 1      , 1     ,...1     ;
%     x1     , x2     , x3     , x4     ,...,xm;
%     y1     , y2     , y3     , y4     ,...,ym;
%     x1^2   , x2^2   , x3^2   , x4^2   ,...,ym^2;
%     x1*y1...
%     y1^2...
%     .
%     .
%     y1^n...                                      ]
%     
% y为:
% [    y1,y2,y3...ym    ]
for ii=1:m
    
    xx=[]
    for j=0:n
        for iii=0:j
            xx=[xx;(pt(ii,1).^iii).*(pt(ii,2).^(j-iii))]
        end      
    end
%   xx=[1;pt(ii,1);pt(ii,2);pt(ii,1).^2;pt(ii,1).*pt(ii,2);pt(ii,2).^2;pt(ii,1).^3;(pt(ii,1).^2).*pt(ii,2);pt(ii,1).*(pt(ii,2).^2);pt(ii,2).^3]
     
    x=[x,xx]
    y=[y,pt(ii,3)]
end


%定义学习率 af=[0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01;0.01];
af_1=ones((n+2)*(n+1)/2,1)*0.00003
af=af_1

%初始化特征值st=[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0];
st=ones((n+2)*(n+1)/2,1)*0.0
st_old=st+1%上一个特征值,为了判断梯度下降结束条件和引入学习率pd控制需要

sum=[0]%公式中间变量
s_1=-ones(1,n_1)%存储所有正点在当前特征值st下的值,为了判断是否分类成功用
s_0=ones(1,n_0)%同上

e=ones((n+2)*(n+1)/2,1)
e(1:6,1)=0
lbd=15
%while(max(s_0(:))>-4|min(s_1(:))<4|max(st_old-st)>0.00001|max(st-st_old)>0.00001)%分类成功且st变化小于某个数
%while(max(s_0(:))>-0.1|min(s_1(:))<0.1)%是否分类成功
while(max(st_old-st)>0.001|max(st-st_old)>0.001)%st变化小于某个数

   st_old=st;
   for ii=1:46000%每次迭代计算多次
       
       %梯度下降公式,
       sum=((1+ exp(-st'*x)).^(-1)-y)*x'/m;
       %st=st-sum'.*af;%未正则化
       
       st=st.*(ones((n+2)*(n+1)/2,1)-lbd*e.*af)-sum'.*af;%正则化
   end
   
   %计算正负点带入当前特征值st后的结果,如果一个所有值大于0,一个所有值小于0,则分类成功
   s_1=[ones(1,n_1)];%;pt_1(:,1)';pt_1(:,2)';(pt_1(:,1)').^2;(pt_1(:,1)').*(pt_1(:,2)');(pt_1(:,2)').^2;(pt_1(:,1)').^3;(pt_1(:,1)').^2.*(pt_1(:,2)');(pt_1(:,1)').*(pt_1(:,2)').^2;(pt_1(:,2)').^3];
   s_0=[ones(1,n_0)];%;pt_0(:,1)';pt_0(:,2)';(pt_0(:,1)').^2;(pt_0(:,1)').*(pt_0(:,2)');(pt_0(:,2)').^2;(pt_0(:,1)').^3;(pt_0(:,1)').^2.*(pt_0(:,2)');(pt_0(:,1)').*(pt_0(:,2)').^2;(pt_0(:,2)').^3];
   for j=1:n
        for iii=0:j
            s_1=[s_1;(pt_1(:,1)'.^iii).*(pt_1(:,2)'.^(j-iii))];
            s_0=[s_0;(pt_0(:,1)'.^iii).*(pt_0(:,2)'.^(j-iii))];
        end      
   end
   s_1=st'*s_1
   s_0=st'*s_0 
   st
    
   af=af_1+abs(st-st_old)*0.1;%引入学习率af的pd控制
   af=af.*(af<af_1*10)+2*af_1.*(af>=af_1*10);%学习率af限幅,大于af初始值的多少倍的话就是给这个值
end



%ellipsefig1(st(4),st(6),st(5),st(2),st(3),st(1));

%绘制图像,本来是二元多次函数的曲线图像,但是没找到合适的函数,
%通过采用绘制二元多次函数在一点范围内的三维图,设置z轴范围比如-1到1之间显示,从俯视图可以勉强看到曲线的形状
[x, y] = meshgrid(-10:0.05:20); % 步长可以适当地增大, 
a=2
z=st(1)
for j=1:n
    for iii=0:j
         z=z+ st(a)*(x.^(iii)).*(y.^(j-iii));
         a=a+1;
    end
end
%z = 3*x.^2+3*y.^2+3*x.*y+1-3*x-3*y;
%mesh(x, y, z)
surf(x, y, z)%显示三维图像
axis([-10 20 -10 20 -0.001 0.001])%限制z轴
view([-0.1,89.9])%设置观察角度,稍微倾斜一下曲线比较清晰

结果对比

加了正则化后的图像
在这里插入图片描述未加正则化

在这里插入图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值