Main Content

MapReduce を使用するヒストグラムの作成

次の例は、大規模なデータ セット内のパターンを、すべての観測値を同時にメモリに読み込まずに可視化する方法を示します。グラフィックスを生成するのに十分な、容量の少ないデータの要約を計算する方法を示します。

ヒストグラムは、変数の確率密度関数 (pdf) の推定値を得るための、一般的な可視化手法です。ヒストグラムを使用すると、加工されていない入力データのサイズをカウントのベクトルに縮小できるため、ビッグ データ環境に適しています。各カウントは、一連の連続する数値間隔のビンのそれぞれに該当する観測値の数です。

関数 mapreduce は、データの複数のブロックに対して別々にカウントを計算します。次に、mapreduce はすべてのブロックのカウントを合計します。この例では、map 関数と reduce 関数はどちらも非常にシンプルです。それでいて、そこから収集される要約情報を柔軟に可視化できます。

データの準備

airlinesmall.csv データ セットを使用してデータストアを作成します。この 12 MB のデータ セットには、到着時間と出発時間を含む、いくつかの航空会社のフライト情報が 29 列に含まれます。この例では、ArrDelay (フライト到着遅延時間) を目的の変数として選択します。

ds = tabularTextDatastore('airlinesmall.csv', 'TreatAsMissing', 'NA');
ds.SelectedVariableNames = 'ArrDelay';

データストアは、既定では 'NA' 値を欠損として扱い、欠損値を NaN 値に置換します。さらに、SelectedVariableNames プロパティにより、選択した目的の変数のみを処理することができ、preview を使用して検査できます。

preview(ds)
ans=8×1 table
    ArrDelay
    ________

        8   
        8   
       21   
       13   
        4   
       59   
        3   
       11   

mapreduce の実行

関数 mapreduce は、入力として map 関数と reduce 関数を必要とします。マッパーはデータのブロックを受け取って中間結果を出力します。リデューサーは中間結果を読み取って最終結果を生成します。

次の例では、マッパーは到着遅延時間をビンに累積することにより、さまざまな到着遅延時間のフライトのカウントを収集します。ビンは、map 関数の 4 番目の入力引数 edges で定義されます。

map 関数のファイルを表示します。

function visualizationMapper(data, ~, intermKVStore, edges)
  % Count how many flights have arrival delay in each interval specified by
  % the EDGES vector, and add these counts to INTERMKVSTORE.
  counts = histc(data.ArrDelay, edges);
  add(intermKVStore, 'Null', counts);
end

ヒストグラムのビンのサイズは重要です。ビンが広すぎると、データ セットの重要な詳細情報が分かりにくくなります。ビンが狭すぎると、ヒストグラムにノイズが多く含まれる場合があります。非常に大規模なデータ セットを処理する場合は、様々なビン幅を試して複数のパスをデータに対して作成するのを避けることをお勧めします。複数のパスを作成するのを避ける簡な方法は、幅の狭いビンでカウントを収集することです。そうすれば、ビンの幅を広げたい場合には生データを再処理しなくても隣接するビンを集計するだけで済みます。フライト到着遅延時間は、1 分刻みで記録されるため、1 分のビンを -60 分から 599 分まで定義します。

edges = -60:599;

無名関数を作成して、map 関数でビン エッジを使用するように構成します。無名関数を使用すると、4 番目の入力引数に特定の値を指定することにより、map 関数を特殊化できます。これで、関数 mapreduce が想定する 3 つの入力引数のみを使用して、map 関数を無名関数から呼び出すことができます。

ourVisualizationMapper = ...
    @(data, info, intermKVstore) visualizationMapper(data, info, intermKVstore, edges);

reduce 関数のファイルを表示します。リデューサーは、マッパーが保存したカウントを合計します。

function visualizationReducer(~, intermValList, outKVStore)
  if hasnext(intermValList)
    outVal = getnext(intermValList);
  else
    outVal = [];
  end
  while hasnext(intermValList)
    outVal = outVal + getnext(intermValList);
  end  
  add(outKVStore, 'Null', outVal);
end

mapreduce を使用して、map 関数および reduce 関数をデータストア ds に適用します。

result = mapreduce(ds, ourVisualizationMapper, @visualizationReducer);
********************************
*      MAPREDUCE PROGRESS      *
********************************
Map   0% Reduce   0%
Map  16% Reduce   0%
Map  32% Reduce   0%
Map  48% Reduce   0%
Map  65% Reduce   0%
Map  81% Reduce   0%
Map  97% Reduce   0%
Map 100% Reduce   0%
Map 100% Reduce 100%

mapreduce は、現在のフォルダー内のファイルで出力データストア result を返します。

結果の整理

出力データストアから、最終的なビンのカウント結果を読み取ります。

r = readall(result);
counts = r.Value{1};

結果の可視化

全範囲のデータを使用して (マッパーにより除外された少数の外れ値を除く)、加工されていないビンのカウントをプロットします。

bar(edges, counts, 'hist');
title('Distribution of Flight Delay')
xlabel('Arrival Delay (min)')
ylabel('Flight Counts')

ヒストグラムには長い裾があります。フライトの大多数の遅延時間の分布をよりわかりやすくするために、制限されたビン範囲を調べます。少しズームインすると、レポートの影響があることがわかります。遅延時間を 5 分刻みに丸めるのは一般的です。

xlim([-50,50]);
grid on
grid minor

移動平均フィルターを使用して、5 分刻みの記録の影響を削除し、カウントを平滑化します。

smoothCounts = filter( (1/5)*ones(1,5), 1, counts);
figure
bar(edges, smoothCounts, 'hist')
xlim([-50,50]);
title('Distribution of Flight Delay')
xlabel('Arrival Delay (min)')
ylabel('Flight Counts')
grid on
grid minor

グラフィックスのバランスをよくするために、最も遅延の大きかったフライトのトップ 1% は表示しません。データの全パス中に適切な情報を収集できていれば、データ セット全体を再処理しなくても多くの方法で可視化を調整できます。

empiricalCDF = cumsum(counts);
empiricalCDF = empiricalCDF / empiricalCDF(end);
quartile99 = find(empiricalCDF>0.99, 1, 'first');
low99 = 1:quartile99;

figure
empiricalPDF = smoothCounts(low99) / sum(smoothCounts);
bar(edges(low99), empiricalPDF, 'hist');

xlim([-60,edges(quartile99)]);
ylim([0, max(empiricalPDF)*1.05]);
title('Distribution of Flight Delay')
xlabel('Arrival Delay (min)')
ylabel('Probability Density')

参考

|

関連するトピック