2017-06-20 108 views
0

我使用minpack.lm軟件包運行非線性最小二乘法。優化擬合係數以便更好地擬合

但是,對於數據中的每個組,我想優化(最小化)擬合參數,如類似於Python的minimize函數。

minimize()函數是Minimizer運行 優化問題時的一個包裝。它需要一個目標函數(函數 ,用於計算要最小化的數組),一個Parameters對象和幾個可選參數。

我需要這個的原因是,我想基於獲得的擬合參數來優化擬合函數以找到適合數據中的兩個組的全局擬合參數。

這是我目前在小組擬合方法,

df <- data.frame(y=c(replicate(2,c(rnorm(10,0.18,0.01), rnorm(10,0.17,0.01))), 
           c(replicate(2,c(rnorm(10,0.27,0.01), rnorm(10,0.26,0.01))))), 
         DVD=c(replicate(4,c(rnorm(10,60,2),rnorm(10,80,2)))), 
         gr = rep(seq(1,2),each=40),logic=rep(c(1,0),each=40)) 

這些羣體的擬合方程是

fitt <- function(data) { 
    fit <- nlsLM(y~pi*label2*(DVD/2+U1)^2, 
       data=data,start=c(label2=1,U1=4),trace=T,control = nls.lm.control(maxiter=130)) 
} 

library(minpack.lm) 
library(plyr) # will help to fit in groups 

fit <- dlply(df, c('gr'), .fun = fitt) #,"Die" only grouped by Waferr 

> fit 
$`1` 
Nonlinear regression model 
    model: y ~ pi * label2 * (DVD/2 + U1)^2 
    data: data 
    label2  U1 
2.005e-05 1.630e+03 
$`2` 
label2  U1 
2.654 -35.104 

我需要知道是否有任何優化功能的總和,OF-正方形來爲兩個組獲得最佳擬合。 我們可以說,你已經擁有了最好的擬合參數爲剩餘總和-的平方,但我知道,minimizer能做到這一點,但我還沒有找到任何類似的例子,我們可以在R

enter image description here

做到這一點

ps。我做了數字和擬合線。

+0

我認爲'?optim'等同於Python的'minim'。 Optim的作者推薦'optimx'包做出了很好的改進。 – Gregor

+0

@Gregor我明白了。我很抱歉讓你們討厭。我只是陷入困境,需要真正幫助解決這個問題! – Alexander

+0

@Gregor我從來沒有聽說過'optimx'。我快速查看了stackoverflow,但似乎沒有分組數據的優化方法。 – Alexander

回答

1

不確定r,但具有共享參數的最小二乘通常很容易實現。

一個簡單的Python例子如下:

import matplotlib 
matplotlib.use('Qt4Agg') 
from matplotlib import pyplot as plt 

from random import random 
from scipy import optimize 
import numpy as np 

#just for my normal distributed errord 
def boxmuller(x0,sigma): 
    u1=random() 
    u2=random() 
    ll=np.sqrt(-2*np.log(u1)) 
    z0=ll*np.cos(2*np.pi*u2) 
    z1=ll*np.cos(2*np.pi*u2) 
    return sigma*z0+x0, sigma*z1+x0 

#some non-linear function 
def f0(x,a,b,c,s=0.05): 
    return a*np.sqrt(x**2+b**2)-np.log(c**2+x)+boxmuller(0,s)[0] 

# residual function for least squares takes two data sets. 
# not necessarily same length 
# two of three parameters are common 
def residuals(parameters,l1,l2,dataPoints): 
    a,b,c1,c2 = parameters 
    set1=dataPoints[:l1] 
    set2=dataPoints[-l2:] 
    distance1 = [(a*np.sqrt(x**2+b**2)-np.log(c1**2+x))-y for x,y in set1] 
    distance2 = [(a*np.sqrt(x**2+b**2)-np.log(c2**2+x))-y for x,y in set2] 
    res = distance1+distance2 
    return res 

xList0=np.linspace(0,8,50) 
#some xy data 
xList1=np.linspace(0,7,25) 
data1=np.array([f0(x,1.2,2.3,.33) for x in xList1]) 
#more xy data using different third parameter 
xList2=np.linspace(0.1,7.5,28) 
data2=np.array([f0(x,1.2,2.3,.77) for x in xList2]) 
alldata=np.array(zip(xList1,data1)+zip(xList2,data2)) 

# rough estimates 
estimate = [1, 1, 1, .1] 
#fitting; providing second length is actually redundant 
bestFitValues, ier= optimize.leastsq(residuals, estimate,args=(len(data1),len(data2),alldata)) 
print bestFitValues 


fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.scatter(xList1, data1) 
ax.scatter(xList2, data2) 
ax.plot(xList0,[f0(x,bestFitValues[0],bestFitValues[1],bestFitValues[2] ,s=0) for x in xList0]) 
ax.plot(xList0,[f0(x,bestFitValues[0],bestFitValues[1],bestFitValues[3] ,s=0) for x in xList0]) 


plt.show() 

#output 
>> [ 1.19841984 2.31591587 0.34936418 0.7998094 ] 

fit with on nonlinear parameter in common

如果需要的話,你甚至可以自己動手讓你的最小化。如果你的參數空間有很好的表現,即近似拋物線最小值,那麼簡單的Nelder Mead method就可以。