Я изучаю некоторые функции numpy/scipy, и я заметил, что scipy.optimize.fmin_bfgs требует изменения вызываемой функции, чтобы дать правильные результаты по сравнению с прямой вызов функции. Мое первое определение функции fnRSS
возвращает правильное значение при вызове функции, но отказывается работать в оптимизации; мое второе определение дает неправильный результат при вызове функции, но правильный при запуске оптимизации. Может ли кто-нибудь сказать мне, что так важно для переноса параметра vY
для оптимизации? Он должен быть уже 164x1.Оптимизация scipy.optimize.fmin_bfgs дает отличный результат от простого вызова функции
import numpy as np
import scipy as sp
import pandas as pd
from scipy import optimize
if __name__ == "__main__":
urlSheatherData = "http://www.stat.tamu.edu/~sheather/book/docs/datasets/MichelinNY.csv"
data = pd.read_csv(urlSheatherData)
Xs = np.vstack(data[['Service','Decor', 'Food', 'Price']].values)
Xs = np.concatenate((np.vstack(np.ones(Xs.shape[0])),Xs), axis=1)
Ys = np.vstack(data[['InMichelin']].values)
# optimal solution (given)
vBeta = np.array([-1.49209249, -0.01117662, 0.044193, 0.05773374, 0.00179794]).reshape(5,1)
print Ys.shape, Xs.shape, vBeta.shape
# first definition of function
def fnRSS(vBeta, vY, mX):
return np.sum((vY - np.dot(mX, vBeta))**2)
print fnRSS(vBeta, Ys, Xs) # correct value
print np.linalg.lstsq(Xs, Ys)[1] # confirm correct value
print sp.optimize.fmin_bfgs(fnRSS, x0=vBeta, args=(Ys,Xs)) # wrong value
# second definition
def fnRSS(vBeta, vY, mX):
return np.sum((vY.T - np.dot(mX, vBeta))**2)
print fnRSS(vBeta, Ys, Xs) # incorrect value
print sp.optimize.fmin_bfgs(fnRSS, x0=vBeta, args=(Ys,Xs)) # correct convergence but simple call gives different value
Мой выход:
(164, 1) (164, 5) (5, 1)
26.3239061505
[ 26.32390615]
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 6660.000000
Iterations: 39
Function evaluations: 3558
Gradient evaluations: 480
[ 4.51220111e-01 1.32711255e-07 8.09143368e-08 -1.06633003e-07
-5.18448332e-08]
9002.87916028
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 26.323906
Iterations: 29
Function evaluations: 1954
Gradient evaluations: 260
[-1.49209095 -0.0111764 0.04419313 0.05773347 0.00179789]
as followup on alko: просто играйте с точкой и посмотрите, какую форму вы получите, когда vBeta - это одномерное по сравнению с массивом столбцов. np.dot транслирует/переносит 1d-массив, если необходимо, но форма и ndim разные. Y должен соответствовать вашему vBeta.ndim – user333700
Спасибо, я буду играть с этим. Мне кажется, мне не нравится, что вам нужно оптимизировать функцию, которая дает неверный доход, когда вы проверяете результат оптимизации - это убивает много модульных тестов. –