2016-05-16 10 views
0

私は、scipyの共役勾配アルゴリズム(fmin_cg)を使用して線形モデル内で最良のフィットを与えるパラメータthetaを見つけようとしています。scipyのfmin_cgの勾配関数

データファイルHouseData.csv(例えば住宅エリア、住宅価格):

120, 250 
200, 467 
250, 500 
1200, 2598 
1500, 3000 

コードは次のとおりです。fprime = gradfコードが正しい結果を返しますが、何でなければ

from scipy import optimize 
import numpy as np 

data=np.genfromtxt('HouseData.csv',delimiter=',') 
X=np.c_[np.ones(len(data)),data[:,:-1]] 
Y=data[:,[-1]] 

def cost_Function(theta): 
    theta1=theta[np.newaxis].T 
    #print('theta: ',theta1) 
    cost = Y-np.dot(X, theta1) 
    return (cost*cost).sum() 

# Gradient Function 
def gradf(theta): 
    theta1 = theta[np.newaxis].T 
    cost = Y - np.dot(X, theta1) 
    #print('cost*X.sum(0) is', np.sum(cost*X,axis=0)) 
    return np.sum(cost*X,axis=0) 


x0 = np.asarray((0,1)) #initial guess 
result = optimize.fmin_cg(cost_Function,x0,fprime=gradf) 
print(result)  

グラジエント関数の問題?上記のように含めると、アルゴリズムはthetaの入力を正確に返します。パフォーマンスを向上させるために別の実装方法がありますか? これは単なる単なる例ですが、アルゴリズムは多くの列と行を持つXでも実行する必要があります。

(のpython 3.5.1、scipyのダウンロードとnumpyの最新バージョン)

+0

パフォーマンスを改善していますか?まあ... CGは使わず、QR分解を使ってください。 [ここ](http://stats.stackexchange.com/questions/175983/whats-the-underlying-algorithm-used-by-rs-lm)および[ここ](http://stats.stackexchange.com)も参照してください。/questions/94496/lm-function-in-r) – sascha

+0

このコードは機能しますか? 'args [0]'の代わりに 'args'を使うべきですね – Eric

+0

私はあなたのグラデーション関数が正しいとは思わない – Eric

答えて

2

あなたの勾配が明らかに間違っています。

コスト関数は2次式なので、勾配を適度に近似できます。gradf(x) = (f(x + eps) - f(x - eps))/(2 eps)。のはそれを試してみましょう:

e0 = np.array([1, 0]) 
e1 = np.array([0, 1]) 
eps = 1e-5 

x0 = np.array([1, 1]) 

df_yours = gradf(x0) 
# array([ 3.54000000e+03, 4.05583000e+06]) 

df_approx = np.array([ 
    cost_Function(x0 + eps*e0) - cost_Function(x0 - eps*e0), 
    cost_Function(x0 + eps*e1) - cost_Function(x0 - eps*e1) 
])/(2 * eps) 
# array([ -7.07999999e+03, -8.11166000e+06]) 

を(ところで、あなたはは絶対を推測するのではなく、やるべきこと)数理解析をやってなければ、あなたの勾配関数は-0.5の要因でオフになっています。そのネガティブは非常に重要です。

1

勾配関数の符号に関するEricのコメントは非常に重要でした。ここで、正しく動作しているコードnp.dot(X、theta1)-Yが正しく、cost_Functionに0.5の係数が追加されました

from scipy import optimize 
import numpy as np 

data=np.genfromtxt('HouseData.csv',delimiter=',') 
X=np.c_[np.ones(len(data)),data[:,:-1]] 
Y=data[:,[-1]] 

def cost_Function(theta): 
    theta1=theta[np.newaxis].T 
    cost = Y-np.dot(X, theta1) 
    return 0.5*(cost*cost).sum() 

# Gradient Function 
def gradf(theta): 
    theta1 = theta[np.newaxis].T 
    cost = np.dot(X, theta1) - Y 
    return np.sum(cost*X,axis=0) 

x0 = np.asarray((0.1,2)) #initial guess 

result = optimize.fmin_cg(cost_Function,x0,fprime=gradf) 
print(result)