1

도둑은 게시물이 실제로 보이는 것보다 오래 보이게합니다. 또한, 내 질문은 함수 호출의 체인 맨 위에 함수에 관한 것입니다. 작동이 특정 비 numpy 함수를 어떻게 벡터화 할 수 있습니까?

부분은 :

나는 카이의 윤곽 플롯가 지정된 메일에 대한 값을 제곱하고 싶습니다. 등고선 플롯을 만드는 방법의 기본 사항을 이해하지만 기본 예제 외부의 기술을 적용 할 수는 없습니다. 문제는 내 기능을 벡터화하는 데있을 수 있습니다. 샘플로서 1000 점의 샘플 가우시안 데이터 집합을 고려해보십시오. 평균 및 확산은 각각 48과 7입니다.

# imports: import numpy as np, import random, from math import pi, from scipy.integrate import quad, from scipy.stats import chisquare, from scipy.optimize import minimize 

dataset_gauss = [random.gauss(48, 7) for index in range(1000)] 

내 기능과 변수 이름은 내 전체 코드는 최대 로그 우도를 사용하여 여러 분포 (가우스, 로그 정규)

def equation_gauss(x, a, b): 
    """ 
    This function returns the equation for the Gaussian distribution. 
    """ 
    cnorm = 1/(b* (2*pi)**(1/2)) 
    return cnorm * np.exp((-1) * (x - a)**2/(2* b**2)) 

이 걸리기 때문에 그들이있는 방법입니다, 내 스크립트 (관련이없는이 질문에 코드는 표시되지 않음)는 params_gauss = [47.972906400237889, 7.0241339595841286]을 반환합니다.

카이 제곱을 계산하려면 먼저 빈 경계 목록을 작성해야합니다. 그러면 각각의 기대 값을 각 빈에 대한 빈 왼쪽에서 오른쪽으로의 분배 방정식의 적분과 같게 할 수 있습니다. 각 빈의 관측 값은 해당 빈 내의 관측 값의 수입니다. 예상 값으로 나눈 빈 당 기대 값과 관측 값의 제곱의 차를 합함으로써 카이 제곱을 계산할 수 있습니다.

def get_bins(distribution, num_bins=50): 
    """ 
    This function returns a specified number of equally sized bins over 
    the domain of the distribution. 
    """ 
    if distribution == 'gauss': 
     dataset = dataset_gauss 
    return np.linspace(min(dataset), max(dataset), num_bins) 

def get_binned_expectations(distribution, args): 
    """ 
    This function returns the expectation values per bin for a dataset 
    given by the specified distribution. 
    """ 
    if distribution == 'gauss': 
     dataset = dataset_gauss 
     func = equation_gauss 
    num_obs = len(dataset) 
    bins = get_bins(distribution) 
    res = [] 
    for idx in range(len(bins)): 
     if idx != len(bins)-1: 
      res.append(quad(func, bins[idx] , bins[idx+1], args = (args[0] , args[1]))[0] * num_obs) 
    return res 

def get_binned_observations(distribution): 
    """ 
    This function returns the observation values per bin for a dataset 
    given by the specified distribution. 
    """ 
    if distribution == 'gauss': 
     dataset = dataset_gauss 
    bins = get_bins(distribution) 
    bin_count = [] 
    for idx in range(len(bins)): 
     if idx != len(bins)-1: 
      summ = 0 
      for datum in dataset: 
       if datum > bins[idx] and datum <= bins[idx+1]: 
        summ += 1 
      bin_count.append(summ) 
     if idx == len(bins)-1: 
      pass 
    return bin_count 

def get_chi_square(distribution, params): 
    """ 
    This function returns the chi square value for a specified 
    distribution. 

    EX: 
     distribution : 'gauss', 'lognormal' 

     params   : [a, b] for parameters a and b 
          'opt' (for optimized parameters) 
    """ 
    values_observation = get_binned_observations(distribution) 
    if params == 'opt': 
     if distribution == 'gauss': 
      params = params_gauss 
    values_expectation = get_binned_expectations(distribution, params) 
    return chisquare(values_observation, values_expectation) 

