使用Rsolnp进行优化

时间:2015-05-20 10:00:22

标签: r optimization

我的数据框看起来像这样

> Data_bounded
       Key channel oas        spend      beta        alpha  LB UB        Lower        Upper
1  DRM_BBY     DRM BBY 3.599127e+06 0.4355527 3.790177e+04  30 30 2.519389e+06 4.678865e+06
2  DRM_ESS     DRM ESS 1.560708e+07 1.0000000 0.000000e+00  30 30 1.092496e+07 2.028921e+07
3  DRM_STG     DRM STG 2.053543e+06 0.4846562 6.602477e+04  30 30 1.437480e+06 2.669605e+06
4  DRM_UNU     DRM UNU 2.541332e+06 0.5000000 1.296799e+03  30 30 1.778932e+06 3.303732e+06
5  EML_BBY     EML BBY 0.000000e+00 1.0000000 0.000000e+00   0  0 0.000000e+00 0.000000e+00
6  EML_BTY     EML BTY 0.000000e+00 1.0000000 0.000000e+00   0  0 0.000000e+00 0.000000e+00
7  EML_SHL     EML SHL 0.000000e+00 1.0000000 0.000000e+00   0  0 0.000000e+00 0.000000e+00
8  ETC_BTY     ETC BTY 0.000000e+00 1.0000000 0.000000e+00 100 10 0.000000e+00 0.000000e+00
9  ETC_ESS     ETC ESS 3.040605e+06 0.5430741 3.661138e+03 100 10 0.000000e+00 3.344666e+06
10 ETC_LAM     ETC LAM 2.184844e+07 0.5570489 2.379726e+04 100 10 0.000000e+00 2.403328e+07
11 ETN_ESS     ETN ESS 2.571237e+06 0.5122024 1.400936e+03 100 10 0.000000e+00 2.828361e+06
12 ETN_LAM     ETN LAM 3.446503e+07 0.6619932 5.246261e+03 100 10 0.000000e+00 3.791154e+07
13 ETS_BTY     ETS BTY 0.000000e+00 1.0000000 0.000000e+00 100 10 0.000000e+00 0.000000e+00
14 ETS_ESS     ETS ESS 3.179937e+05 0.5747293 4.705728e+03 100 10 0.000000e+00 3.497930e+05
15 ETS_LAM     ETS LAM 4.071746e+06 0.7597932 2.232724e+03 100 10 0.000000e+00 4.478921e+06
16 FSI_BTY     FSI BTY 7.093370e+04 1.0000000 0.000000e+00   5 60 6.738701e+04 1.134939e+05
17 FSI_STG     FSI STG 5.852890e+05 0.3000000 1.216848e+06   5 60 5.560246e+05 9.364624e+05
18 MAG_BBY     MAG BBY 1.591777e+06 0.5816724 1.753382e+04  10  5 1.432599e+06 1.671366e+06
19 MAG_BTY     MAG BTY 8.526921e+06 0.3000000 1.704103e+05  10  5 7.674229e+06 8.953267e+06
20 MAG_SHL     MAG SHL 5.546460e+05 0.6597280 1.604735e+03  10  5 4.991814e+05 5.823783e+05
21 MAG_UNU     MAG UNU 6.349920e+05 0.7000000 2.145462e+02  10  5 5.714928e+05 6.667416e+05
22 MSM_BTY     MSM BTY 5.953225e+06 1.0000000 0.000000e+00  30 30 4.167258e+06 7.739193e+06
23 MSM_CLI     MSM CLI 3.095554e+05 1.0000000 0.000000e+00  30 30 2.166888e+05 4.024220e+05
24 MSM_STG     MSM STG 2.051692e+06 0.5000000 1.161424e+03  30 30 1.436184e+06 2.667199e+06
25 OND_BBY     OND BBY 1.195467e+06 0.4000000 1.279868e+03  20 20 9.563732e+05 1.434560e+06
26 OND_BTY     OND BTY 7.513692e+05 0.3048512 3.194817e+05  20 20 6.010953e+05 9.016430e+05
27 OND_CLI     OND CLI 1.901847e+05 0.5009272 1.597470e+03  20 20 1.521478e+05 2.282217e+05
28 OND_ESS     OND ESS 8.269617e+05 0.3000000 1.479966e+05  20 20 6.615694e+05 9.923540e+05
29 OND_SHL     OND SHL 2.844579e+06 0.5606207 5.739453e+02  20 20 2.275663e+06 3.413495e+06
30 OND_STG     OND STG 6.673592e+04 1.0000000 0.000000e+00  20 20 5.338874e+04 8.008310e+04
31 OND_UNU     OND UNU 5.940489e+05 0.5097571 1.905513e+03  20 20 4.752391e+05 7.128586e+05
32 OOH_BBY     OOH BBY 3.149710e+05 1.0000000 0.000000e+00  10  5 2.834739e+05 3.307195e+05
33 OOH_BTY     OOH BTY 5.000000e-07 1.0000000 0.000000e+00  10  5 4.500000e-07 5.250000e-07
34 OOH_CLI     OOH CLI 1.299990e+05 0.3000000 1.657615e+04  10  5 1.169991e+05 1.364990e+05
35 OOH_STG     OOH STG 7.059643e+02 1.0000000 0.000000e+00  10  5 6.353679e+02 7.412625e+02
36 PSS_BBY     PSS BBY 9.281210e+05 0.7092288 2.608441e+02  10 10 8.353089e+05 1.020933e+06
37 PSS_BTY     PSS BTY 7.408000e+04 0.4885998 1.246914e+04  10 10 6.667200e+04 8.148800e+04
38 PSS_CLI     PSS CLI 7.849900e+04 0.7897747 1.361035e+02  10 10 7.064910e+04 8.634890e+04
39 PSS_SHL     PSS SHL 1.003498e+06 0.5183048 8.555700e+03  10 10 9.031482e+05 1.103848e+06
40 PSS_STG     PSS STG 3.353000e+05 0.3000000 3.811032e+05  10 10 3.017700e+05 3.688300e+05
41 PSS_UNU     PSS UNU 2.394850e+05 0.4749274 1.651913e+03  10 10 2.155365e+05 2.634335e+05
42 RAD_BBY     RAD BBY 9.182681e+05 0.5000000 1.979574e+03  10 10 8.264413e+05 1.010095e+06
43 RAD_ESS     RAD ESS 0.000000e+00 1.0000000 0.000000e+00  10 10 0.000000e+00 0.000000e+00
44 RAD_STG     RAD STG 2.852897e+06 0.4176579 4.354847e+04  10 10 2.567607e+06 3.138186e+06
45 RCM_BTY     RCM BTY 1.246777e+05 0.4000000 7.491181e+03   0 15 1.246777e+05 1.433794e+05
46 RCM_ESS     RCM ESS 2.242704e+04 1.0000000 0.000000e+00   0 15 2.242704e+04 2.579110e+04
47 RCM_FOB     RCM FOB 1.094317e+06 0.3684433 1.062531e+05   0 15 1.094317e+06 1.258465e+06
48 ROP_CLI     ROP CLI 1.564082e+05 1.0000000 0.000000e+00  20  5 1.251266e+05 1.642286e+05
49 ROP_SHL     ROP SHL 1.512256e+05 0.6284284 2.321274e+01  20  5 1.209804e+05 1.587868e+05
50 ROP_STG     ROP STG 6.431417e+06 0.4100540 1.510802e+04  20  5 5.145133e+06 6.752987e+06
51 STC_ESS     STC ESS 0.000000e+00 1.0000000 0.000000e+00 100 10 0.000000e+00 0.000000e+00
52 STC_LAM     STC LAM 2.822590e+05 0.6630324 6.334003e+03 100 10 0.000000e+00 3.104849e+05
53 STE_LAM     STE LAM 1.023410e+06 0.6736357 4.057302e+03  10  5 9.210691e+05 1.074581e+06
54 STN_ESS     STN ESS 0.000000e+00 1.0000000 0.000000e+00 100 10 0.000000e+00 0.000000e+00
55 STN_LAM     STN LAM 4.273955e+06 0.7610039 3.018853e+03 100 10 0.000000e+00 4.701351e+06
56 STS_ESS     STS ESS 0.000000e+00 1.0000000 0.000000e+00  10  5 0.000000e+00 0.000000e+00
57 STS_LAM     STS LAM 5.558187e+05 0.4623422 5.090183e+04  10  5 5.002369e+05 5.836097e+05
58 VDO_ESS     VDO ESS 2.206729e+06 0.8000000 2.697051e+02   0 15 2.206729e+06 2.537739e+06
59 VDO_LAM     VDO LAM 2.759217e+06 0.7601210 8.131849e+01   0 15 2.759217e+06 3.173100e+06
60 VDO_UNU     VDO UNU 0.000000e+00 1.0000000 0.000000e+00   0 15 0.000000e+00 0.000000e+00

