专栏首页null的专栏优化算法——牛顿法(Newton Method)

优化算法——牛顿法(Newton Method)

一、牛顿法概述

    除了前面说的梯度下降法,牛顿法也是机器学习中用的比较多的一种优化算法。牛顿法的基本思想是利用迭代点

处的一阶导数(梯度)和二阶导数(Hessen矩阵)对目标函数进行二次函数近似,然后把二次模型的极小点作为新的迭代点,并不断重复这一过程,直至求得满足精度的近似极小值。牛顿法的速度相当快,而且能高度逼近最优值。牛顿法分为基本的牛顿法和全局牛顿法。

二、基本牛顿法

1、基本牛顿法的原理

    基本牛顿法是一种是用导数的算法,它每一步的迭代方向都是沿着当前点函数值下降的方向。

    我们主要集中讨论在一维的情形,对于一个需要求解的优化函数

,求函数的极值的问题可以转化为求导函数

。对函数

进行泰勒展开到二阶,得到

对上式求导并令其为0,则为

即得到

这就是牛顿法的更新公式。

2、基本牛顿法的流程

  1. 给定终止误差值

,初始点

,令

  1. 计算

,若

,则停止,输出

  1. 计算

,并求解线性方程组得解

,并转2。

三、全局牛顿法

    牛顿法最突出的优点是收敛速度快,具有局部二阶收敛性,但是,基本牛顿法初始点需要足够“靠近”极小点,否则,有可能导致算法不收敛。这样就引入了全局牛顿法。

1、全局牛顿法的流程

  1. 给定终止误差值

,初始点

,令

  1. 计算

,若

,则停止,输出

  1. 计算

,并求解线性方程组得解

是不满足下列不等式的最小非负整数

,并转2。

2、Armijo搜索

    全局牛顿法是基于Armijo的搜索,满足Armijo准则:

给定

,令步长因子

,其中

是满足下列不等式的最小非负整数:

四、算法实现

    实验部分使用Java实现,需要优化的函数

,最小值为

1、基本牛顿法Java实现

package org.algorithm.newtonmethod;

/**
 * Newton法
 * 
 * @author dell
 * 
 */
public class NewtonMethod {
	private double originalX;// 初始点
	private double e;// 误差阈值
	private double maxCycle;// 最大循环次数

	/**
	 * 构造方法
	 * 
	 * @param originalX初始值
	 * @param e误差阈值
	 * @param maxCycle最大循环次数
	 */
	public NewtonMethod(double originalX, double e, double maxCycle) {
		this.setOriginalX(originalX);
		this.setE(e);
		this.setMaxCycle(maxCycle);
	}

	// 一系列get和set方法
	public double getOriginalX() {
		return originalX;
	}

	public void setOriginalX(double originalX) {
		this.originalX = originalX;
	}

	public double getE() {
		return e;
	}

	public void setE(double e) {
		this.e = e;
	}

	public double getMaxCycle() {
		return maxCycle;
	}

	public void setMaxCycle(double maxCycle) {
		this.maxCycle = maxCycle;
	}

	/**
	 * 原始函数
	 * 
	 * @param x变量
	 * @return 原始函数的值
	 */
	public double getOriginal(double x) {
		return x * x - 3 * x + 2;
	}

	/**
	 * 一次导函数
	 * 
	 * @param x变量
	 * @return 一次导函数的值
	 */
	public double getOneDerivative(double x) {
		return 2 * x - 3;
	}

	/**
	 * 二次导函数
	 * 
	 * @param x变量
	 * @return 二次导函数的值
	 */
	public double getTwoDerivative(double x) {
		return 2;
	}

	/**
	 * 利用牛顿法求解
	 * 
	 * @return
	 */
	public double getNewtonMin() {
		double x = this.getOriginalX();
		double y = 0;
		double k = 1;
		// 更新公式
		while (k <= this.getMaxCycle()) {
			y = this.getOriginal(x);
			double one = this.getOneDerivative(x);
			if (Math.abs(one) <= e) {
				break;
			}
			double two = this.getTwoDerivative(x);
			x = x - one / two;
			k++;
		}
		return y;
	}

}

2、全局牛顿法Java实现

package org.algorithm.newtonmethod;

/**
 * 全局牛顿法
 * 
 * @author dell
 * 
 */
public class GlobalNewtonMethod {
	private double originalX;
	private double delta;
	private double sigma;
	private double e;
	private double maxCycle;

	public GlobalNewtonMethod(double originalX, double delta, double sigma,
			double e, double maxCycle) {
		this.setOriginalX(originalX);
		this.setDelta(delta);
		this.setSigma(sigma);
		this.setE(e);
		this.setMaxCycle(maxCycle);
	}

	public double getOriginalX() {
		return originalX;
	}

	public void setOriginalX(double originalX) {
		this.originalX = originalX;
	}

	public double getDelta() {
		return delta;
	}

	public void setDelta(double delta) {
		this.delta = delta;
	}

	public double getSigma() {
		return sigma;
	}

