loss下降auc下降_梯度下降算法 线性回归拟合(附Python/Matlab/Julia源代码)

0fde145ebecf1822255a1bab3f750a27.png

梯度下降

梯度下降法的原理

梯度下降法(gradient descent)是一种常用的一阶(first-order)优化方法,是求解无约束优化问题最简单、最经典的方法之一。

梯度下降最典型的例子就是从山上往下走,每次都寻找当前位置最陡峭的方向小碎步往下走,最终就会到达山下(暂不考虑有山谷的情况)。

首先来解释什么是梯度?这就要先讲微分。对于微分,相信大家都不陌生,看几个例子就更加熟悉了。

先来看单变量的微分:

再看多变量的微分:

补充:导数和微分的区别
导数是函数在某一点处的斜率,是Δy和Δx的比值;而微分是指函数在某一点处的切线在横坐标取得增量Δx以后,纵坐标取得的增量,一般表示为dy。

梯度就是由微分结果组成的向量,令


那么,函数f(x,y,z)在(1,2,3)处的微分为


因此,函数f(x,y,z)在(1,2,3)处的梯度为(6,11,6)。

梯度是一个向量,对于一元函数,梯度就是该点处的导数,表示切线的斜率。对于多元函数,梯度的方向就是函数在该点上升最快的方向。

梯度下降法就是每次都寻找梯度的反方向,这样就能到达局部的最低点。

那为什么按照梯度的反方向能到达局部的最低点呢?这个问题直观上很容易看出来,但严禁起见,我们还是给出数学证明。

对于连续可微函数f(x),从某个随机点出发,想找到局部最低点,可以通过构造一个序列

能够满足


那么我们就能够不断执行该过程即可收敛到局部极小点,可参考下图。

596d792635ac851e768ef15d519a754c.png

那么问题就是如何找到下一个点

并保证
呢?我们以一元函数为例来说明。对于一元函数来说,x是会存在两个方向:要么是正方向
, 要么是负方向
,如何选择每一步的方向,就需要用到大名鼎鼎的泰勒公式,先看一下下面这个泰勒展式:

其中

表示f(x)在x处的导数。

若想

,就需要保证
,令


步长
是一个较小的正数,从而有

因此,有

每一步我们都按照

更新x,这就是梯度下降的原理。

这里再对

解释一下,α在梯度下降算法中被称作为学习率或者步长,意味着我们可以通过α来控制每一步走的距离。既要保证步子不能太小,还没下到山底太阳就下山了;也要保证步子不能跨的太大,可能会导致错过最低点。

36dfdfdd0a024cf3d610e0f7db8f5523.png

在梯度前加负号就是朝梯度的反方向前进,因为梯度是上升最快的方向,所以方向就是下降最快的方向。

梯度下降的实例

一元函数的梯度下降

设一元函数为

函数的微分为

设起点为

,步长
,根据梯度下降的公式

经过4次迭代:

1b044d298f5ec6939afdc0b5b62a684c.png

多元函数的梯度下降

设二元函数为

函数的梯度为

设起点为(2,3),步长

,根据梯度下降的公式,经过多次迭代后,有

f8fc71c3b62c65e11dd5ebabc4a9c886.png

loss function(损失函数)

损失函数也叫代价函数(cost function),是用来衡量模型预测出来的值h(θ)与真实值y之间的差异的函数,如果有多个样本,则可以将所有代价函数的取值求均值,记做J(θ)。代价函数有下面几个性质:

  1. 对于每种算法来说,代价函数不是唯一的;
  2. 代价函数是参数θ的函数;
  3. 总的代价函数J(θ)可以用来评价模型的好坏,代价函数越小说明模型和参数越符合训练样本(x, y);
  4. J(θ)是一个标量。

最常见的代价函数是均方误差函数,即


其中,

  • m为训练样本的个数
  • 表示估计值,表达式如下
  • y是原训练样本中的值

我们需要做的就是找到θ的值,使得J(θ)最小。代价函数的图形跟我们上面画过的图很像,如下图所示。

9a7d59c62ff789ed522bb4c36d8b4777.png

看到这个图,相信大家也就知道了我们可以用梯度下降算法来求可以使代价函数最小的θ值。

先求代价函数的梯度

这里有两个变量

,为了方便矩阵表示,我们给x增加一维,这一维的值都是1,并将会乘到
上。那么cost function的矩阵形式为:

这么看公式可能很多同学会不太明白,我们把每个矩阵的具体内容表示出来,大家就很容易理解了。

矩阵

为:

矩阵X为:

矩阵y为:

这样写出来后再去对应上面的公式,就很容易理解了。

下面我们来举一个用梯度下降算法来实现线性回归的例子。有一组数据如下图所示,我们尝试用求出这些点的线性回归模型。

11654846852de64c31bcfa33aee60009.png

首先产生矩阵X和矩阵y

# generate matrix X

按照上面的公式定义梯度函数

def gradient_function(theta, X, y):diff = np.dot(X, theta) - yreturn (1./m) * np.dot(np.transpose(X), diff)

接下来就是最重要的梯度下降算法,我们取

的初始值都为1,再进行梯度下降过程。
def gradient_descent(X, y, alpha):theta = np.array([1, 1]).reshape(2, 1)gradient = gradient_function(theta, X, y)while not np.all(np.absolute(gradient) <= 1e-5):theta = theta - alpha * gradientgradient = gradient_function(theta, X, y)return theta

通过该过程,最终求出的

,线性回归的曲线如下

24918c8ab645596f7edf9c8742b8ff0e.png

附录 source code

matlab一元函数的梯度下降程序

clc;
close all;
clear all;
%% 
delta = 1/100000;
x = -1.1:delta:1.1;
y = x.^2;
dot = [1, 0.2, 0.04, 0.008];
figure;plot(x,y);
axis([-1.2, 1.2, -0.2, 1.3]);
grid on
hold on
plot(dot, dot.^2,'r');
for i=1:length(dot)text(dot(i),dot(i)^2,['theta_{',num2str(i),'}']);
end
title('一元函数的梯度下降过程');

1b044d298f5ec6939afdc0b5b62a684c.png

python一元函数的梯度下降程序

import numpy as np 
import matplotlib.pyplot as pltdelta = 1/100000
x = np.arange(-1.1, 1.1, delta)
y = x ** 2
dot = np.array([1, 0.2, 0.04, 0.008])
plt.figure(figsize=(7,5))
plt.plot(x,y)
plt.grid(True)
plt.xlim(-1.2, 1.2)
plt.ylim(-0.2, 1.3)
plt.plot(dot, dot**2, 'r')
for i in range(len(dot)):plt.text(dot[i],dot[i]**2,r'$theta_%d$' % i)
plt.title('一元函数的梯度下降过程')
plt.show()

021960313e382a500ebc5d130d92d4d9.png

julia一元函数的梯度下降程序

using PyPlot
delta = 1/100000
x = -1.1:delta:1.1
y = x.^2
dot = [1, 0.2, 0.04, 0.008]
plot(x, y)
grid(true)
axis("tight")
plot(dot, dot.^2, color="r")
for i=1:length(dot)text(dot[i], dot[i]^2, "$theta_$i$")
end
title("Single variable function gradient descent")

2fe741846950e3623b36908680d0a935.png

matlab二元函数的梯度下降程序

pecision = 1/100;
[x,y] = meshgrid(-3.1:pecision:3.1);
z = x.^2 + y.^2;
figure;
mesh(x,y,z);
dot = [[2,3];[1.6,2.4];[1.28,1.92];[5.09e-10, 7.64e-10]];
hold on
scatter3(dot(:,1),dot(:,2),dot(:,1).^2+dot(:,2).^2,'r*');
for i=1:4text(dot(i,1)+0.4,dot(i,2),dot(i,1).^2+0.2+dot(i,2).^2+0.2,['theta_{',num2str(i),'}']);
end
title('二元函数的梯度下降过程')

f8fc71c3b62c65e11dd5ebabc4a9c886.png

python二元函数的梯度下降程序

import numpy as np 
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(-3.1,3.1,300)
y = np.linspace(-3.1,3.1,300)
x,y = np.meshgrid(x, y)
z = x**2 + y**2
dot = np.array([[2,3],[1.6,2.4],[1.28,1.92],[5.09e-10, 7.64e-10]])
fig = plt.figure(figsize = (10,6))
ax = fig.gca(projection = '3d')
cm = plt.cm.get_cmap('YlGnBu')
surf = ax.plot_surface(x, y, z, cmap=cm)
fig.colorbar(surf,shrink=0.5, aspect=5)
ax.scatter3D(dot[:,0], dot[:,1], dot[:,0]**2 + dot[:,1]**2, marker='H',c='r')
for i in range(len(dot)-1):ax.text(dot[i,0]+0.4, dot[i,1], dot[i,0]**2 + dot[i,1]**2, r'$Theta_%d$' % i)
ax.text(dot[3,0]+0.4, dot[3,1]+0.4, dot[3,0]**2 + dot[3,1]**2-0.4, r'min')
plt.show()

