Проблема минимизации весов с linprog - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь использовать python (и в настоящее время не могу), чтобы прийти к более эффективному решению, чем Excel Solver для решения проблемы оптимизации.

Matrices

Проблема в форме A B = C -> D, где A B производит C, где абсолютное значение для CD для каждой строки в матрице сведено к минимуму.

У меня есть семь средств, содержащихсяв матрице B все из которых имеют географическую экспозицию в форме

FUND_NAME = np.array([UK,USA,EuroZone, Japan,EM,Apac)]

, как показано ниже


RLS = np.array([0.788743177, 0.168048481,0,0.043208342,0,0])
LIOGLB=np.array([0.084313978,0.578528092,0,0.23641746,0.033709666,0.067030804])
LIONEUR=np.array([0.055032339,0,0,0.944967661,0,0])
STEW_WLDWD=np.array([0.09865472,0.210582713,0.053858632,0.431968002,0.086387178,0.118548755])
EMMK=np.array([0.080150377,0.025212864,0.597285513,0.031832241,0.212440426,0.053078578])
PAC=np.array([0,0.013177633,0.41273195,0,0.510644775,0.063445642])
PICTET=np.array([0.089520913,0.635857603,0,0.218148413,0.023290413,0.033182659])

Из этого мне нужно построитьоптимальное взвешивание семи фондов с использованием матрицы (образно названной A) [x1, x2, x3, x4, x5, x6, x7] с x1 + x2 + ... + x7 = 1 & Также дляi = (1,7) xi нижняя граница = 0 xi верхняя граница = 0,25

Чтобы получить фактические региональные веса ( матрица C ) как можно ближе к приведенному ниже целевому массиву (что соответствует матрице D выше)

Target=np.array([0.2310,0.2576,0.1047,0.1832,0.1103,0.1131])

Я пытался использовать libprog. Но я знаю, что ответ, который я получаю, неправильный.

Funds =np.array([RLS,LIOGLB,    LIONEUR,STEW_WLDWD, EMMK,PAC,PICTET])
twentyfive=np.full((1, 7), 0.25)
bounds=[0,0.25]

res = linprog(Target,A_ub=Funds,b_ub=twentyfive,bounds=[bounds])

Может ли кто-нибудь помочь мне перейти от Excel?

1 Ответ

0 голосов
/ 25 октября 2019

Это действительно регрессия LAD проблема (LAD = наименьшее абсолютное отклонение) с некоторыми побочными ограничениями. Различные формулировки LP для проблем регрессии LAD можно найти здесь . Основываясь на разреженной задаче ограничения, мы можем сформулировать модель LP:

enter image description here

Это математическая модель, которую я собираюсь попытаться решить с помощью linprog . Раскраска выглядит следующим образом: синие символы представляют данные, красные символы - переменные решения. x - это распределения (дроби), которые нам нужно найти, d - остатки линейного приближения, а r - абсолютные значения d *. 1021 *.

linprog требует явной матрицы LP. Для вышеприведенной модели эта матрица A может выглядеть следующим образом:

enter image description here

С этим больше не очень сложно разрабатывать реализацию Python. Код Python может выглядеть следующим образом:

import numpy as np
import scipy.optimize as sp

B = np.array([[0.788743177, 0.168048481,0,0.043208342,0,0],
            [0.084313978,0.578528092,0,0.23641746,0.033709666,0.067030804],
            [0.055032339,0,0,0.944967661,0,0],
            [0.09865472,0.210582713,0.053858632,0.431968002,0.086387178,0.118548755],
            [0.080150377,0.025212864,0.597285513,0.031832241,0.212440426,0.053078578],
            [0,0.013177633,0.41273195,0,0.510644775,0.063445642],
            [0.089520913,0.635857603,0,0.218148413,0.023290413,0.033182659]]).T

target = np.array([0.2310,0.2576,0.1047,0.1832,0.1103,0.1131])

m,n = np.shape(B)

A_eq = np.block([[B,          np.eye(m),  np.zeros((m,m))],
                [np.ones(n), np.zeros(m), np.zeros(m)]])
A_ub = np.block([[np.zeros((m,n)),-np.eye(m), -np.eye(m)],
                 [np.zeros((m,n)),np.eye(m), -np.eye(m)]])

b_eq = np.block([target,1])
b_ub = np.zeros(2*m)

c = np.block([np.zeros(n),np.zeros(m),np.ones(m)])

bnd =   n*[(0,0.25)] + m*[(None,None)] + m*[(0,None)]

res = sp.linprog(c,A_ub,b_ub,A_eq,b_eq,bnd,options={'disp':True})

allocation = res.x[0:n] 

Результаты выглядят следующим образом:

Primal Feasibility  Dual Feasibility    Duality Gap         Step             Path Parameter      Objective          
1.0                 1.0                 1.0                 -                1.0                 6.0                 
0.3777262386888     0.3777262386888     0.3777262386888     0.6478228594143  0.3777262386888     0.3200496644143     
0.08438152300367    0.08438152300366    0.08438152300367    0.8087424108466  0.08438152300366    0.1335722585582     
0.01563291142478    0.01563291142478    0.01563291142478    0.8341722620104  0.01563291142478    0.1118298108651     
0.004083901923022   0.004083901923022   0.004083901923023   0.7432737130498  0.004083901923024   0.1049630948572     
0.0006190254179117  0.0006190254179117  0.0006190254179116  0.8815177164943  0.000619025417913   0.1016021916581     
3.504935403199e-05  3.504935403066e-05  3.504935403079e-05  0.9676694788778  3.504935402756e-05  0.1012177893279     
5.983549975387e-07  5.98354980932e-07   5.983549810074e-07  0.9885372873161  5.983549719474e-07  0.1011921413019     
3.056236812029e-11  3.056401712736e-11  3.056394819773e-11  0.9999489201822  3.056087926755e-11  0.1011915586046     
Optimization terminated successfully.
         Current function value: 0.101192    
         Iterations: 8

print(allocation)

[2.31621461e-01 2.50000000e-01 9.07425872e-12 2.50000000e-01
 4.45030949e-10 2.39692743e-01 2.86857955e-02]
...