R 语言 optim 使用

article/2025/9/16 20:28:27

stats中的optim函数是解决优化问题的一个简易的方法。

Univariate Optimization

f = function(x,a) (x-a)^2
xmin = optimize(f,interval = c(0,1),a=1/3)
xmin

General Optimization

optim函数包含了几种不同的算法。 
算法的选择依赖于求解导数的难易程度,通常最好提供原函数的导数。

在求解之前,一般需要scale。 
可以尝试用不同的方法求解同样的问题。

Nelder-Mead method

optim默认的方法。

又称下山单纯形法,可做非线性函数的极值以及曲线拟合。

其主要思想是: 
在n维空间构建(n+1)顶点的多面体,通过reflection, expansion, contraction  ,来逐步逼近最佳点。

特点是: 
1. 不适用函数的导数信息 
2. 对不可导函数适用 
3. 可能很慢

 

 

BFGS method属于quasi-Newton方法。首先,简单介绍牛顿法: 牛顿法基于目标函数的二阶导数(海森矩阵),收敛速度快,迭代次数少,尤其在最优值附近,收敛速度是二次的。 

 

缺点是:海森矩阵稠密时,每次迭代计算量较大,且每次都会重新计算目标函数的海森矩阵的逆。这样以来,问题规模大时,其计算量以及存储空间都很大。

 

拟牛顿法是在牛顿法基础上的改进,其引入了海森矩阵的近似矩阵,避免了每次迭代都需要计算海森矩阵的逆,其收敛速度介于梯度下降牛顿法之间,属于超线性。

 

 

同时,牛顿法在每次迭代时不能保证海森矩阵总是正定的,一旦其不是正定,优化方向就会跑偏,从而使牛顿法失效,也证明了牛顿法的稳健性较差。 

 

拟牛顿法利用海森矩阵的逆矩阵?代替海森矩阵,虽然每次迭代不一定保证最优化的方向,但是近似矩阵始终正定,因此算法总是朝着最优值搜索。

注意: 1. 使用函数导数信息,通过人工提供或者有限微分 2. 高维的数据存储会很大


CG method


一种共轭梯度法(conjugate gradient),选择连续的、与椭圆轴线相仿的路径。


特点: 
1. 不存储海森矩阵 
2. 三种不同的路径搜索方法 
3. 与BFGS相比,较差的稳定性 

4. 使用函数导数信息

 

 

L-BFGS-B method

 

 

A limited memory version of BFGS

 

特点: 

 

1. 不存储海森矩阵,只有一个对海森矩阵大小受限的更新步骤。 

 

2. 使用导数信息 

 

3. 可以把解决方法限制到box里,是optim中仅有的方法。

 

 

SANN method


模拟退火法(simulated annealing)的变种。


 

特点: 

1. 随机算法 

2. 接受以正概率提升目标的改变 

3. 不使用导数信息 

4. 收敛很慢,但是找到一个good solution很快Brent method

 

An interface to optimize

特点: 

1. 仅适用于一维问题 

 

2. 可以在其他函数中包含How to use

 

 

 

Exampels

 


One Dimensional Ex1

optim假定 

其导数为 

# we supply negative f, since we want to maximize.

f <- function(x) -exp(-( (x-2)^2 ))

######### without derivative

# I am using 1 at the initial value

# $par extracts only the argmax and nothing else

optim(1, f)$par

######### with derivative

df <- function(x) -2*(x-2)*f(x)

optim(1, f, df, method="CG")$par

######### with "Brent" method

 

optim(1,f,method="Brent",lower=-0,upper=3)$par

# figure

x = seq(0,3,length.out = 100)

y = f(x)

plot(x,y)

 

 

One Dimensional Ex2

 

#算法可以很快地发现与初值相近的局部最优值。

f <- function(x) sin(x*cos(x))

optim(2, f)$par

optim(4, f)$par

optim(6, f)$par

optim(8, f)$par

 

 

 

 


Two Dimensional Ex3

 

Rosenbrock function: This function is strictly positive, but is 0 when y = x^2, and x = 1, so (1, 1) is a minimum. 

Let’s see if optim can figure this out. When using optim for multidimensional optimization, the input in your function definition must be a single vector.

 


# 绘图

f <- function(x1,y1) (1-x1)^2 + 100*(y1 - x1^2)^2