40284025c737214151ef6ba481b6fad7.png

julia二元函数的梯度下降程序

这个图的text死活标不上,希望知道的朋友可以告知一下。再多说一句,虽然我之前出了个Julia的教程,里面也包含4种绘图工具(Plots,GR,Gadfly & PyPlot),但没有画过3维的图形,今天为了画这个图可真是费尽周折,Julia官网上的3D绘图的程序基本没有一个可以直接使用的,具体的绘图过程和调试中碰到的问题我还会整理篇文章到知乎和公众号,大家可以看一下。

using Plots
Plots.plotlyjs()
n = 50
x = range(-3, stop=3, length=n)
y= x
z = zeros(n,n)
for i in 1:n, k in 1:nz[i,k] = x[i]^2 + y[k]^2
endsurface(x, y, z)
dot = [[2 3]; [1.6 2.4]; [1.28 1.92]; [5.09e-10  7.64e-10]]
scatter!(dot[:,1], dot[:,2], dot[:,1].^2 .+ dot[:,2].^2)

aafe1993ada8aa7b7fe4f6c08f08aab9.png

matlab梯度下降的线性回归

m = 18;
X0 = ones(m,1);
X1 = (1:m)';
X = [X0, X1];
y = [2,3,3,5,8,10,10,13,15,15,16,19,19,20,22,22,25,28]';
alpha = 0.01;
theta = gradient_descent(X, y, alpha, m);function [grad_res] =  gradient_function(theta, X, y, m)diff = X * theta - y;grad_res = X' * diff / m;
endfunction [theta_res] =  gradient_descent(X, y, alpha, m)theta = [1;1];gradient = gradient_function(theta, X, y, m);while sum(abs(gradient)>1e-5)>=1theta = theta - alpha * gradient;gradient = gradient_function(theta, X, y, m);endtheta_res = theta;
end

python梯度下降的线性回归

import numpy as np 
import matplotlib.pyplot as plt # y = np.array([2,3,3,5,8,10,10,13,15,15,16,19,19,20,22,22,25,28])
# x = np.arange(1,len(y)+1)
# plt.figure()
# plt.scatter(x,y)
# plt.grid(True)
# plt.show()# sample length
m = 18# generate matrix X
X0 = np.ones((m, 1))
X1 = np.arange(1, m+1).reshape(m, 1)
X = np.hstack((X0, X1))# matrix y
y = np.array([2,3,3,5,8,10,10,13,15,15,16,19,19,20,22,22,25,28]).reshape(m,1)# alpha
alpha = 0.01def cost_function(theta, X, y):diff = np.dot(X, theta) - yreturn (1./2*m) * np.dot(np.transpose(diff), diff)def gradient_function(theta, X, y):diff = np.dot(X, theta) - yreturn (1./m) * np.dot(np.transpose(X), diff)def gradient_descent(X, y, alpha):theta = np.array([1, 1]).reshape(2, 1)gradient = gradient_function(theta, X, y)while not np.all(np.absolute(gradient) <= 1e-5):theta = theta - alpha * gradientgradient = gradient_function(theta, X, y)return theta[theta0, theta1] = gradient_descent(X, y, alpha)
plt.figure()
plt.scatter(X1,y)
plt.plot(X1, theta0 + theta1*X1, color='r')
plt.title('基于梯度下降算法的线性回归拟合')
plt.grid(True)
plt.show()

julia梯度下降的线性回归

m = 18
X0 = ones(m,1)
X1 = Array(1:m)
X = [X0 X1];
y = [2,3,3,5,8,10,10,13,15,15,16,19,19,20,22,22,25,28];
alpha = 0.01;
theta = gradient_descent(X, y, alpha, m)function gradient_function(theta, X, y, m)diff = X * theta .- y;grad_res = X' * diff / m;
endfunction gradient_descent(X, y, alpha, m)theta = [1,1]gradient = gradient_function(theta, X, y, m)while all(abs.(gradient) .>1e-5)==truetheta = theta - alpha * gradientgradient = gradient_function(theta, X, y, m)endtheta_res = theta
end