我正在使用优化包Rsolnp

现在我的目标是尽量减少功能:

-sum(阿尔法*支出^测试版)

受约束支出位于Lower和Upper之间,并且最佳支出值的总和等于列支出的总和。然而,解决方案并没有产生任何结果。任何帮助将不胜感激。我正在使用的代码是

Data_bounded是我的数据。

alpha<-Data_bounded$alpha
beta<-Data_bounded$beta

LB_data<-Data_bounded$Lower
UB_data<-Data_bounded$Upper

total_spend<-sum(Data_bounded$spend)

fn1<-function(x)
{
  z<-seq(0,0,length=nrow(Data_bounded))
  for(i in (1:nrow(Data_bounded))){
    z[i]<- alpha[i]*(x[i])^beta[i]
  }
  return(-sum(z))
}



eq1<-function(x)
{
  sum(x)
}


x0 = Data_bounded$spend

opti<-solnp(x0,fun=fn1,LB=LB_data,UB=UB_data,eqfun=eq1,eqB=total_spend)

optimum_spend<-opti$pars

> SAS_soln
   channel oas       spend    beta      alpha     key     UpperBd     LowerBd Optimum_Spend opt_Inc_Sales
1      DRM BBY  3599126.68 0.43555   37901.77 DRM_BBY  4678864.68  2519388.67    4678864.68    30468915.4
2      DRM ESS 15607084.43 1.00000       0.00 DRM_ESS 20289209.76 10924959.10   10924959.10             0
3      DRM STG  2053542.67 0.48466   66024.77 DRM_STG  2669605.47  1437479.87    2669605.47   85965546.97
4      DRM UNU  2541332.00 0.50000    1296.80 DRM_UNU  3303731.59  1778932.40    1778932.40    1729627.27
5      EML BBY        0.00 1.00000       0.00 EML_BBY        0.00        0.00          0.00             .
6      EML BTY        0.00 1.00000       0.00 EML_BTY        0.00        0.00          0.00             .
7      EML SHL        0.00 1.00000       0.00 EML_SHL        0.00        0.00          0.00             .
8      ETC BTY        0.00 1.00000       0.00 ETC_BTY        0.00        0.00          0.00             .
9      ETC ESS  3040605.45 0.54307    3661.14 ETC_ESS  3344666.00        0.00    3344666.00   12788595.53
10     ETC LAM 21848435.35 0.55705   23797.26 ETC_LAM 24033278.89        0.00   24033278.89   307610216.1
11     ETN ESS  2571237.02 0.51220    1400.94 ETN_ESS  2828360.72        0.00    1436429.44    1996155.78
12     ETN LAM 34465032.77 0.66199    5246.26 ETN_LAM 37911536.05        0.00   37911536.05     545688932
13     ETS BTY        0.00 1.00000       0.00 ETS_BTY        0.00        0.00          0.00             .
14     ETS ESS   317993.68 0.57473    4705.73 ETS_ESS   349793.05        0.00     349793.05    7224665.67
15     ETS LAM  4071746.49 0.75979    2232.72 ETS_LAM  4478921.14        0.00    4478921.14   252552248.9
16     FSI BTY    70933.70 1.00000       0.00 FSI_BTY   113493.92    67387.02      67387.02             0
17     FSI STG   585289.02 0.30000 1216848.42 FSI_STG   936462.43   556024.57     936462.43   75280689.89
18     MAG BBY  1591777.00 0.58167   17533.82 MAG_BBY  1671365.85  1432599.30    1671365.85   73057646.57
19     MAG BTY  8526921.00 0.30000  170410.33 MAG_BTY  8953267.05  7674228.90    8660097.95   20547204.92
20     MAG SHL   554646.00 0.65973    1604.74 MAG_SHL   582378.30   499181.40     582378.30   10206360.44
21     MAG UNU   634992.00 0.70000     214.55 MAG_UNU   666741.60   571492.80     666741.60    2560301.93
22     MSM BTY  5953225.18 1.00000       0.00 MSM_BTY  7739192.73  4167257.63    4167257.63             0
23     MSM CLI   309555.42 1.00000       0.00 MSM_CLI   402422.05   216688.80     216688.80             0
24     MSM STG  2051691.88 0.50000    1161.42 MSM_STG  2667199.44  1436184.32    1436184.32    1391860.93
25     OND BBY  1195466.55 0.40000    1279.87 OND_BBY  1434559.86   956373.24     956373.24     315802.98
26     OND BTY   751369.17 0.30485  319481.69 OND_BTY   901643.00   601095.33     901643.00   20885532.25
27     OND CLI   190184.72 0.50093    1597.47 OND_CLI   228221.67   152147.78     228221.67     771932.76
28     OND ESS   826961.70 0.30000  147996.58 OND_ESS   992354.04   661569.36     992354.04     9316476.3
29     OND SHL  2844578.87 0.56062     573.95 OND_SHL  3413494.65  2275663.10    2275663.10    2102793.14
30     OND STG    66735.92 1.00000       0.00 OND_STG    80083.10    53388.74      53388.74             0
31     OND UNU   594048.85 0.50976    1905.51 OND_UNU   712858.62   475239.08     712858.62    1834941.14
32     OOH BBY   314971.00 1.00000       0.00 OOH_BBY   330719.55   283473.90     283473.90             0
33     OOH BTY        0.00 1.00000       0.00 OOH_BTY        0.00        0.00          0.00             .
34     OOH CLI   129999.00 0.30000   16576.15 OOH_CLI   136498.95   116999.10     136498.95     575469.83
35     OOH STG      705.96 1.00000       0.00 OOH_STG      741.26      635.37        635.37             0
36     PSS BBY   928121.00 0.70923     260.84 PSS_BBY  1020933.10   835308.90    1020933.10    4765788.27
37     PSS BTY    74080.00 0.48860   12469.14 PSS_BTY    81488.00    66672.00      81488.00    3128929.49
38     PSS CLI    78499.00 0.78977     136.10 PSS_CLI    86348.90    70649.10      86348.90    1077457.67
39     PSS SHL  1003498.00 0.51830    8555.70 PSS_SHL  1103847.80   903148.20    1103847.80   11596424.97
40     PSS STG   335300.00 0.30000  381103.19 PSS_STG   368830.00   301770.00     368830.00   17827500.41
41     PSS UNU   239485.00 0.47493    1651.91 PSS_UNU   263433.50   215536.50     263433.50     620029.25
42     RAD BBY   918268.08 0.50000    1979.57 RAD_BBY  1010094.89   826441.27    1010094.89    1989541.09
43     RAD ESS        0.00 1.00000       0.00 RAD_ESS        0.00        0.00          0.00             .
44     RAD STG  2852896.79 0.41766   43548.47 RAD_STG  3138186.47  2567607.11    3138186.47      22509301
45     RCM BTY   124677.72 0.40000    7491.18 RCM_BTY   143379.38   124677.72     143379.38     865256.72
46     RCM ESS    22427.04 1.00000       0.00 RCM_ESS    25791.10    22427.04      22427.04             0
47     RCM FOB  1094317.32 0.36844  106253.06 RCM_FOB  1258464.92  1094317.32    1258464.92   18783966.92
48     ROP CLI   156408.20 1.00000       0.00 ROP_CLI   164228.61   125126.56     125126.56             0
49     ROP SHL   151225.56 0.62843      23.21 ROP_SHL   158786.84   120980.45     120980.45      36295.19
50     ROP STG  6431416.66 0.41005   15108.02 ROP_STG  6752987.49  5145133.33    5145133.33    8535764.15
51     STC ESS        0.00 1.00000       0.00 STC_ESS        0.00        0.00          0.00             .
52     STC LAM   282258.99 0.66303    6334.00 STC_LAM   310484.89        0.00     310484.89    27738245.2
53     STE LAM  1023410.08 0.67364    4057.30 STE_LAM  1074580.58   921069.07    1074580.58   46891593.84
54     STN ESS        0.00 1.00000       0.00 STN_ESS        0.00        0.00          0.00             .
55     STN LAM  4273955.04 0.76100    3018.85 STN_LAM  4701350.54        0.00    4701350.54   360935113.7
56     STS ESS        0.00 1.00000       0.00 STS_ESS        0.00        0.00          0.00             .
57     STS LAM   555818.74 0.46234   50901.83 STS_LAM   583609.68   500236.87     583609.68   23586050.24
58     VDO ESS  2206729.31 0.80000     269.71 VDO_ESS  2537738.71  2206729.31    2537738.71   35846491.57
59     VDO LAM  2759217.12 0.76012      81.32 VDO_LAM  3173099.69  2759217.12    3173099.69    7113833.91
60     VDO UNU        0.00 1.00000       0.00 VDO_UNU        0.00        0.00          0.00             .
   Spends_change
