2016-11-03 3 views
1

데이터 집합과 그렇지 않은 데이터 집합간에 공유되는 변수가 여러 개인 데이터 집합에 맞게 만들려고합니다. 그러나 나는 이것을하기 위해 취해야 할 단계가 확실하지 않다. 아래에서는 내가 사용하려고하는 접근법을 보여 줬습니다 ('Issues begins here'가 작동하지 않으며 단지 설명을위한 것임).공유 및 비공유 매개 변수가 조합 된 여러 데이터 집합을 맞추는 방법

In this answer 누군가가 매개 변수를 공유 할 수 있습니다. arcoss datasets이 방법을 사용하면 일부 비공유 매개 변수를 가질 수 있습니다.

누구나 내가 이것을 어떻게 달성 할 수 있었는지, 아니면 누군가가 동일한 결과를 얻기 위해 더 나은 접근 방법을 제안 할 수 있습니까? 감사.

import numpy as np 
from scipy.stats import gamma 
import matplotlib.pyplot as plt 
import pandas as pd 
from lmfit import minimize, Minimizer, Parameters, Parameter, report_fit, Model 


# Create datasets to fit 
a = 1.99 
start = gamma.ppf(0.001, a) 
stop = gamma.ppf(.99, a) 
xvals = np.linspace(start, stop, 100) 
yvals = gamma.pdf(xvals, a) 
data_dict = {} 
for dataset in range(4): 
    name = 'dataset_' + str(dataset) 
    rand_offset = np.random.uniform(-.1, .1) 
    noise = np.random.uniform(-.05, .05,len(yvals)) + rand_offset 

    data_dict[name] = yvals + noise 
df = pd.DataFrame(data_dict) 

# Create some non-shared parameters 
non_shared_param1 = np.random.uniform(0.009, .21, 4) 
non_shared_param2 = np.random.uniform(0.01, .51, 4) 

# Create the independent variable 
ind_var = np.linspace(.001,100,100) 

# Create a model 
def model_func(time, Qi, at, vw, R, rhob_cb, al, NSP1, NSP2): 
    Dt = at * vw 
    Dl = al * vw 

    t = time 

    first_bot = 8 * np.pi * t * rhob_cb 
    sec_bot = np.sqrt((np.pi * (Dl * R) * t)) 
    exp_top = R * np.power((NSP1 - ((t * vw)/R)), 2) 
    exp_bot = 4 * Dl * t 
    exp_top2 = R * np.power(NSP2, 2) 
    exp_bot2 = 4 * Dt * t 
    return (Qi/first_bot * sec_bot) * np.exp(- (exp_top/exp_bot) - (exp_top2/exp_bot2)) 

model = Model(model_func) 

### Issues begin here ### 

all_results = {} 
index = 0 
for col in df: 
    # This block assigns the correct non-shared parameter for the particular fit 
    nsp1 = non_shared_param1[index] 
    nsp2 = non_shared_param2[index] 
    index += 1 

    params = Parameters() 
    at = 0.1 
    al = 0.15 
    vw = 10**-4 
    Dt = at * vw 
    Dl = al * vw 

    # Non-shared parameters 
    model.set_param_hint('NSP1', value = nsp1) 
    model.set_param_hint('NSP2', value = nsp2) 

    # Shared and varying parameters 
    model.set_param_hint('vw', value =10**-4, min=10**-10) 
    model.set_param_hint('at', value =0.1) 
    model.set_param_hint('al', value =0.15) 

    # Shared and fixed parameters 
    model.set_param_hint('Qi', value = 1000, vary = True) 
    model.set_param_hint('R', value = 1.7, vary = True) 
    model.set_param_hint('rhob_cb', value =2895, vary = True) 

    # One set of parameters should be returned 
    result = model.fit(df[col], time = ind_var) 

    all_results[index] = result 
+0

다른 데이터 세트의 샘플 클래스를 예측하려면 해당 데이터 세트의 기능 앙상블을 분류자가 훈련 된 데이터 세트의 것보다 더 투영해야합니다. 즉, 일부 기능을 훈련하고 다른 기능을 테스트 할 수 없습니다! – MMF

