Main Content

並列計算を使用するブートストラップの実装

逐次または並列でのブートストラップ

ここでは、並列と逐次でブートストラップの時間を計測する例を示します。この例では、2 つのガウスの混合からデータを生成して結果として得られるデータのノンパラメトリックな推定を構築し、ブートストラップを使用してサンプリングの変化量がどのようなものであるかを予測します。

  1. データを次のように生成します。

    % Generate a random sample of size 1000,
    % from a mixture of two Gaussian distributions 
    x = [randn(700,1); 4 + 2*randn(300,1)];
  2. データからノンパラメトリックな密度推定を次のように構築します。

    latt = -4:0.01:12;
    myfun = @(X) ksdensity(X,latt); 
    pdfestimate = myfun(x);
  3. サンプリングのばらつきを調べるために推定をブートストラップします。時間比較のために逐次でブートストラップを実行します。

    tic;B = bootstrp(200,myfun,x);toc
    
    Elapsed time is 10.878654 seconds.
  4. 時間比較のために並列でブートストラップを実行します。

    mypool = parpool()
    Starting parpool using the 'local' profile ... connected to 2 workers.
    
    mypool = 
    
      Pool with properties:
    
        AttachedFiles: {0x1 cell}
           NumWorkers: 2
          IdleTimeout: 30
              Cluster: [1x1 parallel.cluster.Local]
         RequestQueue: [1x1 parallel.RequestQueue]
          SpmdEnabled: 1
    
    opt = statset('UseParallel',true);
    tic;B = bootstrp(200,myfun,x,'Options',opt);toc
    
    Elapsed time is 6.304077 seconds.

    この例では、並列計算が逐次計算との比較で 2 倍近く高速になることがわかります。

ksdensity の密度推定を並列ブートストラップで取得された 200 個のブートストラップ済み推定に重ねます。このプロットの密度推定の正確さを評価するための手がかりが得られます。

hold on
for i=1:size(B,1),
    plot(latt,B(i,:),'c:')
end
plot(latt,pdfestimate);
xlabel('x');ylabel('Density estimate')

Plot of density estimate versus x.

再現可能な並列ブートストラップ

再現可能な方法でこの例を並列実行するには、オプションを適切に設定します (再現性のある並列計算を実行するを参照)。まず、問題と並列環境を 逐次または並列でのブートストラップにあるように設定します。その後、サブストリームを使用するオプションと共に、サブストリームをサポートするストリームをオプションに設定します。

s = RandStream('mlfg6331_64'); % has substreams
opts = statset('UseParallel',true,...
    'Streams',s,'UseSubstreams',true);
B2 = bootstrp(200,myfun,x,'Options',opts);

ブートストラップを再度実行して同じ結果を得るには、次の手順を実行します。

reset(s) % set the stream to initial state
B3 = bootstrp(200,myfun,x,'Options',opts);
isequal(B2,B3) % check if same results

ans =
     1