How to use Markov Chain Monte Carlo for data fitting

11 visualizaciones (últimos 30 días)
Ella
Ella el 4 de Ag. de 2025
Comentada: Umar el 6 de Ag. de 2025
I'd like to use a Markov Chain Monte Carlo method for parameter estimation, in data fitting with a model. I usually use LSQNONLIN in Matlab, but that does not do a good job for more complicated nonlinear models. I was recomended (by a Python user) to use MCMC, or something more robust for parameter estimation. Apparently I would need the "DREAM" toolbox, which is nowhere to be found. What should I use instead.
Can you give me an example of a basic code, something that I can just adapt slightly and change the 'model' function.
Attached is an example .csv data file (X vs Y). The model is the following (with 2 parameters Imax and k)
Y = 1+(Imax -1)*(k*X)./(55.3e3 + k*X);
The parameter starting values are Imax0 = 1 and k0 = 1e5.
Let's say, the parameters "prior distribution" should be "Uniform" and "posterior distribution" is "Normal".
I'd very much appreciate an example. Thanks!
  1 comentario
Matt J
Matt J el 5 de Ag. de 2025
Your example doesn't appear to be anything LSQNONLIN or LSQCURVEFIT would struggle with,
[X,Y]=readvars('MCMCDataFile.csv');
RHS=(Y-1)*55.3;
c=[(1-Y).*X, X]\RHS;
k0=c(1), Imax0=c(2)/k0+1
k0 = 272.5221
Imax0 = 1.8800
F=@(p,X) 1+(p(1) -1)*(p(2)*X)./(55.3 + p(2)*X);
opts=optimoptions('lsqcurvefit',StepTol=1e-12, OptimalityTol=1e-12, FunctionTol=1e-12);
[p,resn,res]=lsqcurvefit(F,[Imax0,k0], X,Y,[0,100],[],opts);
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x=linspace(min(X),max(X));
plot(X,Y,'o',x,F(p,x))

Iniciar sesión para comentar.

Respuestas (2)

Matt J
Matt J el 5 de Ag. de 2025
Editada: Matt J el 5 de Ag. de 2025
I assume your Python user friend was talking about PyDREAM,
and that you should call it using Matlab's Python interface, e.g.,
Python Code:
# run_dream.py
import numpy as np
from pyDREAM import DREAM
from pyDREAM.parameters import SampledParam
from pyDREAM.Distribution import Uniform
# Define likelihood function
def likelihood(params):
x, y = params
return -((x - 3)**2 + (y + 1)**2)
# Define priors
prior = [SampledParam(Uniform, -10, 10),
SampledParam(Uniform, -10, 10)]
# Run the DREAM sampler
dream = DREAM(prior, likelihood, niterations=1000)
chains = dream.run()
# Save the chains for MATLAB to read
np.save('chains.npy', chains)
Matlab Code:
% Call the Python script using pyrun
pyrun("exec(open('run_dream.py').read())");
% Load the output
chains = py.numpy.load('chains.npy');
chains_mat = double(chains); % Convert to MATLAB array
  2 comentarios
Ella
Ella el 5 de Ag. de 2025
Thanks, for the suggestions, Matt! The "lsqcurvefit' works well for this simple model, but not for more complicated ones (when 2 parameters are somewhat correlated, etc.).
I'd like to try calling "pydream" from Matlab, but after installing pydream, some of the packages are not found, like the pyDREAM.Distribution. Below is what I have in the directory.
Also, what exactely is the "return" function -((x - 3)**2 + (y + 1)**2) supposed to describe?
Thanks!
Matt J
Matt J el 5 de Ag. de 2025
Editada: Matt J el 5 de Ag. de 2025
when 2 parameters are somewhat correlated, etc
I don't know what that means. In what way aren't they correlated in your example? Regardless, if you only have 2 parameters, you can usually just do an exhastive parameter search. No need to fuss with evolutionary algorithms.
Also, what exactely is the "return" function -((x - 3)**2 + (y + 1)**2) supposed to describe?
A fake loglikelihood function. You would replace it with the real loglikelihood for your data distribution.

Iniciar sesión para comentar.