1            30%
2           -30%
3            30%
4           -30%
5              .
6              .
7              .
8              .
9            10%
10           10%
11          -44%
12           10%
13             .
14           10%
15           10%
16           -5%
17           60%
18            5%
19            2%
20            5%
21            5%
22          -30%
23          -30%
24          -30%
25          -20%
26           20%
27           20%
28           20%
29          -20%
30          -20%
31           20%
32          -10%
33             .
34            5%
35          -10%
36           10%
37           10%
38           10%
39           10%
40           10%
41           10%
42           10%
43             .
44           10%
45           15%
46         0.00%
47           15%
48          -20%
49          -20%
50          -20%
51             .
52           10%
53            5%
54             .
55           10%
56             .
57            5%
58           15%
59           15%
60             .

1 个答案:

答案 0 :(得分:3)

我花了一段时间来调试,但我做到了。首先,我对您的功能进行了一些改进,以使它们运行得更快:

library(Rsolnp)

#first thing to do is calculate the sum of data bounded before subsetting
#the Data_bounded data.frame below
total_spend<-sum(Data_bounded$spend)

#those rows with alpha=0 will always have spend=0 since you maximize.
#So, you don't need them in the calculation. You only cause it 
#to be more slow and increase the number of parameters
#when you know that these will always have spend=0
#Therefore I am excluding them
Data_bounded <- na.omit(Data_bounded[Data_bounded$alpha > 0,])

