Contenu connexe
Similaire à Hadoop / MapReduce とは
Similaire à Hadoop / MapReduce とは (20)
Hadoop / MapReduce とは
- 3. MapReduce
● Mapper で与えられたデータを "キー,値" に変換する
● Reducer に "キー,値のリスト(値, 値, ...)" が渡される。
Reducer は "キー,値" に集約する
● このロジックで分散できるっていう話
● Hadoop Streaming というツールで、好みの言語で
MapReduce できる。
WordCount サンプルがやってることは
● Mapper で与えられたアクセスログ行から "単語, 1" の行を書き出す。
● Reducer で "単語,(1,1,1,...)" から "単語,単語数" に集計して書き出す
- 5. UserID, ItemID
--------------------------
1, 10001
1, 10002
3, 10001
1, 10003
2, 10002
1, 10005
2, 10004
3, 10005
3, 10002
--------------------------
以下のような購入履歴テキストデータから --- 区切りの単位で Mapper に
分散されるとする。
--------------------------
サーバA
1, 10001
1, 10002
3, 10001
--------------------------
サーバB
1, 10003
2, 10002
1, 10005
--------------------------
サーバC
2, 10004
3, 10005
3, 10002
--------------------------
- 7. #!/usr/bin/env ruby
results = {}
while line = STDIN.gets
vals = line.strip.split(",")
results[vals[0]] = [] unless results.key?(vals[0])
results[vals[0]] << vals[1]
end
results.each do |key, value|
str = value.join(":")
print "#{key}t#{str}n"
end
Mapper
- 8. #!/usr/bin/env ruby
lastkey = ""
items = []
while line = STDIN.gets
vals = line.strip.split("t")
if lastkey != "" && vals[0] != lastkey
value = items.join(":")
print "#{lastkey}t#{value}n"
items = []
end
vals[1].split(":").each do |item|
items << item unless items.include?(item)
end
lastkey = vals[0]
end
if lastkey != ""
value = items.join(":")
print "#{lastkey}t#{value}n"
end
Reducer
- 9. --------------------------
サーバA
10001:10002, 1
10001:10003, 1
10001:10005, 1
10002:10001, 1
10002:10003, 1
10002:10005, 1
10003:10001, 1
10003:10002, 1
10003:10005, 1
10005:10001, 1
10005:10002, 1
10005:10003, 1
--------------------------
サーバB
10002:10004,1
10004:10002,1
--------------------------
サーバC
10001:10002, 1
10001:10005, 1
10002:10001, 1
10002:10005, 1
10005:10001, 1
10005:10002, 1
--------------------------
Mapper Reducer
関連する2アイテムIDをキーとして同時購入をカウント
10001:10002, 2
10001:10003, 1
10001:10005, 2
10002:10001, 2
10002:10003, 1
10002:10004, 1
10002:10005, 2
10003:10001, 1
10003:10002, 1
10003:10004, 1
10003:10005, 1
10004:10002, 1
10005:10001, 2
10005:10002, 2
10005:10003, 1
key = (アイテムID):(関連アイテムID)
value = 関連アイテム購入数
要するに
GROUP BY
(アイテムID):(関連アイテムID)
- 10. あとは抽出データをSQLデータベースなどに入れて活用する。関連アイテムの同
時購入数の多いものを類似アイテムとする。
-- "10001:10002, 2"
INSERT INTO recommend_items
(target_item, similar_item, similarity)
VALUES
("10001", "10002", 2);
--"10001:10003, 1"
INSERT INTO recommend_items
(target_item, similar_item, similarity)
VALUES
("10001", "10003", 1);
....
SELECT similar_item FROM recommed_items
WHERE target_item = "10001"
ORDER BY similarity DESC
LIMIT 10;
- 11. --------------------------
サーバA
10001,10002-2
10001,10003-1
10001,10005-2
10002,10001-2
10002,10003-1
--------------------------
サーバB
10002,10004-1
10002,10005-2
10003,10001-1
10003,10002-1
10003,10004-1
--------------------------
サーバC
10003,10005-1
10004,10002-1
10005,10001-2
10005,10002-2
10005,10003-1
--------------------------
Mapper
Reducer
アイテムIDをキーでグループ化し、Reducer で条件に合わな
い関連アイテムIDを除外することもできる。2未満は含めない
場合の例
10001,10002-2:10005-2:10001-2
10002,10001-2:10005-2
10005:10001-2
key = アイテムID
value = (関連アイテムID)-(同時購入数):....
要するに
GROUP BY (アイテムID)
HAVING (同時購入数) > 1
Hadoop の稼働コストのほうがかかるので、集計が終わったら Hadoop 外でやるほうがよい。次の Job
に引き継ぐためのデータであったり、不要なゴミデータばかりでデータ量が大きすぎる場合には有効。