Umar
Umar el 5 de Ag. de 2025
Editada: Walter Roberson el 5 de Ag. de 2025
Hi @Ella,
I read your comments,since I am using Matlab mobile and don’t have access to toolbox,I created a custom MCMC algorithm. Below, I will provide a detailed example that includes the necessary code, explanations, and final plots.
Step 1: Define the Model Function
define your model function in MATLAB.
function Y = model(params, X)
Imax = params(1);
k = params(2);
Y = 1 + (Imax - 1) * (k .* X) ./ (55.3e3 + k .* X);
end
Step 2: Define the Log-Likelihood Function
Next, define a log-likelihood function that will evaluate how well the model fits the data given the parameters.
function logL = logLikelihood(params, X, Y)
Y_pred = model(params, X);
residuals = Y - Y_pred;
logL = -0.5 * sum(residuals.^2); % Assuming normal distribution
end
Step 3: Implement the MCMC Algorithm
Now, implement the MCMC algorithm. This will involve proposing new parameter values, calculating the acceptance ratio, and deciding whether to accept or reject the new parameters.
function [samples, logL_values] = mcmc(X, Y, num_samples, initial_params)
samples = zeros(num_samples, length(initial_params));
logL_values = zeros(num_samples, 1);
current_params = initial_params;
current_logL = logLikelihood(current_params, X, Y);
for i = 1:num_samples
% Propose new parameters
proposed_params = current_params + randn(size(current_params));
% Random walk
% Calculate log-likelihood for proposed parameters
proposed_logL = logLikelihood(proposed_params, X, Y);
% Calculate acceptance ratio
acceptance_ratio = exp(proposed_logL - current_logL);
% Accept or reject the proposed parameters
if rand < acceptance_ratio
current_params = proposed_params;
current_logL = proposed_logL;
end
% Store the samples
samples(i, :) = current_params;
logL_values(i) = current_logL;
end
end
Step 4: Run the MCMC Simulation
Now, run the MCMC simulation using the provided data and initial parameter values.
% Provided data
X = [0; 0.333333333; 0.661417323; 0.984375; 1.302325581; 1.615384615;
1.923664122; 2.227272727];
Y = [1; 1.669344148; 1.712769626; 1.721821986; 1.73873249; 1.774320879;
1.792085924; 1.8151507];
% Initial parameters
initial_params = [1, 1e5]; % Imax0 and k0
num_samples = 10000; % Number of MCMC samples
% Run MCMC
[samples, logL_values] = mcmc(X, Y, num_samples, initial_params);
Step 5: Analyze and Plot the Results
Finally, analyze the results and create plots to visualize the parameter estimates and the fitted model.
% Parameter estimates
Imax_est = mean(samples(:, 1));
k_est = mean(samples(:, 2));
% Generate fitted values
Y_fit = model([Imax_est, k_est], X);
% Plotting
figure;
scatter(X, Y, 'filled', 'MarkerFaceColor', 'b'); % Original data
hold on;
plot(X, Y_fit, 'r-', 'LineWidth', 2); % Fitted model
xlabel('X');
ylabel('Y');
title('Data Fitting using MCMC');
legend('Data', 'Fitted Model');
grid on;
hold off;
% Display estimated parameters
fprintf('Estimated Imax: %.4f\n', Imax_est);
Estimated Imax: 2.1047
fprintf('Estimated k: %.4f\n', k_est);
Estimated k: 100068.4244
Please see attached.
So, if you follow the mentioned steps, you should be able to implement this basic MCMC algorithm for parameter estimation in MATLAB without relying on external toolboxes. You can adapt this simple model function as needed for different models. The provided code includes all necessary components, from defining the model to running the MCMC simulation and visualizing the results. Feel free to modify the number of samples or the proposal distribution to suit your specific needs.
Please note that comments provided by @Matt J sound reasonable and not a bad idea to follow his comments. However, we all are here to help you.
Hope this helps.
  8 comentarios
Ella
Ella el 5 de Ag. de 2025
Umar, this doesn't seem to fit. Possibly something is wrong with the definition of the likelihood function. Thanks, though!
Umar
Umar el 6 de Ag. de 2025

Hi @Ella,

Am I missing something?

Iniciar sesión para comentar.

Categorías

Más información sobre Automotive Applications en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by