Как оптимизировать линейные коэффициенты для числовых массивов в функции максимизации? - PullRequest
0 голосов
/ 26 мая 2019

Я должен оптимизировать коэффициенты для трех массивов, что увеличивает мою функцию оценки.У меня есть целевой массив с именем train ['target'] и три массива предсказаний с именами array1, array2 и array3.

Я хочу поставить наилучшие линейные коэффициенты, т. Е. X, y, z для этих трех массивов, которые максимизируют функцию

roc_aoc_curve (train ['target'], x array1+ y array2 + z * array3)

указанная выше функция будет максимальной, когда прогноз ближе к цели.то есть x array1 + y array2 + z * array3 должен быть ближе к поезду ['target'].

Диапазон значений x, y, z> = 0 и x, y,z <= 1 </p>

В основном я пытаюсь поместить веса x, y, z для каждого из трех массивов, которые бы сделали функцию

x array1 + y массив2 + z * массив3 ближе к поезду ['target']

Любая помощь в получении этого будет принята с благодарностью.

Я использовал pulp.LpProblem ('Giapetto', pulp.LpMaximize), чтобы сделать максимизацию.Он работает для нормальных чисел, целых чисел и т. Д., Однако не работает при попытке сделать это с массивами.

import numpy as np
import pulp

# create the LP object, set up as a maximization problem
prob = pulp.LpProblem('Giapetto', pulp.LpMaximize)

# set up decision variables
x = pulp.LpVariable('x', lowBound=0)
y = pulp.LpVariable('y', lowBound=0)
z = pulp.LpVariable('z', lowBound=0)

score =  roc_auc_score(train['target'],x*array1+ y*array2 + z*array3)

prob += score

coef = x+y+z

prob += (coef==1)

# solve the LP using the default solver
optimization_result = prob.solve()

# make sure we got an optimal solution
assert optimization_result == pulp.LpStatusOptimal

# display the results
for var in (x, y,z):
    print('Optimal weekly number of {} to produce: {:1.0f}'.format(var.name, var.value()))

Получение ошибки в строке

score =  roc_auc_score(train['target'],x*array1+ y*array2 + z*array3)

TypeError: неподдерживаемые типы операндов для /: 'int' и 'LpVariable'

Can'tпрогресс за этой линией при использовании массивов.Не уверен, что мой подход правильный.Буду признателен за любую помощь в оптимизации функции.

1 Ответ

0 голосов
/ 26 мая 2019

Когда вы добавляете суммы элементов массива в модель PuLP, вы должны использовать для этого встроенные конструкции PuLP, такие как lpSum - вы не можете просто добавлять массивы вместе (как вы обнаружили).

Итак, ваше определение score должно выглядеть примерно так:

score = pulp.lpSum([train['target'][i] - (x * array1[i] + y * array2[i] + z * array3[i]) for i in arr_ind])

Несколько замечаний по этому поводу:

[+] Вы не предоставили определениеиз roc_auc_score, поэтому я просто притворился, что он равен сумме поэлементной разницы между целевым массивом и взвешенной суммой трех других массивов.

[+] Я подозреваю, что ваш фактический расчет для roc_auc_score нелинейно;подробнее об этом ниже.

[+] arr_ind - это список индексов массивов, который я создал следующим образом:

# build array index
arr_ind = range(len(array1))

[+] Вы также не сделали этоговключите массивы, поэтому я создал их так:

array1 = np.random.rand(10, 1)
array2 = np.random.rand(10, 1)
array3 = np.random.rand(10, 1)

train = {}
train['target'] = np.ones((10, 1))

Вот мой полный код, который компилируется и выполняется, хотя я уверен, что он не даст вам того результата, на который вы надеетесь, так какЯ только что догадался о target и roc_auc_score:

import numpy as np
import pulp

# create the LP object, set up as a maximization problem
prob = pulp.LpProblem('Giapetto', pulp.LpMaximize)

# dummy arrays since arrays weren't in OP code
array1 = np.random.rand(10, 1)
array2 = np.random.rand(10, 1)
array3 = np.random.rand(10, 1)

# build array index
arr_ind = range(len(array1))

# set up decision variables
x = pulp.LpVariable('x', lowBound=0)
y = pulp.LpVariable('y', lowBound=0)
z = pulp.LpVariable('z', lowBound=0)

# dummy roc_auc_score since roc_auc_score wasn't in OP code
train = {}
train['target'] = np.ones((10, 1))
score = pulp.lpSum([train['target'][i] - (x * array1[i] + y * array2[i] + z * array3[i]) for i in arr_ind])

prob += score

coef = x + y + z

prob += coef == 1

# solve the LP using the default solver
optimization_result = prob.solve()

# make sure we got an optimal solution
assert optimization_result == pulp.LpStatusOptimal

# display the results
for var in (x, y,z):
    print('Optimal weekly number of {} to produce: {:1.0f}'.format(var.name, var.value()))

Вывод:

Optimal weekly number of x to produce: 0
Optimal weekly number of y to produce: 0
Optimal weekly number of z to produce: 1

Process finished with exit code 0

Теперь, если ваша функция roc_auc_score является нелинейной, у вас будут дополнительные проблемы.Я бы посоветовал вам попытаться сформулировать оценку линейным способом, возможно, используя дополнительные переменные (например, если вы хотите, чтобы оценка была абсолютной величиной).

...