Python 基于fmin_-bfgs的Logistic回归与Scipy优化

Python 基于fmin_-bfgs的Logistic回归与Scipy优化,python,optimization,numpy,machine-learning,scipy,Python,Optimization,Numpy,Machine Learning,Scipy,我正在尝试实现逻辑回归,我正在使用Scipy的优化模块来找到优化的θ值。使用fmin功能时,我能够获得正确的值。但我想在使用需要梯度的fmin_bfgs函数时这样做 以下是一段代码片段: #Returns Cost of current theta values and gradient of cost w.r.t theta. def costFunction(theta, X, y, _lambda): #Initializes useful variables m = l

我正在尝试实现逻辑回归,我正在使用Scipy的优化模块来找到优化的θ值。使用fmin功能时,我能够获得正确的值。但我想在使用需要梯度的fmin_bfgs函数时这样做

以下是一段代码片段:

#Returns Cost of current theta values and gradient of cost w.r.t theta.
def costFunction(theta, X, y, _lambda):

    #Initializes useful variables
    m = len(y)
    grad = np.zeros((np.shape(theta)))

    #Solves for Hypothesis for input X.
    h_x = Sigmoid(np.dot(X,theta))

    #Reshaped because numpy kept returning row vector, not column.
    h_x = h_x.reshape((m,1))

    #Cost is broken up into terms for simplicity. 
    term1 = -y*np.log(h_x)
    term2 = (1-y)*np.log((1-h_x))



    #Regularized Cost FUnction
    J = (1/m) * sum(term1-term2) + (_lambda/(2*m)) * sum(np.square(theta[1:][:]))

    #Gradient for Theta1
    grad_reg = (_lambda/m)*theta[1:]

    #Combines gradient for Theta1 and onward. 
    grad = (1/m)* (np.dot(np.transpose(X),(h_x-y))) + np.vstack(([0],grad_reg)) 

    return J,grad 





#Finds Optimal Value for theta
cost, grad = costFunction(initial_theta, X,y, _lambda)
opt_theta = fmin_bfgs(cost,x0=initial_theta,fprime=grad, args = (X,y,_lambda))
我得到的错误是,
'numpy.ndarray'对象不可调用
,它来自优化模块中的
函数包装器
函数。我甚至尝试在两个不同的函数中返回梯度和成本,但得到了某种类型的
vstack
错误(如果这很重要/有帮助的话)

就我所知,我已经提供了优化函数所要求的


编辑/更新:我意识到我遇到的错误是因为我传递了cost和grad numpy数组作为参数,而它希望函数返回这些参数。我意识到我可以创建一个包装器函数?为了在不使用两个单独函数的情况下获取这两个值,但出于临时目的,我更改了costFunction,使其只返回成本,并创建了一个全新的函数,
Grad()
,该函数只返回梯度(但代码相同)。这给了我一个
所有的输入数组维度,除了连接轴必须完全匹配
vstack error

如果没有一个最小的可复制的示例,就很难调试东西

按照我调试它的方式,我会从简单的事情开始,以确保基本语法正确。有几种使用带显式梯度的bfgs最小化的方法。首先,没有梯度信息:

In [1]: import numpy as np

In [2]: from scipy.optimize import minimize

In [3]: def f(x):
   ...:     return np.sum((x-2.)**2)
   ...: 

In [4]: x0 = np.ones(3)

In [5]: minimize(f, x0, method='bfgs')
Out[5]: 
  status: 0
 success: True
    njev: 4
    nfev: 20
     fun: 1.6656677750444977e-16
       x: array([ 1.99999999,  1.99999999,  1.99999999])
<snip>
或者,您可以将
jac
设置为callable,它应该具有与成本函数相同的签名并返回梯度:

In [6]: def f_and_jac(x):
   ...:     val = np.sum((x-2.)**2)
   ...:     grad = 2.*(x-2.)
   ...:     return val, grad
   ...: 

In [7]: minimize(f_and_jac, x0, method='bfgs', jac=True)   # notice the 'jac' parameter
Out[7]: 
  status: 0
 success: True
    njev: 4
    nfev: 4
     fun: 0.0
       x: array([ 2.,  2.,  2.])
In [8]: def jac(x):
   ...:     return 2.*(x-2.)
   ...: 

In [9]: minimize(f, x0, method='bfgs', jac=jac)
Out[9]: 
  status: 0
 success: True
    njev: 4
    nfev: 4
     fun: 0.0
       x: array([ 2.,  2.,  2.])

我接受了你的建议,复制一些简单的东西,所以我让梯度函数给出了第一个梯度应该是什么。这些值是正确的,但似乎有一个奇怪的间距。它是:
[-0.1-12.00921659-11.26284221]
。在前两个值之间有一个奇数间隔。我去了vstack函数错误的地方,它显然收到了一个我打印出来的元组。在展平方法之前是
([0],数组([[0.],[0.]])
,在展平方法之后是
([0],数组([0,0.])
。如何使其成为单个阵列?这并没有真正的帮助。最好把你的问题分成几个单独的问题:很明显,有一个关于最小化本身,还有一个关于代价函数。好吧,我的目的显然是,如何让
np.vstack(([0],grad_reg))
返回单个数组?不是类似于
([0],数组([0,0.])