最后附上我出过的免费的Julia教学视频链接:

Julia 教程 从入门到进阶 - 网易云课堂​study.163.com

微信公众号:Quant_Times

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/501273.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

台式电脑耳机插孔在哪_吉林戴尔电脑音箱维修app,查看详情_曹操闪修

首页 > 新闻列表 > 正文发布时间&#xff1a;2020-10-24 01:14:13 浏览&#xff1a; 14导读&#xff1a;吉林戴尔电脑音箱维修app, 这样的问题一般只有三种解决方法&#xff0c;一种就是重新新冲突的驱动。第二种方法就是在中改变各自的中断&#xff0c;消除冲突。第三种…

Linux的实际操作:文件目录类的实用指令(rm mv)

其实rm和我们上几节学到的rmdir有点类似 &#xff0c;区别在哪里呢&#xff1f;rm是可以删除文件或者文件夹&#xff0c;rmdir是删除文件夹&#xff0c;而且如果是一个非空文件夹&#xff0c;是不能通过rmdir删除的&#xff0c;需要用rm -rf 去强制递归删除&#xff08;不懂的话…

无法将该对象添加到ldap服务器_LDAP 基础知识

LDAP 基础知识目录简介协议概览目录结构架构&#xff08;Schema&#xff09;对象类&#xff08;objectClass&#xff09;属性&#xff08;Attribute&#xff09;条目&#xff08;Entry&#xff09;LDAP 中的数据常用命令启动和关闭: start-ds / stop-ds检查 LDAP 服务器状态: s…

windows7系统损坏修复_【软件资讯】还在用win7?微软Windows 7系统正式停止技术支持...

本文转自IT之家&#xff0c;作者玄隐。早在2015年1月&#xff0c;微软结束了对Windows 7的主流支持&#xff0c;该公司停止向旧操作系统添加新功能。微软将Windows 7从主流支持转移到扩展支持。2020年1月14日&#xff0c;今天迎来了Windows 7的停止技术支持&#xff0c;微软将把…

Linux的实际操作:文件目录类的实用指令(cat more less)

1.cat 要查看的文件 &#xff08;是以只读的方式打开,区别于vim可以查看文件并且编辑&#xff09; cat -n 要查看的文件 &#xff08;只读&#xff0c;且提供行号&#xff09; cat -n 要查看的文件 | more &#xff08;这个操…

电子测量与仪器第四版pdf_准确选择表面粗糙度仪的测量参数应该从哪些地方着手好【电子仪器吧】...

表面粗糙度仪的参数怎么选择&#xff1f;首先要先满足运用功能要求&#xff0c;其次再兼顾经济性能。即&#xff0c;在满足运用要求的前题下&#xff0c;尽可能下降外表粗糙度要求&#xff0c;放大表面粗糙度允许值。对多数外表面来说&#xff0c;给出高度特色评定参数即可反映…

Linux的实际操作:文件目录类的实用指令(重定向“>“和追加“>>“)

1. > 表示重定向 &#xff08;重定向什么意思呢&#xff1f;就是把一个文件的内容&#xff0c;保存到指定的位置&#xff09; > 是定向输出到文件&#xff0c;如果文件不存在&#xff0c;就创建文件&#xff1b;如果文件存在&#xff0c;就将其清空&#…

wrapper怎么用_用责任链模式设计拦截器