+0

@MMF 죄송합니다, 나는 따라 오지 않는다고 생각합니다. 내 다른 데이터 세트는 서로 다른 공간 위치에서 동일한 이벤트를 관찰 한 것입니다. 그런 다음 거리를 고려한 동일한 수식을 사용하여 데이터에 맞 춥니 다.그래서 일부 공유되지 않은 매개 변수 (공간)가 필요하지만 '알 수 없음'매개 변수는 각 관측 지점에서 동일해야합니다. 본질적으로 모든 비공유 매개 변수의 모든 조합을 시도하고 모든 관찰에서 가장 작은 잔차를 생성하는 조합을 반환하고 싶습니다. 내 질문에 완전히 설명 된 접근법이이 문제에 완전히 틀립니까? 당신의 도움을 주셔서 감사합니다! – Bprodz

답변

2

lmfit을 사용하면 항상 하나의 매개 변수 객체를 사용하므로 여러 개의 매개 변수 객체를 사용하지 않습니다.

여러 모델을 유사한 모델 (아마도 동일한 수학 모델이지만 각 모델의 매개 변수 값이 다를 것으로 예상 함)에 동시에 맞추려면 여러 구성 요소 모델의 잔차를 연결하는 객관적인 기능이 필요합니다. 그리고 각 모델은 Parameters()의 단일 인스턴스에서 가져온 매개 변수를 가져야하며 각 매개 변수는 고유 한 이름을가집니다.

그래서, 같은 기능을 가진 2 데이터 세트에 맞게 (의 매개 변수 "센터", "크기"및 "시그마"로, 가우시안을 사용하자), 당신은 그런

params = Parameters() 
params.add('center_1', 5., vary=True) 
params.add('amplitude_1', 10., vary=True) 
params.add('sigma_1', 1.0, vary=True 
params.add('center_2', 8., vary=True) 
params.add('amplitude_2', 3., vary=True) 
params.add('sigma_2', 2.0, vary=True) 

로 매개 변수를 정의 할 수 있습니다 당신이 할 수있는 것처럼

def residual(params, x, datasets): 
    model1 = params['amplitude_1'] * gaussian(x, params['center_1'], params['sigma_1']) 
    model2 = params['amplitude_2'] * gaussian(x, params['center_2'], params['sigma_2'] 

    resid1 = datasets[0] - model1 
    resid2 = datasets[1] - model2 
    return np.concatenate((resid1, resid2)) 

fit = lmfit.minimize(residual, params, fcn_args=(x, datasets)) 

로 아마, 두 번째의 모델을 계산하는 등등 첫 번째 데이터 세트에 대한 모델과 'center_2'을 계산하는 'center_1', 'amplitude_1'및 'sigma_1'를 사용 이 값을 볼 수 있으면 매개 변수 값은 기본적으로 독립적입니다. 다른 데이터 세트에서 사용할 매개 변수 값을 공유하려면 명시 적으로 지정해야합니다 (사용자가 제공 한 링크 된 답변에 표시된대로).

params.add('sigma_2', expr='sigma_1') 

당신은에 추가 할 두 진폭을 요구할 수 : 동일한 일하기 위해 sigma 값을 필요로 할 경우

예를 들어, 단지 매개 변수 정의에 위의 잔여 기능을, 변하지 않을 것 일부 값 :

params.add('amplitude_2', expr='10 - amplitude_1') 

아니면 당신이 'center_2가'center_1 '보다 큰 것을 보장 할 것이지만, 금액으로는 적합 결정한다 :

params.add('center_offset', value=0.5, min=0) 
params.add('center_2', expr='center_1 + center_offset') 

이들은 모두 매개 변수 값을 연결하는 방법입니다. 기본적으로 이들은 독립적입니다. 물론 모든 모델에서 사용되는 매개 변수를 가질 수도 있습니다 (예 : 매개 변수 'sigma'를 호출하여 모든 모델에 사용).