x <- seq(-2,2,by=.15)

y <- seq(-1,3,by=.15)

z <- outer(x,y,f)

persp(x,y,z,phi=45,theta=-45,col="yellow",shade=.00000001,ticktype="detailed")

# 求解

f <- function(x) (1-x[1])^2 + 100*(x[2]-x[1]^2)^2

# starting values must be a vector now

optim( c(0,0), f )$par

[1] 0.9999564 0.9999085

 

Two Dimensional Ex4

Himmelblau’s function:

 

 

 

 

 

There appear to be four “bumps” that look like minimums in the realm of (-4,-4), (2,-2),(2,2) and (-4,4). 

 

Again this function is strictly positive so the function is minimized when x^2 + y − 11 = 0 and x + y^2 − 7 = 0.


#画图

f <- function(x1,y1) (x1^2 + y1 - 11)^2 + (x1 + y1^2 - 7)^2

x <- seq(-4.5,4.5,by=.2)

y <- seq(-4.5,4.5,by=.2)

z <- outer(x,y,f)

persp(x,y,z,phi=-45,theta=45,col="yellow",shade=.65 ,ticktype="detailed")

#求解局部最优值

f <- function(x) (x[1]^2 + x[2] - 11)^2 + (x[1] + x[2]^2 - 7)^2

optim(c(-4,-4),f)$par
optim(c(2,-2), f)$par
optim(c(2,2), f)$par

optim(c(-4,4),f)$par

 

#which are indeed the true minimums. This can be checked by seeing that #these inputs  correspond to function values that are about 0.

 

 

Minimise residual sum of squares

# 初始化数据

d = data_frame(x=1:6,y=c(1,3,5,6,8,12))

d

ggplot(d,aes(x,y)) + geom_point() +  stat_smooth(method = "lm")

# 最小问题的优化函数

min.RSS = function(data,par) {
    with(data,sum((par[1]+par[2]*x-y)^2))

}

#optim函数调用的格式

result = optim(par=c(0,0),min.RSS,data=d)

#optim调用的结果参数

result$par
result$value
result$counts
result$convergence
result$message

 

#可视化分析结果

 

ggplot(d,aes(x,y)) + geom_point() +geom_abline(intercept=result$par[1],

    slope=result$par[2],color="red")

 

 

#optim与lm的结果对比分析

lm(y~x,data=d)

result$par


Maximum likelihood

To fit a Poisson distribution to x I don’t minimise the residual sum of  squares, instead I maximise the likelihood for the chosen parameter lambda.


# 观测数据

obs = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 17, 42, 43)

freq = c(1392, 1711, 914, 468, 306, 192, 96, 56, 35, 17, 15, 6, 2, 2, 1, 1)

x <- rep(obs, freq)

plot(table(x), main="Count data")

qplot(x,stat_bin=1)

 

# 优化函数,注意“-”号

 

lklh.poisson <- function(x, lambda) lambda^x/factorial(x) * exp(-lambda)

log.lklh.poisson <- function(x, lambda){ 

    -sum(x * log(lambda) - log(factorial(x)) - lambda) 

}

 

 

# 调用optim

optim(par=2,log.lklh.poisson,x=x)

optim(par=2,log.lklh.poisson,x=x,method="Brent",lower=2,upper=3)

# 比较结果

library(MASS)

fitdistr(x, "Poisson")

mean(x)

# 系统信息

sessionInfo()

 


总结:这个函数需要知道所求最小值函数的表达式、

f = function(x,a) (x-a)^2
xmin = optimize(f,interval = c(0,1),a=1/3)
xminf <- function(x) -exp(-( (x-2)^2 ))######### without derivative# I am using 1 at the initial value# $par extracts only the argmax and nothing elseoptim(1, f)$par######### with derivativedf <- function(x) -2*(x-2)*f(x)optim(1, f, df, method="CG")$par######### with "Brent" methodoptim(1,f,method="Brent",lower=-0,upper=3)$par# figurex = seq(0,3,length.out = 100)y = f(x)plot(x,y)

 

 

$minimum
[1] 0.3333333

$objective
[1] 0

 

[1] 1.9
Warning message:
In optim(1, f) : 用Nelder-Mead方法来算一维优化不很可靠:
用"Brent"或直接用optimize()

[1] 2

[1] 2

 

