도둑은 게시물이 실제로 보이는 것보다 오래 보이게합니다. 또한, 내 질문은 함수 호출의 체인 맨 위에 함수에 관한 것입니다. 작동이 특정 비 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, Y
이 meshgrid
인 x, 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.