0
点赞
收藏
分享

微信扫一扫

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解

醉东枫 2022-11-14 阅读 98

本文将介绍R中可用于投资组合优化的不同求解器。

通用求解器

通用求解器可以处理任意的非线性优化问题,但代价可能是收敛速度慢。

默认包

包stats(默认安装的基本R包)提供了几个通用的优化程序。

  • optimize()。用于区间内的一维无约束函数优化(对于一维求根,使用uniroot())。
  1.  f <- function(x) exp(-0.5*x) * sin(10*pi*x)
  2.  f(0.5)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化

 

  1.   
  2.   
  3.  result <- optimize(f, interval = c(0, 1), tol = 0.0001)
  4.  result
  5.   
  6.   
  7.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_02

  1.  # 绘制
  2.  curve(0, 1, n = 200)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_03

  • ​optim()通用优化,有六种不同的优化方法。​
  • ​Nelder-Mead:相对稳健的方法(默认),不需要导数。​
  • ​CG:适用于高维无约束问题的低内存优化​
  • ​BFGS:简单的无约束的准牛顿方法​
  • ​L-BFGS-B:用于边界约束问题的优化​
  • ​SANN​​: 模拟退火法
  • ​Brent​​: 用于一维问题(实际上是调用optimize())。

这个例子做了一个最小二乘法拟合:最小化

 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_04

  1.  # 要拟合的数据点
  2.  # 线性拟合的l2-norm误差平方 y ~ par[1] + par[2]*x
  3.  # 调用求解器(初始值为c(0, 1),默认方法为 "Nelder-Mead")。
  4.  optim(par = c(0, 1), f, data = dat)
  5.   
  6.   
  7.  # 绘制线性回归图

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_05

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_06

  1.  # 与R中内置的线性回归进行比较
  2.  lm(y ~ x, data = dat)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_07

下一个例子说明了梯度的使用,著名的Rosenbrock香蕉函数:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_08

,梯度

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_09

,无约束最小化问题

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_10

  1.  # Rosenbrock香蕉函数及其梯度
  2.  banana <- function(x)
  3.  c(-400 * x[1] * (x[2] - x[1] * x[1]) - 2 * (1 - x[1]),
  4.  200 * (x[2] - x[1] * x[1]))
  5.  optim(c(-1.2, 1), f_banana)
  6.   
  7.   
  8.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_11

optim(c(-1.2, 1), f, gr, method = "BFGS")

下面的例子使用了界约束。

最小化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_12