f <- function(x) sin(x*cos(x))optim(2, f)$paroptim(4, f)$paroptim(6, f)$paroptim(8, f)$par

 

[1] 2.316016

> optim(4, f)$par
[1] 4.342236
Warning message:

> optim(6, f)$par
[1] 5.688647
Warning message:
In optim(6, f) : 用Nelder-Mead方法来算一维优化不很可靠:
用"Brent"或直接用optimize()
> optim(8, f)$par
[1] 7.132227
Warning message:
In optim(8, f) : 用Nelder-Mead方法来算一维优化不很可靠:

# 绘图f <- function(x1,y1) (1-x1)^2 + 100*(y1 - x1^2)^2x <- seq(-2,2,by=.15)y <- seq(-1,3,by=.15)z <- outer(x,y,f)persp(x,y,z,phi=45,theta=-45,col="yellow",shade=.00000001,ticktype="detailed")

# 求解f <- function(x) (1-x[1])^2 + 100*(x[2]-x[1]^2)^2# starting values must be a vector nowoptim( c(0,0), f )$par

> optim( c(0,0), f )$par
[1] 0.9999564 0.9999085

#画图f <- function(x1,y1) (x1^2 + y1 - 11)^2 + (x1 + y1^2 - 7)^2x <- seq(-4.5,4.5,by=.2)y <- seq(-4.5,4.5,by=.2)z <- outer(x,y,f)persp(x,y,z,phi=-45,theta=45,col="yellow",shade=.65 ,ticktype="detailed")#求解局部最优值f <- function(x) (x[1]^2 + x[2] - 11)^2 + (x[1] + x[2]^2 - 7)^2optim(c(-4,-4),f)$par
optim(c(2,-2), f)$par
optim(c(2,2), f)$paroptim(c(-4,4),f)$par

> optim(c(-4,-4),f)$par
[1] -3.779347 -3.283172
> optim(c(2,-2), f)$par
[1]  3.584370 -1.848105
> optim(c(2,2), f)$par
[1] 3.000014 2.000032
> optim(c(-4,4),f)$par
[1] -2.805129  3.131435
> optim(c(-4,4),f)$par
[1] -2.805129  3.131435

Minimise residual sum of squares# 初始化数据d = data_frame(x=1:6,y=c(1,3,5,6,8,12))dggplot(d,aes(x,y)) + geom_point() +  stat_smooth(method = "lm")# 最小问题的优化函数min.RSS = function(data,par) {with(data,sum((par[1]+par[2]*x-y)^2))}#optim函数调用的格式result = optim(par=c(0,0),min.RSS,data=d)#optim调用的结果参数result$parresult$valueresult$countsresult$convergenceresult$message#可视化分析结果ggplot(d,aes(x,y)) + geom_point() +geom_abline(intercept=result$par[1],slope=result$par[2],color="red")#optim与lm的结果对比分析lm(y~x,data=d)result$par

 

> d
    x  y z
1   0  1 a
2   1  2 b
3   2  3 c
4   3  4 a
5   4  5 b
6   5  6 c
7   6  7 a
8   7  8 b
9   8  9 c
10  9 10 a
11 10 11 b
12 11 12 c
13 12 13 a
14 13 14 b
15 14 15 c

 

 

> result$par
[1] 0.9998865 0.9999687

 result$value
[1] 1.934804e-06
> result$counts
function gradient 
      79       NA 
> result$convergence
[1] 0
> result$message
NULL

 

 

 

# 观测数据obs = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 17, 42, 43)freq = c(1392, 1711, 914, 468, 306, 192, 96, 56, 35, 17, 15, 6, 2, 2, 1, 1)x <- rep(obs, freq)plot(table(x), main="Count data")qplot(x,stat_bin=1)# 优化函数,注意“-”号lklh.poisson <- function(x, lambda) lambda^x/factorial(x) * exp(-lambda)log.lklh.poisson <- function(x, lambda){ -sum(x * log(lambda) - log(factorial(x)) - lambda) }# 调用optimoptim(par=2,log.lklh.poisson,x=x)optim(par=2,log.lklh.poisson,x=x,method="Brent",lower=2,upper=3)# 比较结果library(MASS)fitdistr(x, "Poisson")mean(x)# 系统信息sessionInfo()总结:这个函数需要知道所求最小值函数的表达式、

 

 