重要

你需要排除alpha == 0的行的另一个原因是,在许多情况下,你得到的下限等于零,上限也等于零,即花费变量不能取任何数字并产生NAN并导致算法失败(例如,请参见data.frame的最后一行)。

alpha<-Data_bounded$alpha
beta<-Data_bounded$beta

#this is what causes big trouble (see below in the answer)
LB_data<-Data_bounded$Lower
UB_data<-Data_bounded$Upper 


#I simplified your objective function. Using a for-loop is
#100 times slower
fn1<-function(spend)
{
  -sum(alpha * spend^beta)
}


#the constraint equation
eq1<-function(spend)
{
  sum(spend)
}

上述设置会导致非收敛,因为每个参数的下限和上限范围明显不同:

> summary(LB_data)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      0  105400  563800 1045000 1433000 7674000 
> summary(UB_data)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
   81490   529000  1089000  3367000  3206000 37910000 

使用这些使得无法计算粗麻布估计并且算法不收敛:

> solnp(rep(0.5,40),fun=fn1,LB=LB_data,UB=UB_data,eqfun=eq1,eqB=total_spend)

solnp-->The linearized problem has no feasible
solnp-->solution.  The problem may not be feasible.

Iter: 1 fn: -504199815.6409  Pars:  4667300.58566 1428556.94211 1769551.34256       0.50002       0.50002       0.50002       0.50002       0.50002       0.50002  920038.05845 1423762.10411 8943897.27854  506400.51947  655335.69677 1427283.02003 1424483.55152  892622.98201  142709.47599  984386.60168 3367895.50511  472422.09101  107401.43750 1010577.85985   57016.73234   60975.13135 1093896.28870  292081.76334  206116.88396  999731.21048 3128070.24034  115116.37073 1248989.03752  111401.37452 5138141.05109       0.50002 1065101.70687       0.50002  508212.67696 2209897.98640 3164060.56280
solnp--> Solution not reliable....Problem Inverting Hessian.