我在 Redant(https://github.com/all4you/redant) 中通过继承 ChannelHandler 实现了拦截器的功能&#xff0c;并且 pipeline 就是一种责任链模式的应用。但是我后面对原本的拦截器进行了重新设计&#xff0c;为什么这样做呢&#xff0c;因为原本的方式是在 ChannelHandler 的基…

VS2019 配色_这个双11,凯里-欧文陪你过!欧文6正式发布,城市版配色真的香

北京时间11月5日&#xff0c;在篮网主场对阵鹈鹕的比赛中&#xff0c;欧文一上场就让教主眼前一亮&#xff0c;这鞋骚的有点过分啊。欧文6代已经于北京时间11月5日正式发布&#xff0c;虽然首发配色毫无惊喜&#xff0c;毕竟早在休赛期就已经被曝得连底裤都不剩了&#xff0c;但…

Linux的实际操作:文件目录类的实用指令(echo head tail)

1.echo 输出内容到控制台 例子&#xff1a;实用echo指令输出环境变量&#xff0c;输出当前的环境变量路径 2.head 用于显示文件的开头部分内容&#xff0c;默认情况下head显示文件的前10行内容&#xff08;因为有些文件比较大&#xff0c;我们有时候不全去看&#xff09; 空格…

如何延长作用域链_通过实例理解javaScript中的this到底是什么和它的词法作用域...

最近&#xff0c;听到李笑来说&#xff0c;讲解编程的过程中&#xff0c;举例子很重要。而且&#xff0c;我最近看的各种javaScript工具书中的例子&#xff0c;也都有点复杂。所以啊&#xff0c;我试着举一些简单又直观的例子&#xff0c;与各位苦学javaScript的同学&#xff0…

word2vector数据集样式_这样做数据可视化驾驶舱,高端大气,一目了然,领导不点赞都难...

2020年了&#xff0c;数据可视化已经不是个新鲜词了&#xff0c;把数据以可视化图表的形式展示并没有多神奇&#xff0c;用Excel等传统的办公工具就可以轻松实现。以前传统数据分析报告就是ppt里贴图表&#xff0c;再配上分析结论&#xff0c;这种形式的数据呈现是静态的&#…

Linux的实际操作:文件目录类的实用指令(ln history)

1.ln 软连接也叫做符号链接&#xff0c;类似于windows的快捷方式&#xff0c;主要是存放了链接其它文件的路径 ln -s 原文件或者目录 软链接名 &#xff08;功能&#xff1a;给原文件创建一个软链接&#xff09; 案例&#xff1a;将/roo…

mysql 删除重复数据_日常答疑|MySQL删除重复数据踩过得坑

问题群友提问&#xff1a;MySQL这样删除重复数据为啥不成功呢&#xff1f;严小样儿&#xff1a;安排&#xff01;咋一看&#xff0c;大家都说where子句里面应该使用极值函数&#xff0c;加个max就对了&#xff0c;这么简单&#xff01;# 大家想象中这样写是对的&#xff0c;其实…

搜狗手机浏览器_搜狗推广开户费多少钱?【搜狗开户代理商】

搜狗开户流程提供落地页审核提供服务器ip 安排解析账户预存款4000币上传关键词及素材开启广告上线福如海广告&#xff0c;搜狗开户代理商全国行业开户&#xff0c;有无资质均可手机&#xff1a;18705657032【同微信】搜狗广告详细介绍搜狗广告展现形式PC端-搜狗搜索推广当网民在…

understand 6.0_软件工程专业篇-vc++6.0安装教程(解决win10不兼容)

在进行安装教程之前还是和大家说几句废话啊。VC6.0就是出品的一款开发C的IDE。所谓IDE就是&#xff1a;为了方便程序员开发&#xff0c;集成了代码编辑器、编译器、链接器、调试器等工具的集成开发环境。 现在外面企业已经很少有使用VC6.0的了&#xff0c;毕竟已经是将近17年前…

Linux的实际操作:时间日期类的实用指令(date cal)

1.date 显示当前日期 &#xff08;1&#xff09;date 显示当前时间 &#xff08;2&#xff09; date %Y 显示年份 date%m 显示月份 date%d 显示日 date "%Y-%m-%d %H:%M:%S" 显示年月日时分秒 注意&#xff1a;加号不能少 双引号中间的连接可以取任意符号 &a…

Linux的实际操作:搜索查找类的实用指令(find locate grep 管道符|)

1.find 将从指定目录向下递归地遍历其各个子目录&#xff0c;将满足条件的文件或者目录显示在终端 find 【搜索范围】 【选项】 文件 &#xff08;搜索范围往往是绝对路径或者相对路径&#xff09; 选项功能-name按照指定文件名查找文件-user查找属于指定用户名所有…

error:java:无效的源发行版_IDEA java出现无效的源发行版14解决方案_java

这篇文章主要介绍了IDEA java出现无效的源发行版14解决方案,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下问题描述问题原因出现该问题的原因是项目Project当中的jdk与电脑当中的jdk版本不一致造成的。解决方法…

为什么买入不了创业版_详解实战抄底——如何抄到下引线的最底端。及妖股的首板买入点...

11月26日上周四&#xff0c;如果方便的朋友可以打开下创业板当天的分时图&#xff0c;更加有利于理解。(下图所示)主板和创业板11月26日分时图当天创业板冲高回落开始探底&#xff0c;我在10点17分的时候提示准备抄底&#xff0c;在10点22分的时候&#xff0c;再次强调创业板跌…