约束: 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_13

  1.  p <- length(x); sum(c(1, rep(4, p-1)) * (x - c(1, x[-p])^2)^2) }
  2.  # 25维度约束
  3.  optim(rep(3, 25), f,lower = rep(2, 25), upper = rep(4

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_14

这个例子使用模拟退火法(用于全局优化)。

  1.  #全局最小值在-15左右
  2.  res <- optim(50, f, method = "SANN")
  3.   
  4.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_15

  1.   
  2.  # 现在进行局部改进(通常只改进了一小部分)
  3.  optim(res$par, f , method = "BFGS")

 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_16

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_17

  • constrOptim()。使用自适应约束算法,在线性不等式约束下最小化一个函数(调用optim())。

  1.  # 不等式约束(ui %*% theta >= ci): x <= 0.9, y - x > 0.1
  2.  constrOptim(c(.5, 0)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_18

 

  • ​nlm()​​: 这个函数使用牛顿式算法进行目标函数的最小化。
  1.  nlm(f, c(10,10))
  2.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_19

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_20

  • ​nlminb()​​: 进行无界约束优化。.
  1.  nlminb(c(-1.2, 1), f)
  2.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_21

  1.  nlminb(c(-1.2, 1), f, gr)
  2.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_22

optim

基础函数optim()作为许多其他求解器的包,可以方便地使用和比较。

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_23

  1.  # opm() 可以同时使用几个方法
  2.  opm( f , method = c("Nelder-Mead", "BFGS"))

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_24

全局优化

全局优化与局部优化的理念完全不同(全局优化求解器通常被称为随机求解器,试图避免局部最优点)。

特定类别问题的求解器

如果要解决的问题属于某一类问题,如LS、LP、MILP、QP、SOCP或SDP,那么使用该类问题的专用求解器会更好。
 

最小二乘法 (LS)

线性最小二乘法(LS)问题是将

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_25

最小化,可能有界或线性约束。

线性规划(LP)

函数solveLP(),可以方便地解决以下形式的LP:

最小化:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_26

约束:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_27

  1.  #> 加载所需软件包
  2.   
  3.   
  4.  cvec <- c(1800, 600, 600) # 毛利率
  5.  bvec <- c(40, 90, 2500) # 捐赠量
  6.   
  7.  # 运行求解器
  8.  solveLP(maximum = TRUE)

 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_28

混合整数线性规划 (MILP)

lpSolve(比linprog快得多,因为它是用C语言编码的)可以解决线性混合整数问题(可能带有一些整数约束的LP)。

  1.   
  2.  # 设置问题:
  3.  # maximize x1 + 9 x2 + x3
  4.  # subject to x1 + 2 x2 + 3 x3 <= 9
  5.  # 3 x1 + 2 x2 + 2 x3 <= 15
  6.   
  7.  # 运行求解
  8.  res <- lp("max", f, con)
  9.   
  10.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_29

 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_30

  1.   
  2.  # 再次运行,这次要求三个变量都是整数
  3.  lp( int.vec = 1:3)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_31

solution

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_32

二次规划 (QP)

可以方便地解决以下形式的QP

  1.  最小化:
  2.  约束:
  3.   
  4.  # 设置问题:
  5.  # minimize -(0 5 0) %*% x + 1/2 x^T x
  6.  # subject to A^T x >= b
  7.  # with b = (-8,2,0)^T
  8.  # (-4 2 0)
  9.  # A = (-3 1 -2)
  10.  # ( 0 0 1)
  11.   
  12.  #运行求解
  13.  solve(Dmat,...)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_33

解决具有绝对值约束和目标函数中的绝对值的二次规划。

二阶锥规划 (SOCP)

有几个包:

  • ECOSolveR提供了一个与嵌入式COnic Solver(ECOS)的接口,这是一个著名的、高效的、稳健的C语言库,用于解决凸问题。
  • CLSOCP提供了一个用于解决SOCP问题的一步平滑牛顿方法的实现。

优化基础

我们已经看到了两个包,它们是许多其他求解器的包。

用于凸问题、MIP和非凸问题

ROI包为处理R中的优化问题提供了一个框架。它使用面向对象的方法来定义和解决R中的各种优化任务,这些任务可以来自不同的问题类别(例如,线性、二次、非线性规划问题)。

LP – 考虑 LP:

最大化:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_34

约束:

 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_35

  1.  #> ROI: R 优化基础设施
  2.  #> 求解器插件: nlminb, ecos, lpsolve, scs.
  3.  #> 默认求解器: auto.
  4.   
  5.  OP(objective = L_objective(c(3, 7, -12)),...,
  6.  maximum = TRUE)
  7.   
  8.  #> 投资回报率优化问题:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_36

  1.   
  2.  # 让我们来看看可用的求解器
  3.   
  4.  # solve it
  5.  res <- ROI_solve(prob)
  6.  res

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_37

 

MILP – 考虑先前的LP,并通过添加约束条件x2,x3∈Z使其成为一个MILP.

  1.  # 只需修改之前的问题
  2.  types(prob) <- c("C", "I", "I")
  3.  prob

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_38

 

BLP – 考虑二元线性规划 (BLP):

最小化:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_39

约束:

 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_40

  1.  OP(objective = L_objective,..., ,
  2.  types = rep("B", 5))
  3.  ROI_solve(prob)
  4.   
  5.  #> Optimal solution found.
  6.  #> The objective value is: -1.01e+02

SOCP – 考虑SOCP:

最大化:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_41

约束:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_42

并注意到SOC约束 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_43

 可以写成

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_44

或 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_45

,在代码中实现为:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_46


  1.  OP(objective = L_objective,...,
  2.  maximum = TRUE)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_47

 

SDP--考虑SDP:

最小化:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_48

约束:

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_49

并注意SDP约束

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_50

可以写成

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_51

(大小为3是因为在我们的问题中,矩阵为2×2,但vech()提取了3个独立变量,因为矩阵是对称的)。

  1.  OP(objective = L_objective,...,
  2.  rhs ))
  3.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_52

NLP – 考虑非线性规划(NLP)

最大化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_53

约束

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_54

  1.  OP(objective = F_objective,..., bounds ,
  2.  maximum = TRUE)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_55

 

凸优化

R为凸优化提供了一种面向对象的建模语言。它允许用户用自然的数学语法来制定凸优化问题,而不是大多数求解器所要求的限制性标准形式。通过使用具有已知数学特性的函数库,结合常数、变量和参数来指定目标和约束条件集。现在让我们看看几个例子。

最小二乘法 – 让我们从一个简单的LS例子开始:最小化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_56

当然,我们可以使用R的基础线性模型拟合函数lm()。

  1.  # 生成数据
  2.  m <- 100
  3.  n <- 10
  4.  beta_true <- c(-4:5)
  5.   
  6.   
  7.  # 生成数据
  8.  res <- lm(y ~ 0 + X) # 0表示我们的模型中没有截距。
  9.   

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_57

 

用CVXR来做

  1.   
  2.  result <- solve(prob)
  3.  str(result)

 

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_58

  

我们现在可以很容易地添加一个限制条件来解决非负的LS。

  1.  Problem(Minimize(obj), constraints = list(beta >= 0))
  2.  solve(prob)

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_59

稳健的Huber回归 - 让我们考虑稳健回归的简单例子:

最小化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_60

其中

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_61

  1.  sum(huber(y - X %*% beta, M)
  2.  Problem(Minimize(obj))
  3.  solve(prob)
  4.   

弹性网正则化 - 我们现在要解决的问题是:最小化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_最小化_62

  1.  # 定义正则化项
  2.  elastic<- function(beta) {
  3.  ridge <- (1 - alpha) * sum(beta^2)
  4.  lasso <- alpha * p_norm(beta, 1)
  5.   
  6.   
  7.  # 定义问题并解决它
  8.   
  9.  sum((y - X %*% beta)^2) + elastic(beta, lambda, alpha)
  10.  Problem(Minimize(obj))
  11.  solve(prob)

稀疏逆协方差矩阵--考虑矩阵值的凸问题:最大化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_63

,条件是

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_64

  1.  log_det(X) - matrix_trace(X %*% S)
  2.  list(sum(abs(X)) <= alpha)

协方差--考虑矩阵值的凸问题:在

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_65

的条件下,最大化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_66


  1.   
  2.  constr <- list(Sigma[1,1] == 0.2, Sigma[1,2] >= 0, Sigma[1,3] >= 0,
  3.  Sigma[2,2] == 0.1, Sigma[2,3] <= 0, Sigma[2,4] <= 0,
  4.  Sigma[3,3] == 0.3, Sigma[3,4] >= 0, Sigma[4,4] == 0.1)

投资组合优化--考虑马科维茨投资组合设计:最大化

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_67


拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_数据_68

  1.  Problem(Maximize(obj), constr)
  2.  solve(prob)

结论

R语言中可用的求解器的数量很多。建议采取以下步骤。

  • 如果是凸优化问题,那么开始进行初步测试。
  • 如果速度不够快,使用ROI。
  • 如果仍然需要更快的速度,那么如果问题属于定义好的类别之一,则使用该类别专用的求解器(例如,对于LP,推荐使用lpSolve,对于QP则使用quadprog)。
  • 然而,如果问题不属于任何类别,那么就必须使用非线性优化的一般求解器。在这个意义上,如果一个局部的解决方案就够了,那么可以用许多求解器的包。如果需要全局求解器,那么软件包gloptim是一个不错的选择,它是许多全局求解器的包。

拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解_r语言_69

举报

相关推荐

0 条评论