唯一的解决方案是为您的参数提供良好的界限(估计花费的总和显然仍然等于total_spend,所以这肯定是正确的)。这将有效:

#so just set all the boundaries between 0 and Inf. 
#solnp will easily be able to find the optimal parameters even though
#the search space is big.
#this took a few seconds on my laptop
opti<-solnp(rep(0.5,40),fun=fn1,LB=rep(0,40),UB=rep(Inf,40),eqfun=eq1,eqB=total_spend)

你获得了收敛和最佳价值!!

> opti
$pars
 [1] 5.214072e+05 5.457175e+05 1.226056e+02 2.459264e+04 6.727744e+06 4.592510e+02 1.144198e+07 3.482826e+05 2.222721e+07 1.146275e+06 7.594007e+06
[12] 1.338454e+05 1.903417e+05 3.010091e+01 3.705320e+06 1.092090e+00 4.652869e+05 2.935163e+01 3.307376e+03 2.073538e+02 4.628795e+04 1.267862e+03
[23] 4.366613e+02 1.796496e+06 1.396554e+03 3.488297e+06 7.859770e+05 2.858621e+06 1.218379e+02 2.200433e+05 3.241032e+02 3.490860e+04 1.837521e+00
[34] 3.846448e+04 1.237474e+07 1.134505e+07 2.552423e+07 5.201814e+06 1.525503e+06 3.634506e+00