	public void setSigma(double sigma) {
		this.sigma = sigma;
	}

	public double getE() {
		return e;
	}

	public void setE(double e) {
		this.e = e;
	}

	public double getMaxCycle() {
		return maxCycle;
	}

	public void setMaxCycle(double maxCycle) {
		this.maxCycle = maxCycle;
	}

	/**
	 * 原始函数
	 * 
	 * @param x变量
	 * @return 原始函数的值
	 */
	public double getOriginal(double x) {
		return x * x - 3 * x + 2;
	}

	/**
	 * 一次导函数
	 * 
	 * @param x变量
	 * @return 一次导函数的值
	 */
	public double getOneDerivative(double x) {
		return 2 * x - 3;
	}

	/**
	 * 二次导函数
	 * 
	 * @param x变量
	 * @return 二次导函数的值
	 */
	public double getTwoDerivative(double x) {
		return 2;
	}

	/**
	 * 利用牛顿法求解
	 * 
	 * @return
	 */
	public double getGlobalNewtonMin() {
		double x = this.getOriginalX();
		double y = 0;
		double k = 1;
		// 更新公式
		while (k <= this.getMaxCycle()) {
			y = this.getOriginal(x);
			double one = this.getOneDerivative(x);
			if (Math.abs(one) <= e) {
				break;
			}
			double two = this.getTwoDerivative(x);
			double dk = -one / two;// 搜索的方向
			double m = 0;
			double mk = 0;
			while (m < 20) {
				double left = this.getOriginal(x + Math.pow(this.getDelta(), m)
						* dk);
				double right = this.getOriginal(x) + this.getSigma()
						* Math.pow(this.getDelta(), m)
						* this.getOneDerivative(x) * dk;
				if (left <= right) {
					mk = m;
					break;
				}
				m++;
			}
			x = x + Math.pow(this.getDelta(), mk)*dk;
			k++;
		}
		return y;
	}
}

3、主函数

package org.algorithm.newtonmethod;

/**
 * 测试函数
 * @author dell
 *
 */
public class TestNewton {
	public static void main(String args[]) {
		NewtonMethod newton = new NewtonMethod(0, 0.00001, 100);
		System.out.println("基本牛顿法求解:" + newton.getNewtonMin());

		GlobalNewtonMethod gNewton = new GlobalNewtonMethod(0, 0.55, 0.4,
				0.00001, 100);
		System.out.println("全局牛顿法求解:" + gNewton.getGlobalNewtonMin());
	}
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 优化算法——牛顿法(Newton Method)

    一、牛顿法概述     除了前面说的梯度下降法,牛顿法也是机器学习中用的比较多的一种优化算法。牛顿法的基本思想是利用迭代点 ? 处的一阶导数(梯度)和二阶导数(...

    zhaozhiyong
  • 计算广告——广告定向实践

    计算广告学涉及到很多的不同的学科知识,包括大规模搜索,文本分析,机器学习,信息检索以及经济学等等。在计算广告中,其核心问题是在给定的环境下,找到用户和广告之间的...

    zhaozhiyong
  • 机器学习算法实现解析——libFM之libFM的训练过程概述

    本节主要介绍的是libFM源码分析的第四部分——libFM的训练。 FM模型的训练是FM模型的核心的部分。 4.1、libFM中训练过程的实现 在FM模型的训练...

    zhaozhiyong
  • 优化算法——牛顿法(Newton Method)

    一、牛顿法概述     除了前面说的梯度下降法,牛顿法也是机器学习中用的比较多的一种优化算法。牛顿法的基本思想是利用迭代点 ? 处的一阶导数(梯度)和二阶导数(...

    zhaozhiyong
  • java数组的另一种用法

    每一个enum实例,一个不同的子类 你可以重载一个enum实例的方法。这将高效的给一个enum的实例一个自己的实现。

    用户5166556
  • 算法提高 12-1三角形

    问题描述   为二维空间中的点设计一个结构体,在此基础上为三角形设计一个结构体。分别设计独立的函数计算三角形的周长、面积、中心和重心。输入三个点,输出这三个...

    AI那点小事
  • 带抽象方法的枚举

    package org.lgy.study.enumstudy; public enum Operation{ PLUS,MINUS,M...

    MonroeCode
  • 网站性能指标 - Apdex指数

    假设有两个架构设计方案:方案A 和 方案B 方案A 并发请求 < 200 时,响应时间为 0.5秒 并发请求 > 1000 时,响应时间为 10秒 方案...

    dys
  • Python调用PHP的函数

            在电子商务的web平台中有可能存在这样的需求,在月末进行分红账务结算,这样就需要在web服务器下写脚本定时执行数据库的操作,这里有很多种可选的方...

    py3study
  • 使用Express+TypeScript编写后台服务

    最近接到一个比较简单的任务,需求如下: 1、从MQTT服务器订阅断电报警信息然后入库到SQLServer或者MySQL数据库中 2、从MQTT服务器订阅到站...

    ccf19881030

扫码关注云+社区

领取腾讯云代金券