2014-12-02 102 views
0

我想實現Logistic迴歸,我使用Scipy的Optimize模塊來找到優化的theta值。使用fmin函數時,我能夠得到正確的值。但是我想在使用需要漸變的fmin_bfgs函數時這樣做。fmin_bfgs Logistic迴歸和Scipy優化

下面的代碼片段:

#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' object is not callable這是從優化模塊中的function_wrapper功能。我甚至嘗試在兩個不同的函數中返回漸變和成本,但得到了vstack某種錯誤(如果這很重要/有幫助)。

就我所見,我已經提供了優化功能所要求的。

編輯/更新:我意識到我得到的錯誤是因爲當期望函數返回這些參數時,我將成本和grad numpy數組作爲參數傳遞。我意識到我可以創建一個包裝函數?爲了在不使用兩個單獨函數的情況下獲得這兩個值,但爲了臨時目的,我更改了costFunction,因此它只返回成本,並創建了一個全新的函數Grad()(儘管代碼相同),只返回grad。這再次給了我all the input array dimensions except for the concatenation axis must match exactly vstack錯誤。

回答

0

如果沒有最小可重現的例子,很難調試。

我會調試它的方式,我會從一些簡單的事情開始,以確保我獲得基本的語法。有幾種使用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> 

,用漸變,你可以有一個可調用的返回功能梯度:

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.]) 

或者,您也可以設置jac到一個可調用,它應該與成本函數具有相同的簽名並返回梯度:

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

我向您提供了有關複製s簡單,所以我有漸變功能吐出第一個漸變應該是什麼。值是正確的,但似乎有一個奇怪的間距。它是:'[-0.1 -12.00921659 -11.26284221]'。在前兩個值之間它有一個奇數的間距。我去了vstack函數錯誤的地方,它顯然收到了我打印出來的元組。在flatten方法之前是'([0],array([[0], [0。]]))',而在之後是'([0],array([0,0]))''扁平化方法。我如何得到這是一個單一的數組? – user3047023 2014-12-03 15:22:11

+0

這不是很有幫助。最好把你的問題分解成單獨的問題:有一個關於最小化本身的問題,另外一個關於成本函數。 – 2014-12-03 17:09:44

+0

好吧,那麼我明顯想要這個的是,如何獲得'np.vstack(([0],grad_reg))'返回一個數組?不像'([0],array([0.,0。]))''? – user3047023 2014-12-03 17:36:08