$convergence
[1] 0

修改

现在您向我展示了SAS输出,我可以看到即使alpha为零,您也可以获得大于零的支出金额。记住这一点并且排除上限和下限为零的情况(花费这些意味着为零 - 与SAS输出相同)这可以工作和收敛并使用实际的上限和下边界:

library(Rsolnp)

#first thing to do is calculate the sum of data bounded before subsetting
#the Data_bounded data.frame below
total_spend<-sum(Data_bounded$spend)

Data_bounded <- na.omit(Data_bounded[!(Data_bounded$Lower == 0 & Data_bounded$Upper == 0), ])

alpha<-Data_bounded$alpha
beta<-Data_bounded$beta

#this is what causes big trouble (see below in the answer)
LB_data<-Data_bounded$Lower
UB_data<-Data_bounded$Upper 


#I simplified your objective function. Using a for-loop is
#100 times slower
fn1<-function(spend)
{
  -sum(alpha * spend^beta)
}


#the constraint equation
eq1<-function(spend)
{
  sum(spend)
}


opti<-solnp(rep(0.5,40),fun=fn1,LB=rep(0,40),UB=rep(Inf,40),eqfun=eq1,eqB=total_spend)

输出:

> opti
$pars
 [1] 1.863565e+06 8.537037e-02 4.980553e+06 5.078493e+04 1.756843e+07 2.178128e+07 2.455468e+07 1.681695e+07 7.889301e+06 2.746788e+07
[11] 8.545552e-02 5.534938e+05 7.639648e+06 6.134385e+05 7.901136e+05 2.876899e+06 8.545261e-02 8.545261e-02 2.943462e+03 1.178904e+02
[21] 9.985594e+05 9.349150e+02 5.105370e+05 8.303612e+02 8.545261e-02 3.959562e+05 8.545261e-02 8.545261e-02 9.386337e+05 8.545257e-02
[31] 1.607354e+02 2.848127e+04 2.931769e+02 3.296281e+04 8.193187e+05 3.486277e+06 2.300425e+03 1.352874e+05 2.158217e+04 8.545291e-02

$convergence
[1] 0