Scipy оптимизирует поведение по-разному с 1-й Матрица против векторного ввода st.Решение 1-й матрицы неверно - PullRequest
0 голосов
/ 19 марта 2019

Я испытал, что кормление scipy.optimize 1-d матрица (формы (N, 1)) дает разные (неправильные) результаты по сравнению с предоставлением ему одинаковых данных в виде векторов (векторы w и y в MVE ниже

import numpy as np
from scipy.optimize import minimize
X = np.array([[ 1.13042959,  0.45915372,  0.8007231 , -1.15704469,  0.42920652],
       [ 0.14131009,  0.9257914 ,  0.72182141,  0.86906652, -0.32328187],
       [-1.40969139,  1.32624329,  0.49157981,  0.2632826 ,  1.29010016],
       [-0.87733399, -1.55999729, -0.73784827,  0.15161383,  0.11189782],
       [-0.94649544,  0.10406324,  0.65316464, -1.37014083, -0.28934968]])

wtrue = np.array([3.14,2.78,-1,0, 1.6180])

y = X.dot(wtrue)
def cost_function(w, X, y):
    return np.mean(np.abs(y - X.dot(w)))

#  %%
w0 = np.zeros(5)
output = minimize(cost_function, w0, args=(X, y), options={'disp':False, 'maxiter':128})
print('Vector Case:\n', output.x, '\n', output.fun)

# Reshaping w0 and y to (N,1) will 'break things'
w0 = np.zeros(5).reshape(-1,1)
y = y.reshape(-1,1) #This is the problem, only commenting this out will make below work
output = minimize(cost_function, w0, args=(X, y), options={'disp':False, 'maxiter':128})
print('1-d Matrix Case:\n', output.x, '\n', output.fun)

Придает

Vector Case: [3.13999999e + 00 2.77999996e + 00 -9.99999940e-01 1.79002338e-08,1.61800001e + 00] 1.7211226932545288e-08 // ИСТИНА почти 0

1-й матричный корпус: [-0,35218177 -0,50008129 0,34958755 -0,42210756 0,79680766] 3.3810648518841924 // НЕПРАВИЛЬНО близко к истинному решению

Кто-нибудь знает, почему решение, использующее 1-d матричные входы, получается «неправильным»?

Я подозреваю, что это где-то на пути b / c .minimize превращает вектор параметров в реальный вектор, и тогда я знаю, что (2,) + (2,1) дает (2,2) матрицу скорее чем (2,) или (2,1). Это все еще кажется мне «странным», и я хотел бы знать, не упускаю ли я что-то большее здесь.

1 Ответ

1 голос
/ 20 марта 2019
In [300]: y                                                                               
Out[300]: array([ 4.7197293 ,  1.7725223 ,  0.85632763, -6.17272225, -3.8040323 ])
In [301]: w0                                                                              
Out[301]: array([0., 0., 0., 0., 0.])
In [302]: cost_function(w0,X,y)                                                           
Out[302]: 3.465066756332

Первоначально изменение формы y не меняет стоимость:

In [306]: cost_function(w0,X,y.reshape(-1,1))                                             
Out[306]: 3.4650667563320003

Теперь получите решение: В [308]: output = optimize.minimize (cost_function, w0, args = (X, y), options = {'disp': False ...:, 'maxiter': 128})

In [310]: output.x                                                                        
Out[310]: 
array([ 3.14000001e+00,  2.77999999e+00, -9.99999962e-01, -5.58139763e-08,
        1.61799993e+00])

Оцените стоимость как оптимальную x

In [311]: cost_function(output.x,X,y)                                                     
Out[311]: 7.068144833866085e-08        # = output.fun

Но с измененным y стоимость отличается:

In [312]: cost_function(output.x,X,y.reshape(-1,1))                                       
Out[312]: 4.377833258899681

Начальное значение x0 выравнивается кодом (посмотрите на optimize.optimize._minimize_bfgs), поэтому изменение формы w0 не имеет значения. Но массивы args передаются в функцию стоимости без изменений. Поэтому, если изменение формы y изменит расчет стоимости, изменится оптимизация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...