I'm doing a bootstrap based on this thread with the following code (file.txt here):
import = Import["file.txt", "List"];
data = Log[10, import];
data = Delete[data, Position[data, RankedMin[data, 1]][[1, 1]]];
data = Delete[data, Position[data, RankedMin[data, 1]][[1, 1]]];
data = Delete[data, Position[data, RankedMax[data, 1]][[1, 1]]];
dist=MixtureDistribution[{p,1-p},{NormalDistribution[μ1, σ1],NormalDistribution[μ2, σ2]}];
param=FindDistributionParameters[data,dist,{{μ1,-0.02},{σ1,0.66},{μ2,1.47},{σ2,0.47},{p,0.21}},ParameterEstimator->{"MaximumLikelihood",Method->"NMaximize"}];
bootstrap=Table[FindDistributionParameters[RandomVariate[dist/.param,Length[data]],dist,{{μ1,-0.02},{σ1,0.66},{μ2,1.47},{σ2,0.47},{p,0.21}},ParameterEstimator->{"MaximumLikelihood",Method->"NMaximize"}],{10}];
param
takes 11 sec, I'd expect bootstrap
to take approx. 110 sec or something a bit longer (RandomVariate
itself takes 0.02 sec, so seems irrelevant for the absolute timing), but actually it takes about 400 sec - looks like $O(n^2)$.
On a 4-core machine, using ParallelTable
I can get down to about 100 sec, but that's a side issue - I want to do it 100 or 1000 times. In the latter I expect the code to take $\approx 11\times 1000 sec=3 hrs$, and using ParallelTable
go under 1 hr.
In my understanding the above code does the same task (taking 11 sec) multiple times independently of each other, so two tasks should take 22 sec and so on. However, even Table
with only two iterations take 36 sec.
Where am I wrong and how to optimize this?
EDIT I checked what happens when I change p
to E^w/(1+E^w)
(also changing Table
to ParallelTable
to speed things up):
dist=MixtureDistribution[{E^w/(1+E^w),1/(1+E^w)},{NormalDistribution[μ1, σ1],NormalDistribution[μ2, σ2]}];
param=FindDistributionParameters[data,dist,{{μ1,-0.02},{σ1,0.66},{μ2,1.47},{σ2,0.47},{w,Log[1/3.]}},ParameterEstimator->{"MaximumLikelihood",Method->"NMaximize"}];
bootstrap=ParallelTable[FindDistributionParameters[RandomVariate[dist/.param,Length[data]],dist,{{μ1,-0.02},{σ1,0.66},{μ2,1.47},{σ2,0.47},{w,Log[1/3.]}},ParameterEstimator->{"MaximumLikelihood",Method->"NMaximize"}],{10}];
and it takes 162 sec compared to 115 sec using p
as in my initial post.
EEDIT2 After Sjoerd's answer I checked what happens when I set in my initial bootstrap
code {p,0.4}
: 100 executions take 230 sec, 200 executions - 470 sec. Almost linearly. So it appears, like in the accepted answer, that near the correct values the algorithms needs many iterations to converge and it takes lots of time. Probably setting also other starting values (for $\mu_i$ and $\sigma_i$) would improve the timing even more.
import
on the first line should probably bedata
, right? $\endgroup$MixtureDistribution
knows the parameter range but whetherFindDistributionParameters
knows this. It has really no way of knowing this; so, this is where things go wrong. $\endgroup$