我一直在尝试使用MATLAB的fit函数将幂定律分布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
非常感谢。
答案 0 :(得分:0)
如果您要使数据适合幂律分布y=ax^b
,则应检查this或this链接,因为它们为{{ 1}}和a
项。
方程式适用性的原因,或“方程式的来源”的解释来自用于获得线性回归的最小二乘拟合的公式。
如果方程式为b
,则可以从最小二乘线性回归中找到y=ax+b
和a
。如果您有幂律,请b
。记录双方并使用logarithm properties获取以下信息:
y=ax^b
→y=ax^b
→log(y)=log(ax^b)
→log(y)=log(a)+blog(x)
→线性方程式
您可以对Y=A+BX
和log(x)
使用线性回归公式来获得log(y)
和a
。这样避免了使用数值方法来获得非线性拟合的回归。
MATLAB内置函数fit解决了最小二乘拟合的优化问题-它试图最小化残差平方和。如果您的问题是非线性的,则该算法将基于良好的初始估计。不同的初始估计可能会产生不同的结果。那就是非线性问题和优化的问题。
根据经验,每次必须进行拟合时,如果问题不是线性的,则应该尝试的第一步是查看是否可以线性化方程式。如果可以的话(如此处的情况),您可以采用系数的封闭式解决方案,而不必依靠数值方法和好的/差的初始估计。