Я использую все свои статистические данные в R и python для всех периферийных задач. Просто для удовольствия я попытался оптимизировать BFGS, чтобы сравнить его с обычным результатом LS - как в python, использующем scipy/numpy. Но результаты не совпадают. Я не вижу никаких ошибок. Я также прикрепляю эквивалентный код в R (который работает). Может ли кто-нибудь исправить мое использование scipy.optimize.fmin_bfgs, чтобы соответствовать результатам OLS или R?Правильное использование scipy.optimize.fmin_bfgs требуется по сравнению с кодом R
import csv
import numpy as np
import scipy as sp
from scipy import optimize
class DataLine:
def __init__(self,row):
self.Y = row[0]
self.X = [1.0] + row[2:len(row)]
# 'Intercept','Food','Decor', 'Service', 'Price' and remove the name
def allDataLine(self):
return self.X + list(self.Y) # return operator.add(self.X,list(self.Y))
def xData(self):
return np.array(self.X,dtype="float64")
def yData(self):
return np.array([self.Y],dtype="float64")
def fnRSS(vBeta, vY, mX):
return np.sum((vY - np.dot(mX,vBeta))**2)
if __name__ == "__main__":
urlSheatherData = "/Hans/workspace/optimsGLMs/MichelinNY.csv"
# downloaded from "http://www.stat.tamu.edu/~sheather/book/docs/datasets/MichelinNY.csv"
reader = csv.reader(open(urlSheatherData), delimiter=',', quotechar='"')
headerTuple = tuple(reader.next())
dataLines = map(DataLine, reader)
Ys = map(DataLine.yData,dataLines)
Xs = map(DataLine.xData,dataLines)
# a check and an initial guess ...
vBeta = np.array([-1.5, 0.06, 0.04,-0.01, 0.002]).reshape(5,1)
print np.sum((Ys-np.dot(Xs,vBeta))**2)
print fnRSS(vBeta,Ys,Xs)
lsBetas = np.linalg.lstsq(Xs, Ys)
print lsBetas[1]
# prints the right numbers
print lsBetas[0]
optimizedBetas = sp.optimize.fmin_bfgs(fnRSS, x0=vBeta, args=(Ys,Xs))
# completely off ..
print optimizedBetas
Результатом оптимизации является:
Optimization terminated successfully.
Current function value: 6660.000006
Iterations: 276
Function evaluations: 448
[ 4.51296549e-01 -5.64005114e-06 -3.36618459e-06 4.98821735e-06
9.62197362e-08]
Но это действительно должно соответствовать результаты МНК достигнуты в lsBetas = np.linalg.lstsq(Xs, Ys)
:
[[-1.49209249]
[ 0.05773374]
[ 0.044193 ]
[-0.01117662]
[ 0.00179794]]
Здесь R-код в случае полезно (он также имеет то преимущество, что он может читать непосредственно из URL-адреса):
urlSheatherData = "http://www.stat.tamu.edu/~sheather/book/docs/datasets/MichelinNY.csv"
dfSheather = as.data.frame(read.csv(urlSheatherData, header = TRUE))
vY = as.matrix(dfSheather['InMichelin'])
mX = as.matrix(dfSheather[c('Service','Decor', 'Food', 'Price')])
mX = cbind(1, mX)
fnRSS = function(vBeta, vY, mX) { return(sum((vY - mX %*% vBeta)^2)) }
vBeta0 = rep(0, ncol(mX))
optimLinReg = optim(vBeta0, fnRSS,mX = mX, vY = vY, method = 'BFGS', hessian=TRUE)
print(optimLinReg$par)
К тому же, какие у вас версии модулей и системная архитектура? Мне не удалось успешно оптимизировать ваш код во всех доступных комбинациях (на самом деле их довольно много). All eneded 'Warning: Желаемая ошибка не всегда достигается из-за потери точности.' – alko
Я использую Enthought Canopy Python 2.7.3 | 64-бит на Mac OSX 10.6.8, 1.7.1 на numpy и 0.12.0 на scipy. –
[Этот вопрос] (http://stackoverflow.com/questions/21055930/scipy-optimize-fmin-bfgs-optimization-gives-different-result-from-simple-functio) связан и в основном показывает, что он является вынужденным трансформация vBeta, которая является проблемой. –