확인으로의 해보자 : 두번째 값 pvalue 적합 파라미터의 확률이있을

res = get_chi_square('gauss', params='opt') 
print(res) 
new_params = [40, 10] 
new_res = get_chi_square('gauss', params=new_params) 
print(new_res) 

>> Power_divergenceResult(statistic=55.465132812431413, pvalue=0.21391356257718666) 
>> Power_divergenceResult(statistic=14950.604250041084, pvalue=0.0) 

첫 번째 값 statistic는 치 해당 파라미터로 얻어진 값의 제곱이다. 제 목적을 위해서는 첫 번째 요소 만 print(new_res[0])이라고 부르는 것이 가장 좋습니다. (자유도가 명시되지 않았기 때문에 확률이 정확하지 않습니다.)

윤곽 플롯을 만들기 위해 dim-2 배열을 통해 격자 공간을 생성해야한다는 것을 이해했습니다. 먼저 각 매개 변수에 대한 숫자 목록을 반환하는 함수를 작성합니다. X, Ymeshgridx, y을 반환하는 함수입니다.

def get_axis_data(param, frac, size): 
    """ 
    This function returns a specified number of elements in a range 
    centered around the value of the inputted parameter. The extrema 
    of this range are specified as: 
        param ± param * frac 
    """ 
    update = frac * param 
    return np.linspace(param - update, param + update, size) 

내 문제 :

내가 plt.contourf(X, Y, Z, cmap)를 사용할 수 있다는 것을 알고. 하지만, 을 입력으로 사용하여 meshgrid -ed 매개 변수를 입력하는 방법을 모르겠다. 목록 최적화 매개 변수를 통해 (효율적으로) 카이 제곱을 계산하기 위해 scipy 모듈을 호출하기 때문에. 내가 실패한 것을 주석 처리했습니다. 위의 실행

def get_grid_data(distribution, frac=1/4, size=9, func=get_chi_square, cmap='plasma'): 
    """ 
    This function returns the grid values for a contour plot of the 
    error metric as a function of the parameters of a specified 
    distribution. 

    EX: 
     func: 'chi square', 'maximum log-likelihood' (error metric) 
    """ 
    if distribution == 'gauss': 
     opt_params = params_gauss 
    a_vals = get_axis_data(opt_params[0], frac, size) 
    b_vals = get_axis_data(opt_params[1], frac, size) 
    X, Y = np.meshgrid(a_vals, b_vals) 
    # func = np.vectorize(func) 
    # Z = func(distribution, [X, Y])[0] 
    return X, Y#, Z 

X, Y = get_grid_data('gauss') 
print("X") 
print(X) 
print("") 
print("Y") 
print(Y) 

을 제공합니다

X 
[[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ] 
[ 35.9796798 38.97798645 41.9762931 44.97459975 47.9729064 
    50.97121305 53.9695197 56.96782635 59.966133 ]] 

Y 
[[ 5.26810047 5.26810047 5.26810047 5.26810047 5.26810047 5.26810047 
    5.26810047 5.26810047 5.26810047] 
[ 5.70710884 5.70710884 5.70710884 5.70710884 5.70710884 5.70710884 
    5.70710884 5.70710884 5.70710884] 
[ 6.14611721 6.14611721 6.14611721 6.14611721 6.14611721 6.14611721 
    6.14611721 6.14611721 6.14611721] 
[ 6.58512559 6.58512559 6.58512559 6.58512559 6.58512559 6.58512559 
    6.58512559 6.58512559 6.58512559] 
[ 7.02413396 7.02413396 7.02413396 7.02413396 7.02413396 7.02413396 
    7.02413396 7.02413396 7.02413396] 
[ 7.46314233 7.46314233 7.46314233 7.46314233 7.46314233 7.46314233 
    7.46314233 7.46314233 7.46314233] 
[ 7.9021507 7.9021507 7.9021507 7.9021507 7.9021507 7.9021507 
    7.9021507 7.9021507 7.9021507 ] 
[ 8.34115908 8.34115908 8.34115908 8.34115908 8.34115908 8.34115908 
    8.34115908 8.34115908 8.34115908] 
[ 8.78016745 8.78016745 8.78016745 8.78016745 8.78016745 8.78016745 
    8.78016745 8.78016745 8.78016745]] 

