我一直在尝试使用MATLAB的拟合函数来拟合幂律分布:ns ~ s^-a (where ns is the probability density function; s is the empirical observation; and a is the scaling exponent)与我的经验数据(参见链接)。然而,我在获得可重现的解决方案时遇到了问题。如果不指定起始点,则每次运行都会得到不同的结果--尽管我使用的是相同的数据集。然后,当我指定一个起始点时,该函数会给出与我指定的起始点相同的结果。此外,无论我是否指定了诸如Levenberg-marquardt之类的算法,或者是否使用了默认算法,问题都仍然存在。我的代码如下:
clc; clear; close all;
%%%%%%%%%%%%%%%%%%% Load data
[data, ~, ~] = xlsread('myDataset.xlsx',1,'A:A');
%%%%%%%%%%%%%%%%%% Histogram plot
data = sort(data);
[y, edges] = histcounts(data, 100000, 'Normalization','pdf');
edges = edges(2:end) - (edges(2)-edges(1))/2;
figure;
scatter(edges, y, 4, 'ro', 'Markerfacecolor', 'r');
hold on;
box on;
edges = edges';
y = y';
%%%%%%%%%%%%%%%%%% Specify input parameters
%(1): cut-off value
xmin = 1*10^5;
%(2): x-values after cut-off
x = edges(edges>=xmin);
ind = find(edges>=xmin,1,'first');
%(3): y-values after cut-off
y([1:ind-1]) = [];
%%%%%%%%%%%%%%%%%% fit power-law model
f = fittype('b*x.^-a');
fModel = fit(x, y, f, 'Algorithm','levenberg-marquardt');
coeffs = coeffvalues(fModel);
plot(fModel,'b--')
set(gca, 'xscale','log', 'yscale','log')
xlabel('s', 'fontsize',8)
ylabel('ns', 'fontsize',8)据说a的值在2.189附近。虽然我可能不会得到这个确切的值-因为它将取决于数据集,但我希望至少得到大约1.5 - 2范围内的值。
我非常感谢任何对解决这个问题有用的帮助、建议或参考。有关经验数据,请参阅以下链接。https://gofile.io/?c=EoEW7k
非常感谢。
发布于 2019-10-16 22:01:07
如果您正在尝试将您的数据适合幂律分布y=ax^b,那么您应该检查this或this链接,因为它们为a和b术语提供了封闭形式的解决方案。
对于方程的适用性的推理,或者对“它来自哪里”的解释,来自于用于获得线性回归的最小二乘拟合的公式。
如果你有一个形式为y=ax+b的方程,你可以从最小二乘线性回归中找到a和b。如果你有幂律,y=ax^b。记录两端并使用logarithm properties获取:
log(y)=log(a)+blog(x)→Y=A+BX→Linear→log(y)=log(ax^b)→→(y=ax^b方程式和方程式→
可以使用log(x)和log(y)的线性回归公式来获得a和b。这避免了使用数值方法来获得非线性拟合的回归。
MATLAB内置函数fit解决了最小二乘拟合的优化问题-它试图最小化残差的平方和。如果您的问题是非线性的,则该算法依赖于良好的初始估计。不同的初始估计可能会产生不同的结果。这就是非线性问题和优化的问题。
作为一个经验法则,每次你必须做拟合,如果你的问题不是线性的,你应该尝试的第一步是看看你是否可以线性化你的方程。如果可以,就像这里的情况一样,您可以获得系数的封闭形式解,而不需要依赖于数值方法和好的/差的初始估计。
https://stackoverflow.com/questions/58414231
复制相似问题