'Likelihood of pykalman filter yields the same result each time
I'm trying to calibrate a Schwartz Smith two factor model using the Kalman Filter. The idea is to get the parameters that maximize the likelihood.
The math behind the calibration can be checked here:


The likelihood output is stuck at 134 even when I'm randomly choosing values for the parameters. Can anyone help me with this ?
def objective_function(kalman_params, args):
forward_data = args[0]
dt = args[1]
number_of_timesteps = forward_data.shape[0]
observation_dimensions = forward_data.shape[1]
#print('The observation dimensions are ', observation_dimensions)
states = np.zeros((number_of_timesteps, 2))
#print('The states dimension is ', states.shape)
measurements = forward_data
measurements['Spot'] = np.log(measurements['Spot'])
measurements = measurements.values
#print('The measurements dimension is : ', measurements.shape)
kappa = kalman_params[0]
sigma_xi = kalman_params[1]
sigma_epsilon = kalman_params[2]
rho = kalman_params[3]
mu_epsilon_star = kalman_params[4] - kalman_params[5]
lambda_xi = kalman_params[5]
initial_state_mean = np.zeros(2)
initial_state_covariance = np.identity(2)
#rint('The initial state covariance shape is ', initial_state_covariance.shape)
cov_1_1 = (sigma_xi**2 / (2 * kappa)) * (1 - np.exp(- 2 * kappa * dt))
cov_1_2 = (rho * sigma_xi * sigma_epsilon / (kappa)) * (1 - np.exp(- kappa * dt))
cov_2_1 = cov_1_2
cov_2_2 = sigma_epsilon**2 * dt
transition_covariance = np.array([[cov_1_1, cov_1_2] , [cov_2_1, cov_2_2]])
#print('The transition covariance matrix shape is ', transition_covariance.shape)
observation_covariance = np.identity(observation_dimensions)
#print('The observation covariance matrix shape is ', observation_covariance.shape)
A_matrix = []
C_matrix = []
forward_contracts = []
for t in forward_data.index:
A_temp = [0]
C_temp = [[1,1]]
for forward in forward_data.columns:
if forward == 'Spot':
continue
if 'months' in forward:
maturity = int(forward.replace(' months', ''))/12
else:
maturity = int(forward.replace(' month', ''))/12
ti = t / 267
forward_contract = ForwardContract(ti, maturity, forward_data['Spot'].loc[t], None, forward_data[forward].loc[t])
forward_contracts.append(forward_contract)
instant_ti = forward_contract.t
maturity_T = forward_contract.T
A_temp.append(A(instant_ti, maturity_T, sigma_epsilon, sigma_xi, mu_epsilon_star, kappa, lambda_xi, rho))
C_temp.append([np.exp(-kappa * (maturity_T - instant_ti)), 1])
A_matrix.append(A_temp)
C_matrix.append(C_temp)
A_matrix = np.array(A_matrix)
#print(A_matrix)
displacement = [[0, mu_epsilon_star] for i in range(number_of_timesteps - 1)]
transition_displacement = np.array(displacement)
#print('The transition offset shape is ', transition_displacement.shape)
observation_displacement = A_matrix
#print('The observation offset shape is ', A_matrix.shape)
transition = [[[np.exp(-kappa * dt), 0], [0, 1]] for i in range(number_of_timesteps - 1)]
transition_matrix = np.array(transition)
#print('The transition matrix shape is ', transition_matrix.shape)
#print(transition_matrix)
observation_matrix = np.array(C_matrix)
#print('The observation matrix shape is ', observation_matrix.shape)
print(observation_matrix)
variables = ['transition_matrices', 'observation_matrices', 'transition_offsets', 'observation_offsets', 'transition_covariance', 'observation_covariance']
kalman_fliter = KalmanFilter(transition_matrices = transition_matrix,
observation_matrices = observation_matrix,
transition_covariance = transition_covariance,
observation_covariance = observation_covariance)
#transition_offsets = transition_displacement,
#observation_offsets = observation_displacement,
#initial_state_mean = initial_state_mean,
#initial_state_covariance = initial_state_covariance,
#em_vars = variables,
#n_dim_state = states.shape[1],
#n_dim_obs = observation_dimensions)
#fitted = kalman_fliter.em(measurements, n_iter = 100, em_vars = variables).smooth(measurements)
#hidden = np.exp(fitted[0][:,1] + fitted[0][:,0])
#error = abs(forward_data['Spot'] - hidden).mean()
lk = kalman_fliter.loglikelihood(measurements)
print(lk)
return -lk
#return error
def A(T, t, sigma_epsilon, sigma_xi, mu_epsilon_star, kappa, lambda_xi, rho):
return (mu_epsilon_star + sigma_epsilon**2 / 2) * (T - t) - (1 - np.exp(-kappa * (T - t))) * lambda_xi / kappa + sigma_xi**2 * (1 - np.exp(-2 * kappa * (T - t))) / (4 * kappa) + rho * sigma_xi * sigma_epsilon * (1 - np.exp(- kappa * (T - t))) / kappa
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
