Lognormal Fitting with the Pore Size and its Probabilities

8 visualizzazioni (ultimi 30 giorni)
Dear all,
I have some pore sizes and its probabilites. Visually the pore size distribution follows the lognormal distribution, and the particle size distribution usually follows lognormal distribution, as the black line in the figure shows. So I try to fit it to a lognormal distribution with the following code:
Counts = [71 73 53 77 79 141 158 237 360 594 958 1659 3094 7183 19034 40051 125001 143248 164224 168209 172406 167600 160578 146530 124505 90064 67769 42179 21645 1070];
PoreSize = [89716.4 71264.3 56607.2 44964.7 35716.7 28370.8 22535.7 17900.8 14219.1 11294.6 8971.6 7126.4 5660.7 2837.1 2253.6 1790.1 712.6 566.1 449.6 357.2 283.7 225.4 179 142.2 112.9 89.7 71.3 56.6 45 35.7];
probs = Counts / sum(Counts);
ExpOfY = sum(PoreSize.*probs);
Ysqr = PoreSize.^2;
ExpOfYsqr = sum(Ysqr.*probs);
VarOfY = ExpOfYsqr - ExpOfY1^; % variance of the scores tabulated in vectors 1 & 2
Invalid expression. Check for missing or extra characters.
normu = log(ExpOfY/sqrt(1+VarOfY/ExpOfY^2));
norvar = log(1+VarOfY/ExpOfY^2);
norsigma = sqrt(norvar);
dist = makedist('Lognormal','mu',normu1,'sigma',norsigma1);
x = linspace(0.001,200000,2000000); % Use whatever range is appropriate for data
pdfOfx1 = pdf(dist,x);
figure; hold on; plot(PoreSize,Counts);
plot(x,pdfOfx * 6200); % Multiply 6200 just to compare with the original data.
After fitting, the results look wired, comparing with the raw data point distribution. The agreement between the fitting and the original looks quite bed.I have also tried to use the makedist, the results look similar as well. Does anyone know the reason?
Best
  18 Commenti
Rena Berman
Rena Berman il 21 Feb 2024
Modificato: Rena Berman il 21 Feb 2024
(Answers Dev) @William Rose, @the cyclist, I have forwarded this on to the appropriate MW developers.

Accedi per commentare.

Risposta accettata

William Rose
William Rose il 8 Gen 2024
Take the logarithm of the pore sizes, then compute mu and sigma using the log(pore size) vector. The mu, sigma computed that way are what you should pass to makedist('Lognormal',...). Perhaps the rest of your code will work correctly after that.
  27 Commenti
Torsten
Torsten il 19 Gen 2024
He used Matlab's lsqcurvefit() to find the mu and sigma that gives the n=best fit, in a least-squares sense, to the data.
Although it will be difficult to find a statistical justification to use function fitting methods in distribution fitting ...
William Rose
William Rose il 19 Gen 2024
I see from @Torsten's plots above that the MOM estimates of mu, sigma give a PDF that looks terrible (green line) on the semi-log plot. MOM also gave a visually unacceptable solution for @Alex Lee's data.

Accedi per commentare.

Più risposte (2)

Hassaan
Hassaan il 8 Gen 2024
Modificato: Hassaan il 8 Gen 2024
% Given Data
Counts = [71 73 53 77 79 141 158 237 360 594 958 1659 3094 7183 19034 40051 125001 143248 164224 168209 172406 167600 160578 146530 124505 90064 67769 42179 21645 1070];
PoreSize = [89716.4 71264.3 56607.2 44964.7 35716.7 28370.8 22535.7 17900.8 14219.1 11294.6 8971.6 7126.4 5660.7 2837.1 2253.6 1790.1 712.6 566.1 449.6 357.2 283.7 225.4 179 142.2 112.9 89.7 71.3 56.6 45 35.7];
probs = Counts / sum(Counts);
% Calculating Expected Values and Variance
ExpOfY = sum(PoreSize.*probs);
Ysqr = PoreSize.^2;
ExpOfYsqr = sum(Ysqr.*probs);
VarOfY = ExpOfYsqr - ExpOfY^2; % Corrected the typo here
% Calculating the parameters for the lognormal distribution
normu = log(ExpOfY/sqrt(1+VarOfY/ExpOfY^2));
norvar = log(1+VarOfY/ExpOfY^2);
norsigma = sqrt(norvar);
% Create a lognormal distribution object
dist = makedist('Lognormal','mu',normu,'sigma',norsigma);
% Define the range for your data (adjust as needed)
x = linspace(min(PoreSize), max(PoreSize), 1000);
% Calculate the PDF
pdfOfx = pdf(dist,x);
% Plotting the data
figure; hold on;
scatter(PoreSize,Counts, 'b'); % Scatter plot of the original data
plot(x,pdfOfx * max(Counts), 'r'); % Plot of the fitted distribution
xlabel('Pore Size');
ylabel('Counts');
title('Pore Size Distribution with Lognormal Fit');
legend('Data','Lognormal Fit');
hold off;
  1. Syntax and Typographical Errors: Ensure that all variable names and operations are correct. The expression VarOfY = ExpOfYsqr - ExpOfY1^; in your original code seems to contain errors. It's corrected here.
  2. Visualizing Data: I've used a scatter plot for the original data and a line plot for the fitted distribution. Adjust the scaling factor (max(Counts)) as needed to better compare the two.
  3. Data Range: The range of x in the line x = linspace(min(PoreSize), max(PoreSize), 1000); is set from the minimum to the maximum of your pore sizes. Adjust this as necessary.
  4. Distribution Parameters: The 'mu' and 'sigma' for a lognormal distribution are derived from the logarithm of your data. Ensure these are calculated correctly.
  5. Fitting and Model Choice: If the fit is still poor, consider alternative fitting methods or distributions. The fit quality can vary significantly based on the characteristics of your data.
---------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering

Torsten
Torsten il 8 Gen 2024
Modificato: Torsten il 8 Gen 2024
Counts = [71 73 53 77 79 141 158 237 360 594 958 1659 3094 7183 19034 40051 125001 143248 164224 168209 172406 167600 160578 146530 124505 90064 67769 42179 21645 1070];
PoreSize = [89716.4 71264.3 56607.2 44964.7 35716.7 28370.8 22535.7 17900.8 14219.1 11294.6 8971.6 7126.4 5660.7 2837.1 2253.6 1790.1 712.6 566.1 449.6 357.2 283.7 225.4 179 142.2 112.9 89.7 71.3 56.6 45 35.7];
data = [];
for i = 1:numel(Counts)
data = [data,PoreSize(i)*ones(1,Counts(i))];
end
phat = mle(data,'Distribution','LogNormal')
phat = 1×2
5.5569 0.8497
x = linspace(0,2000,1000);
hold on
plot(x,lognpdf(x,phat(1),phat(2)),'g')
histogram(data,'Normalization','pdf')
xlim([0 2000])
probs = Counts / sum(Counts);
ExpOfY = sum(PoreSize.*probs);
Ysqr = PoreSize.^2;
ExpOfYsqr = sum(Ysqr.*probs);
VarOfY = ExpOfYsqr - ExpOfY^2; % variance of the scores tabulated in vectors 1 & 2
normu = log(ExpOfY^2/sqrt(VarOfY+ExpOfY^2))
normu = 4.9283
norvar = log(1+VarOfY/ExpOfY^2);
norsigma = sqrt(norvar)
norsigma = 1.4788
plot(x,lognpdf(x,normu,norsigma),'b')
hold off

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by