> optim(par=2,log.lklh.poisson,x=x)
$par
[1] 2.703516

$value
[1] 9966.067

$counts
function gradient 
      24       NA 

$convergence
[1] 0

$message
NULL

Warning message:
In optim(par = 2, log.lklh.poisson, x = x) :
  用Nelder-Mead方法来算一维优化不很可靠:
用"Brent"或直接用optimize()

> optim(par=2,log.lklh.poisson,x=x,method="Brent",lower=2,upper=3)
$par
[1] 2.703682

$value
[1] 9966.067

$counts
function gradient 
      NA       NA 

$convergence
[1] 0

$message
NULL
 

> # 比较结果
> library(MASS)
> fitdistr(x, "Poisson")
     lambda  
  2.70368239 
 (0.02277154)

 

> mean(x)
[1] 2.703682

> sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=Chinese (Simplified)_China.936  LC_CTYPE=Chinese (Simplified)_China.936   
[3] LC_MONETARY=Chinese (Simplified)_China.936 LC_NUMERIC=C                              
[5] LC_TIME=Chinese (Simplified)_China.936    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] MASS_7.3-47   ggplot2_2.2.1

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.13     lattice_0.20-35  rCharts_0.4.5    grid_3.4.1       plyr_1.8.4       gtable_0.2.0     scales_0.5.0    
 [8] rlang_0.1.4      lazyeval_0.2.1   whisker_0.3-2    labeling_0.3     RJSONIO_1.3-0    tools_3.4.1      munsell_0.4.3   
[15] yaml_2.1.16      compiler_3.4.1   colorspace_1.3-2 tibble_1.3.4    


http://chatgpt.dhexx.cn/article/mD3bk77u.shtml

相关文章

PyTorch基础(六)-- optim模块

PyTorch的optim是用于参数优化的库&#xff08;可以说是花式梯度下降&#xff09;&#xff0c;optim文件夹主要包括1个核心的父类&#xff08;optimizer&#xff09;、1个辅助类&#xff08;lr_scheduler&#xff09;以及10个常用优化算法的实现类。optim中内置的常用算法包括a…

pytorch基础(四):使用optim优化函数

文章目录 前言一、问题描述二、官方文档代码三、optimizer的工作原理总结 前言 本系列主要是对pytorch基础知识学习的一个记录&#xff0c;尽量保持博客的更新进度和自己的学习进度。本人也处于学习阶段&#xff0c;博客中涉及到的知识可能存在某些问题&#xff0c;希望大家批评…

HTTP协议之GET与POST区别

GET和POST是HTTP请求的两种基本方式&#xff0c;对于这两种请求方式的区别&#xff0c;只要是接触过Web开发的就能说出一二&#xff1a;GET把参数包含在URL中&#xff0c;POST通过正文传参&#xff01; 而我想深入了解以下的时候&#xff0c;就去了w3cschool&#xff0c;这是w…

Get和Post区别是什么

附上原文地址&#xff1a;https://www.cnblogs.com/logsharing/p/8448446.html GET和POST是HTTP请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中&#xff0c;POST通过request body传递参数。…

get与post区别(很全~)

get与post区别 GET&#xff1a; &#xff08;1&#xff09;从指定的资源请求数据 &#xff08;2&#xff09;请求数据有长度限制&#xff08;不同每个浏览器限制长度可能不一样&#xff09; &#xff08;3&#xff09;请求url会在浏览器地址栏中显示 &#xff08;4&#x…

Web中get和post区别

99% 的人都理解错了 HTTP 中 GET 与 POST 的区别&#xff08;转&#xff09; 转自&#xff1a;WebTechGarden 微信公众号GET 和 POST 是 HTTP 请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过 WEB 开发的人都能说出一二。最直观的区别就是 GET 把参数包含在 U…

get,post区别

Http定义了与服务器交互的不同方法&#xff0c;最基本的方法有4种&#xff0c;分别是GET&#xff0c;POST&#xff0c;PUT&#xff0c;DELETE。URL全称是资源描述符&#xff0c;我们可以这样认为&#xff1a;一个URL地址&#xff0c;它用于描述一个网络上的资源&#xff0c;而H…

GET 与 POST 区别

GET和POST是HTTP请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中&#xff0c;POST通过request body传递参数。 你可能自己写过无数个GET和POST请求&#xff0c;或者已经看过很多权威网站总结出…

