Main Content

MapReduce を使用するグループごとの平均の計算

この例では、mapreduce を使用してデータ セット内のグループごとの平均を計算する方法を示します。データのサブグループに対する計算の実行方法を示しています。

データの準備

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

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

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

preview(ds)
ans=8×2 table
    ArrDelay    DayOfWeek
    ________    _________

        8           3    
        8           1    
       21           5    
       13           5    
        4           4    
       59           3    
        3           4    
       11           6    

mapreduce の実行

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

次の例で、マッパーはデータの各ブロックで遅延時間のカウントと合計を曜日ごとに計算し、次に、結果を中間的なキーと値のペアとして保存します。キーは曜日を表す整数 (1 から 7) で、値は各曜日の遅延時間のカウントと合計を表す 2 要素のベクトルです。

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

function meanArrivalDelayByDayMapper(data, ~, intermKVStore)
  % Data is an n-by-2 table: first column is the DayOfWeek and the second
  % is the ArrDelay. Remove missing values first.
  delays = data.ArrDelay;
  day = data.DayOfWeek;
  notNaN = ~isnan(delays);
  day = day(notNaN);
  delays = delays(notNaN);

  % find the unique days in this chunk
  [intermKeys,~,idx] = unique(day, 'stable');

  % group delays by idx and apply @grpstatsfun function to each group
  intermVals = accumarray(idx,delays,size(intermKeys),@countsum);
  addmulti(intermKVStore,intermKeys,intermVals);

  function out = countsum(x)
    n = length(x); % count
    s = sum(x); % mean
    out = {[n, s]};
  end
end

Map フェーズの後、mapreduce は中間のキーと値のペアを一意なキー (この場合、曜日) ごとにグループ化します。したがって、リデューサーへの各呼び出しは、ある曜日に関連付けられた値を処理します。リデューサーは、入力キー (intermKey) で指定された曜日の遅延時間の中間的なカウントと合計のリストを受け取り、総カウント n と総合計 s に値を合計します。次に、リデューサーは全体的な平均を計算し、最終的なキーと値のペアを 1 つ出力に追加します。このキーと値のペアは、ある曜日のフライト到着遅延時間の平均を表します。

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

function meanArrivalDelayByDayReducer(intermKey, intermValIter, outKVStore)
  n = 0;
  s = 0;

  % get all sets of intermediate results
  while hasnext(intermValIter)
    intermValue = getnext(intermValIter);
    n = n + intermValue(1);
    s = s + intermValue(2);
  end

  % accumulate the sum and count
  mean = s/n;
  % add results to the output datastore
  add(outKVStore,intermKey,mean);
end

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

meanDelayByDay = mapreduce(ds, @meanArrivalDelayByDayMapper, ...
                               @meanArrivalDelayByDayReducer);
********************************
*      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  14%
Map 100% Reduce  29%
Map 100% Reduce  43%
Map 100% Reduce  57%
Map 100% Reduce  71%
Map 100% Reduce  86%
Map 100% Reduce 100%

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

出力データストア meanDelayByDay から最終結果を読み取ります。

result = readall(meanDelayByDay)
result=7×2 table
    Key      Value   
    ___    __________

     3     {[7.0038]}
     1     {[7.0833]}
     5     {[9.4193]}
     4     {[9.3185]}
     6     {[4.2095]}
     2     {[5.8569]}
     7     {[6.5241]}

結果の整理

整数のキー (1 から 7) は曜日を表します。結果をさらに整理するには、キーを categorical 配列に変換し、単独のセル要素から数値を取得して結果のテーブルの変数の名前を変更します。

result.Key = categorical(result.Key, 1:7, ...
               {'Mon','Tue','Wed','Thu','Fri','Sat','Sun'});
result.Value = cell2mat(result.Value);
result.Properties.VariableNames = {'DayOfWeek', 'MeanArrDelay'}
result=7×2 table
    DayOfWeek    MeanArrDelay
    _________    ____________

       Wed          7.0038   
       Mon          7.0833   
       Fri          9.4193   
       Thu          9.3185   
       Sat          4.2095   
       Tue          5.8569   
       Sun          6.5241   

テーブルの行を、平均フライト到着遅延時間で並べ替えます。これにより、旅行をするなら土曜日が最良で、金曜日が最悪なことがわかります。

result = sortrows(result,'MeanArrDelay')
result=7×2 table
    DayOfWeek    MeanArrDelay
    _________    ____________

       Sat          4.2095   
       Tue          5.8569   
       Sun          6.5241   
       Wed          7.0038   
       Mon          7.0833   
       Thu          9.3185   
       Fri          9.4193   

参考

|

関連するトピック