나는 위의 코드에서 X 또는 Y의 동일한 형식으로 Z를 인쇄하고 싶습니다.이런 식으로 어떻게 카이 제곱 함수 값을 얻을 수 있습니까?

편집 : get_grid_params하는 기능 get_grid_data 변경 아래로 이루어진다 I 카이 스퀘어 값 (81)을 생성 할 수 get_grid_data 재정의 경우

. 나는 이것이 앞으로 나아갈 것으로 생각하지만, 윤곽 플롯을 위해 res (위의 Z으로 표시)의 배열 요소 순서에 대해 확신 할 수 없습니다.

def get_grid_params(distribution, frac, size): 
    """ 
    This function returns the grid values for a contour plot of the 
    error metric as a function of the parameters of a specified 
    distribution. 

    EX: 
     func: 'chi square', 'maximum log-likelihood' (error metric) 
    """ 
    if distribution == 'gauss': 
     opt_params = params_gauss 
    a_vals = get_axis_data(opt_params[0], frac, size) 
    b_vals = get_axis_data(opt_params[1], frac, size) 
    X, Y = np.meshgrid(a_vals, b_vals) 
    # func = np.vectorize(func) 
    # Z = func(distribution, [X, Y]) 
    return X, Y 

def get_grid_data(distribution, frac=1/4, size=9, func=get_chi_square): 
    """ 

    """ 
    X, Y = get_grid_params(distribution, frac, size) 
    res = [] 
    for idx in range(len(X)): 
     for jdx in range(len(Y)): 
      res.append(func(distribution, [X[idx][jdx], Y[idx][jdx]])[0]) 
    print(res) 
get_grid_data('gauss') 

# 81 elements ==> 9x9 grid 
[4208765217.1232886, 79756867.433148235, 2102012.2187297232, 77845.812346977109, 4299.2223157168837, 2529.7286507333743, 20486.858965000847, 257923.37090704756, 4854102.2912357552, 93281349.868633255, 3214630.1060019895, 149308.23999474355, 9526.0996064385563, 892.28204593366377, 1078.7222202890009, 6755.3095776326609, 53291.09528539874, 588864.18413363863, 4691132.998034155, 266721.46912966535, 20459.717521392733, 2093.3255539124393, 279.78284725132187, 577.3737260040574, 3111.9705345888774, 17462.38755758019, 125880.4188491786, 450519.22715869371, 40667.241172187212, 5020.7992346344054, 744.8798302729781, 116.9962855442742, 364.63898596547921, 1791.3456214870084, 7916.7426067634342, 40972.313769493878, 76104.092836489493, 10798.249475713539, 2013.1185415524558, 381.52353083113587, 66.126519584745949, 264.93942984225561, 1200.5798834763946, 4482.867919608283, 18107.837200860213, 21572.225934943446, 4551.094178016996, 1136.7099239043926, 253.51850353558262, 54.455759914884304, 218.13425049819415, 897.03841272531849, 2952.9334085022683, 9936.4277408736034, 9337.1516297669732, 2622.2698023608255, 789.26686546629082, 202.78664001629076, 60.365012999827258, 199.40257099587109, 726.84333101567586, 2159.6632005396755, 6339.5377293121628, 5372.7483380962221, 1815.8139713332946, 620.16531689499118, 184.61780691354744, 75.563465535153725, 196.96163816097214, 626.64757117448494, 1701.8233311097256, 4494.3117008380068, 3664.4699687203392, 1400.0096023072927, 527.65588603959168, 182.94718825996048, 96.20249715692033, 204.59025315045054, 566.75361531867895, 1416.8609878368447, 3434.8994517014899] 
# reshape as 9x9 shows the order of params is wrong. 

답변

0

get_chi_squarethis answer의 코드로 정의되어있는 섹션 the desired output를 생성 할 때까지 상기 코드를 결합 (그러나 포함) 출력한다.

관련 문제