GET和POST区别及缓存问题

2.就是get和post区别的缓存问题。 首先要了解什么是缓存。 HTTP缓存的基本目的就是使应用执行的更快&#xff0c;更易扩展&#xff0c;但是HTTP缓存通常只适用于idempotent request&#xff08;可以理解为查询请求&#xff0c;也就是不更新服务端数据的请求&#xff09;&#x…

Get与Post区别与范例讲解

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka 一、 J2EE WEB应用文件目录结构 Java Web应用由一组静态HTML页、Servlet、JSP和其他相关的class组成&#xff0c;它们一起构成一个大的工程项目。每种组件在Web应用中都有固定的存放目录。Web应用的配…

GET和POST区别详解

GET和POST是HTTP请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中&#xff0c;POST通过request body传递参数。 你可能自己写过无数个GET和POST请求&#xff0c;或者已经看过很多权威网站总结出…

get和post区别

GET和POST的安全性 1、GET是通过URL方式请求&#xff0c;可以直接看到&#xff0c;明文传输 2、POST是通过请求header请求&#xff0c;可以开发者工具或者抓包可以看到&#xff0c;同样也是明文的 3、GET请求会保存在浏览器历史纪录中&#xff0c;还可能会保存在Web的日志中 G…

post和get区别

GET和POST是HTTP请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中&#xff0c;POST通过request body传递参数。 你可能自己写过无数个GET和POST请求&#xff0c;或者已经看过很多权威网站总结出…

GET 和 POST 有什么区别?

GET 和 POST 是 HTTP 请求中最常用的两种请求方法&#xff0c;在日常开发的 RESTful 接口中&#xff0c;都能看到它们的身影。而它们之间的区别&#xff0c;也是一道常见且经典的面试题&#xff0c;所以我们本文就来详细的聊聊。 HTTP 协议定义的方法类型总共有以下 10 种&…

查找(一)——静态查找表

目录 一、查找的基本概念 二、顺序查找 &#xff08;线性查找&#xff09; 1、基本思想 2、核心代码 3、顺序查找设置哨兵 4、顺序查找的优点&#xff1a; 5、顺序查找的缺点&#xff1a; 6、折半查找 7、折半查找判定树 8、线性表查找的特点 三、索引顺序表&#x…

查找表结构

查找表介绍 在日常生活中&#xff0c;几乎每天都要进行一些查找的工作&#xff0c;在电话簿中查阅某个人的电话号码&#xff1b;在电脑的文件夹中查找某个具体的文件等等。本节主要介绍用于查找操作的数据结构——查找表。 查找表是由同一类型的数据元素构成的集合。例如电话号…

数据结构 第八章 查找(静态查找表)

集合 1、集合中的数据元素除了属于同一集合外,没有任何的逻辑关系 2、在集合中,每个数据元素都有一个区别于其他元素的唯一标识(键值或者关键字值) 3、集合的运算&#xff1a; 1 查找某一元素是否存在(内部查找、外部查找) 2 将集合中的元素按照它的唯一标识进行排序4、集合的…

9.1 查找表:静态查找表

9.1 查找表&#xff1a;静态查找表. 9.2 查找表&#xff1a;动态查找表. 9.3 查找表&#xff1a;哈希表. 9.1 查找表&#xff1a;静态查找表 1 基本概念2 抽象数据类型3 顺序查找表3.1 顺序存储结构模块中的实现3.2 分析顺序查找的时间性能. 4 有序查找表4.1 代码实现4.2 折半查…

数据结构----查找表

前言 突然发现自己过得茫茫然&#xff0c;学过的东西&#xff0c;似懂非懂&#xff0c;不知所以。昨晚打开以前瞎写 的博客&#xff0c;又来了兴趣。 人在反思中成长&#xff0c;在总结中进步。加油&#xff01;目录 前言 查找表 正文静态查找表顺序查找表有序查找表索引查找表…

sql server查找表的字段信息

查找表的字段信息 SELECT (case when a.colorder1 then d.name else end) N表名, a.colorder N字段序号, a.name N字段名, (case when COLUMNPROPERTY( a.id,a.name,IsIdentity)1 then √else end) N标识, (case when (SELECT count(*) FROM sysobjects WHERE (name in (SEL…