今さら聞けない Hadoop 勉強会   第3回     MapReduce 実装編             セントラルソフト株式会社           システム1部 システム開発課                    奥山 洋平
本勉強会の目的2
本勉強会の目的       Hadoop に関連する技術や培ったノウハウを、勉強会に参加された        方と        共有する       スケジュール           第一回 Hadoop 基礎(1月19日開催)    ...
本日の目的   第1回で紹介したワードカウントを使って    MapReduce 実装の基礎を学び、第2回でジョブフ    ローを作成した k-means と TF-IDF アルゴリズムを    使って実装テクニックを学んでもらう      ...
目次   ワードカウント実装   k-means 実装   TF-IDF 実装   まとめ
注意   本勉強会では、現在 Cloudera 社が無料で配布している    CDH3(Cloudera Distribution including Apache Hadoop    v3)からインストールできる Hadoop のバージョン...
ワードカウント実装
ワードカウントとは   ある文書中の単語の数をカウントし、単語ごとにそ    の数を結果として出力する
ワードカウントの処理の流れ   Map       入力は key がバイトオフセット、value が1行の文章       出力は key が一つの単語、value が数字の1       処理は入力の value を単語に分割し、そ...
処理の流れ全体図 ローカルファイル ローカルファイル ローカルファイル            Shuffle & Sort 処理 ローカルファイル10
作成するプログラム   Mapper       Map 処理を行う   Reducer       Reduce 処理を行う   Driver       ジョブ(1回の MapReduce )の各種設定、ジョブの実       ...
デフォルトのプログラム   Hadoop にはデフォルトの設定があり、指定をしない    と    その設定を使用する   例       デフォルトの Mapper           入力の key と value をそのまま出力す...
Mapper(1)   まずは実際のコードを載せます
Mapper(2)   MapReduce のプログラムを Java で書く際、必要な    クラスは “org.apache.hadoop” の中からインポート    する
Mapper(3)   Mapper のクラスは MapReduceBase クラスを継承    し、Mapper のインターフェイスを実装する   Mapper インターフェイスのパラメータは入力の key    の型、入力の value...
データ型(1)   Map や Reduce などのそれぞれのフェーズでの入出    力の key は WritableComparable、value は Writable    である必要がある   Writable とはデータのシリア...
データ型(2)   WritableComparable の例(左が対応する一般的な    型)       Int      :IntComparable       Long     :LongComparable       Fl...
Mapper(4)
Mapper(5)   map メソッドの中に map 処理を記述する
map メソッド(1)   map メソッドの引数は入力の key、入力の value、    出力の OutputCollector、値を設定して Driver に渡す    Reporterの順になっている                ...
map メソッド(2)①   Text 型を String 型に変換し、半角スペースで区切ら    れた文を単語に分割しやすいように StringTokenizer    に入れる②   単語を全て取り出す③   set メソッドで Text ...
Reducer                         こちらには Iterator   記述方法は Mapper とほぼ一緒       は                           つかない               ...
reduce メソッド①   Iterator から値を取り出して集計②   set メソッドで IntWritable 型に変換③   OutputCollector で出力①②③
Driver(1)   import 類は省略します
Driver(2)   Driver のクラスは Configured クラスを継承し、Tool    の    インターフェイスを実装する   MapReduce を実行すると最初に Driver の main()            ...
ToolRunner   ToolRunner を使うことで、引数から Map や    Reduce を    実行するノード数の指定などできる
Driver(3)   import 類は省略します
run メソッド   run メソッドの中に以下のような処理を記述する       引数の数のチェック       設定のインスタンス生成       入出力のパスの設定       入力ファイルの読み込み形式       使用する...
引数の数のチェック   引数の数をチェックして、必要に応じて ToolRunner    のprintGenericCommandUsage メソッドを使って    メッセージを表示する
設定のインスタンス生成   ジョブの設定情報を管理する JobConf クラスの    インスタンスを生成する         自身のオブジェクトの設定の取得                実行する Driver のクラス名         ...
入出力のパスの設定   引数のどれが入力と出力に当たるのか記述する             引数の文字列からパスを生成し conf に                    セット
入力ファイルの読み込み形式   JobConf クラスの setInputFormat(class 名) メソッド    を使うと、引数の class 名に応じた形式でファイル    の読み込みをすることができる   例       Te...
使用する Map や Reduce の設定   JobConf クラスの setMapperClass(class 名) メソッ    ドでどの Map を使うのか設定できる(Reduce も同    様)
出力の型の設定   Map と Reduce(ジョブ) の出力の key と value の    型を    設定することができる
ジョブの実行   JobClient.runjob(設定情報を持つ JobConf のオブジェ    クト)を実行することで、ジョブが実行される
etc   その他 Map , Reduce を実行するノードの数や、タ    スクの失敗を何パーセントまで許容するかなどを    JobConf の    オブジェクトに持たせて実行できる
k-means 実装
注意 その2   以降は新しく出てきたプログラミング技法以外の説    明を細かくは行いません
k-means アルゴリズム概要    k-menas アルゴリズムは「クラスタの割り当て」と     「クラスタの重心を求める」という処理を繰り返     し、最適な重心を求めるアルゴリズム    39
ジョブフロージョブ1:初期化ジョブ2:割り当てたクラスタの重心を求めるジョブ3:各レコードを、各クラスタの重心に一番近いク  ラスタに   割り当て直す                  レコー                  ド集合    ...
入力ファイル(1)   今回はクラスタリングのサンプルデータとして有名    な    アヤメのデータを用いる       1行の内容(1レコード)           がく片,がく片幅,花びら,花びらの幅,アヤメの品種
入力ファイル(2)   今回は簡単にするために1行のフォーマットを以下    の    ように変更する       がく片 がく片幅 花びら 花びらの幅         半角スペース             5.1   3.5   1.4 ...
ジョブ1概要    処理        各レコードに対して、ランダムにクラスタを割り当てる    入力(クラスタリングするデータファイル)        key     : 入力ファイルの形式による        value   : ...
ジョブ1実装   ファイルの読み込み形式       TextInputFormat   Map 処理       key に乱数でクラスタ1~3の番号を割り振る   Reduce 処理       何もしない(デフォルト Redu...
ジョブ2概要    処理        割り当てられたクラスタの重心を求める    入力(ランダムにクラスタを割り当てられたレコー     ド)        key     : クラスタ番号        value   : 1レコ...
ジョブ2実装   ファイルの読み込み形式        KeyValueTextInputFormat   Map 処理        何もしない(デフォルト Mapper)   Reduce 処理    1.    同じ key に...
ジョブ3概要    処理        各レコードを、一番近いクラスタに割り当て直す    入力1(クラスタの重心)        key          : クラスタ番号        value   : クラスタの重心の位置 ...
ジョブ3検討    問題となりそうなところ        2つの形式のデータの入力はどうする?                入力形式は統一する                (TextInputFormat と KeyValueTextI...
ジョブ3概要修正    処理        各レコードを、一番近いクラスタに割り当て直す    入力1(クラスタの重心)        key          : クラスタ番号        value   : クラスタの重心の位置...
JobConf インスタンスへの値の持たせ方   Driver の中で JobConf インスタンスの set(文字    列 , 値)    メソッドを使うことで、 第一引数の文字列に、第二    引数の値を持たせることができる   持た...
Map や Reduce で JobConf を参照する   Map や Reduce で JobConf を参照するには    configure(JonConf インスタンス) メソッドを使う   configure メソッドは map...
JobConf に値を持たせるときの注意   Map や Reduce で値を書き換えたり、新たに持たせ    る    ことはできない   持たせる値が多くなる場合はメモリが足りなくなる    ので、ジョブを追加する
ジョブ3実装(1)   ファイルの読み込み形式       KeyValueTextInputFormat   Driver 処理       クラスタの中心のデータファイルを開いて3つのレコー        ドを取り出し、それぞれ J...
ジョブ3実装(2)   Reduce 処理       configure メソッド内でクラスタの中心のデータを取り出        す       reduce メソッド内で入力と3つのクラスタの中心データ        との     ...
残った問題(1)    ジョブ3の終了後、条件によって処理を終了するか、     ジョブ2の処理に戻るか分岐する問題        終了条件         1.   予め決めた回数クラスタの割り当てを行う         2.   クラス...
残った問題(2)   この処理を実装       割り当ての変化のチェックはどこで行う?            ジョブ3の reduce でのクラスタの割り当て直しで            key が変わったかどうかチェックすればいい   ...
Reporter   map や reduce メソッドでジョブに共通のカウンタ    を増減できる
Reporter 使い方(カウントアップ)   使うカウンタの名前を列挙型(enum)を定義する   map や reduce メソッドの中で Reporter クラスのイ    ンスタンスから getCounter(定義したカウンタ名) ...
Reporter 使い方(カウンタの参照)   ジョブ実行の runjob メソッドの返り値 RunningJob    クラスのインスタンスを変数に代入   そのインスタンスから getCounters メソッドでカウ    ンタの   ...
ジョブ3実装(2)に追加   Reduce 処理       configure メソッド内でクラスタの中心のデータを取り出        す       reduce メソッド内で入力と3つのクラスタの中心データ        との  ...
ジョブ3概要修正(2)    処理        各レコードを、一番近いクラスタに割り当て直す    入力1(クラスタの重心)        key          : クラスタ番号        value   : クラスタの重心...
ジョブ3実装(1)に追加   ファイルの読み込み形式       KeyValueTextInputFormat   Driver 処理       クラスタの中心のデータファイルを開いて3つのレコード        を取り出し、それぞ...
ループ処理   ループ処理を一つのジョブとし、そのジョブから    ジョブ2と3を繰り返し呼び出す            ループのジョブ             ループ処理           ジョブ   ジョブ            2  ...
ジョブの中から別のジョブを呼ぶメリット                                 一つのジョブで制御する場シェルに直接書く場合                       合hadoop jar kmeans.jar Jo...
紹介した技法(k-means)   JobConf 経由からのジョブ全体への値渡しの方法   Reporter のカウンタの使用方法   ジョブの中からジョブを呼び出す方法
TF-IDF 実装
TF-IDF アルゴリズム概要    文書中の単語に関する重み付けのアルゴリズム        その単語がその文書でどれくらい特徴的であるかを         単語ごと文書ごとに数値化(tfidf 値)            出てくる文書...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
入力ファイル(前回の資料より)    入力ファイルから文書名を取得する必要があるので、     今回の入力ファイルは説明を簡単にするため以下の     フォーマットを用いる                    入力ファイル         ...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ1概要    処理        文書名のリスト作成    入力(文書データ)        key     : 文書名@バイトオフセット        value   : 1行の文    出力(文書名のリスト)      ...
ジョブ1実装   ファイルの読み込み形式       KeyValueTextInputFormat   Map 処理       “@”より前(文書名)を key に、value に空文字列を入れ        る   Reduce...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ2概要    処理        文書名を数える    入力(文書名のリスト)        key     : 文書名        value   : 空文字列    出力(文書数)        key     : 文...
ジョブ2実装   ファイルの読み込み形式       TextInputFormat   Map 処理       key と value に数字の1を入れる(同じオブジェクトを        入れる)   Reduce 処理    ...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ3概要    処理        文書で出現した単語のリスト作成    入力(文書データ)        key     : 文書名@バイトオフセット        value   : 1行の文    出力(文書で出現した単語...
ジョブ3実装   ファイルの読み込み形式       KeyValueTextInputFormat   Map 処理       value を単語に切り分けて、英単語以外を除外し、アル        ファベットの大文字を小文字にする...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ4概要    処理        ジョブ3で作成した、文書で出現した単語のリストか         ら、単語の出現した文書数を求める    入力(文書で出現した単語のリスト)        key     : 文書名      ...
ジョブ4実装   ファイルの読み込み形式       KeyValueTextInputFormat   Map 処理       入力の key と value を入れ替える   Reduce 処理       Iterator ...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ5概要    処理        文書中の単語の出現回数を求める    入力(文書データ)        key     : 文書名@バイトオフセット        value   : 1行の文    出力(文書中の単語の出現...
ジョブ5実装   ファイルの読み込み形式       KeyValueTextInputFormat   Map 処理       value の文を単語に分割する       分割した単語@<key の “@”より前の文書名>を k...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ6概要    処理        ジョブ4(単語が出現した文書数)とジョブ5(文書中の単語         の出現回数)の結果を結合する    入力1(単語の出現した文書数)        key          : 単語   ...
ジョブ6実装(1)   ファイルの読み込み形式       KeyValueTextInputFormat   Map 処理       入力1の key の後ろに “@000” を付ける       入力2は何もしない   Shu...
Shuffle & Sort の書き換え   Shuffle & Sort を自分で作る場合、Partitioner(key    を    どの Reducer へ振り分けるのか決める)や    WritableComparable(どの順...
ジョブ6実装(2)   Reduce 処理       “@000”が key に含まれる場合はその value の値を、        “@000”が key に含まれない value の後ろに結合する
@000 の意味   Shuffle & Sort のソートの結果、同じ単語の key の    中で    先頭になるようにするために “@000” にする   これにより key に “@000” がついている value の値    ...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ7概要    処理        文書中の単語の総数を求める    入力(文書データ)        key     : 文書名@バイトオフセット        value   : 1行の文    出力(文書中の単語の総数) ...
ジョブ7実装   ファイルの読み込み形式       KeyValueTextInputFormat   Map 処理       key の@より前(文書名)を出力の key に、value の文を        単語に分割し、その数...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ8概要    処理        ジョブ6(単語の出現した文書数 + 文書中の単語の出現回数)と         ジョブ7(文書中の単語の総数)の結果を結合する    入力1(単語の出現した文書数 + 文書中の単語の出現回数)   ...
ジョブ8実装   ファイルの読み込み形式       KeyValueTextInputFormat   Map 処理       入力1は key の@の前後を入れ替える       入力2の key の後ろに “@000” を付け...
ジョブフロー        ジョブ     ジョブ               ジョブ          文書数を求める         1       2                 9       文書名の    文書名を数      ...
ジョブ9概要    処理        式に代入して tfidf 値を計算    入力1(文書数)        key          : 文書数        value   : 文書数    入力2(単語の出現した文書数 +...
ジョブ9実装   ファイルの読み込み形式       KeyValueTextInputFormat   Driver 処理       入力1のファイルを開いて、文書数の値を JobConf に持たせ        る   Map ...
ジョブ9補足   デフォルトの Mapper を使い、Reduce 処理で tfidf    値を計算しても良いが、Map 処理で計算しておく    と、Shuffle & Sort でソートされた結果がファイルに    書きだされる
紹介した技法(TF-IDF)   Partitioner の書き換えによる Reduce への値の割り    振り方の変更の方法   一つの key と value のペアに複数の情報を持たせる    方法   ソート順を意識した key...
まとめ
本日紹介した技法   JobConf 経由からのジョブ全体への値渡しの方法   Reporter のカウンタの使用方法   ジョブの中からジョブを呼び出す方法   Partitioner の書き換えによる Reduce への値の割り振り...
Upcoming SlideShare
Loading in …5
×

今さら聞けないHadoop勉強会第3回 セントラルソフト株式会社(20120327)

3,395 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,395
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
19
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

今さら聞けないHadoop勉強会第3回 セントラルソフト株式会社(20120327)

  1. 1. 今さら聞けない Hadoop 勉強会 第3回 MapReduce 実装編 セントラルソフト株式会社 システム1部 システム開発課 奥山 洋平
  2. 2. 本勉強会の目的2
  3. 3. 本勉強会の目的 Hadoop に関連する技術や培ったノウハウを、勉強会に参加された 方と 共有する スケジュール  第一回 Hadoop 基礎(1月19日開催)  HDFS と MapReduce の概念  ロールプレイ  第二回 アルゴリズム(2月28日開催)  k-means アルゴリズム  TF-IDF アルゴリズム  第三回 「MapReduce 実装テクニック」を予定(本日3月27日)  ワードカウント  k-means  TF-IDF  第四回 「理論・エコシステム編」を予定(4月予定)  HDFS  HBase  Hive 3
  4. 4. 本日の目的 第1回で紹介したワードカウントを使って MapReduce 実装の基礎を学び、第2回でジョブフ ローを作成した k-means と TF-IDF アルゴリズムを 使って実装テクニックを学んでもらう ジョブフロー MapReduce プログラム 4
  5. 5. 目次 ワードカウント実装 k-means 実装 TF-IDF 実装 まとめ
  6. 6. 注意 本勉強会では、現在 Cloudera 社が無料で配布している CDH3(Cloudera Distribution including Apache Hadoop v3)からインストールできる Hadoop のバージョン 0.20 を用いて説明を行います Hadoop Streaming という標準入出力のできるプログラ ミング言語なら MapReduce が動かせる方法があります が、 本勉強会では Java を使った解説を行います 本勉強会で紹介するプログラムはエラー処理を行って いません
  7. 7. ワードカウント実装
  8. 8. ワードカウントとは ある文書中の単語の数をカウントし、単語ごとにそ の数を結果として出力する
  9. 9. ワードカウントの処理の流れ Map  入力は key がバイトオフセット、value が1行の文章  出力は key が一つの単語、value が数字の1  処理は入力の value を単語に分割し、それぞれを key に し、value に1を入れて出力する Reduce  入力は key が単語、value が数字の1の集合  出力は key が単語、value がその単語が文書に現れた回 数  処理は入力の value の1を全て足して、出力の value に し、key はそのままで出力する
  10. 10. 処理の流れ全体図 ローカルファイル ローカルファイル ローカルファイル Shuffle & Sort 処理 ローカルファイル10
  11. 11. 作成するプログラム Mapper  Map 処理を行う Reducer  Reduce 処理を行う Driver  ジョブ(1回の MapReduce )の各種設定、ジョブの実 行を行う Shuffle & Sort はデフォルトのものを使うのでプログラムは作成 しない
  12. 12. デフォルトのプログラム Hadoop にはデフォルトの設定があり、指定をしない と その設定を使用する 例  デフォルトの Mapper  入力の key と value をそのまま出力する  デフォルトの Reducer  入力の value (複数の値)から一つずつ入力の key と一緒に出 力する  デフォルトの Shuffle & Sort  key の値そのままで昇順にソート、ハッシュを使って Reduce へ の割り振りを決める  その他ファイルの読み込み形式など
  13. 13. Mapper(1) まずは実際のコードを載せます
  14. 14. Mapper(2) MapReduce のプログラムを Java で書く際、必要な クラスは “org.apache.hadoop” の中からインポート する
  15. 15. Mapper(3) Mapper のクラスは MapReduceBase クラスを継承 し、Mapper のインターフェイスを実装する Mapper インターフェイスのパラメータは入力の key の型、入力の value の型、出力の key の型、出力の value の型の順になっている public class WCMap extends MapReduceBase implements Mapper<Object, Text, Text, IntWritable> {
  16. 16. データ型(1) Map や Reduce などのそれぞれのフェーズでの入出 力の key は WritableComparable、value は Writable である必要がある Writable とはデータのシリアライズを高速で行う データ型のインターフェイス WritableComparable は Writable のデータに順番を 付けられるようにしたデータ型のインターフェイス (Shuffle & Sort のソート順はここで定義される)
  17. 17. データ型(2) WritableComparable の例(左が対応する一般的な 型)  Int :IntComparable  Long :LongComparable  Float :FloatComparable  Double :DoubleComparable  String :Text  など
  18. 18. Mapper(4)
  19. 19. Mapper(5) map メソッドの中に map 処理を記述する
  20. 20. map メソッド(1) map メソッドの引数は入力の key、入力の value、 出力の OutputCollector、値を設定して Driver に渡す Reporterの順になっている 出力の 出力の public void map(Object key, key の型 value の型 Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException
  21. 21. map メソッド(2)① Text 型を String 型に変換し、半角スペースで区切ら れた文を単語に分割しやすいように StringTokenizer に入れる② 単語を全て取り出す③ set メソッドで Text 型に変換する④ key の word と value の ONE(定数1)を collect メ ソッドで出力する ① ② ③ ④
  22. 22. Reducer こちらには Iterator 記述方法は Mapper とほぼ一緒 は つかない Shuffle & Sort でまとめ た value は Iterator に 入っている
  23. 23. reduce メソッド① Iterator から値を取り出して集計② set メソッドで IntWritable 型に変換③ OutputCollector で出力①②③
  24. 24. Driver(1) import 類は省略します
  25. 25. Driver(2) Driver のクラスは Configured クラスを継承し、Tool の インターフェイスを実装する MapReduce を実行すると最初に Driver の main() ToolDriver の中で実装するメソッ インターフェイスの 実行したいクラスのインスタ メソッドが呼び出される run メソッドを実行するためのクラスド ンス 引数 public static void main(String[] args) throws Exception { int exitCode = ToolRunner.run(new WordCount(), args); System.exit(exitCode); }
  26. 26. ToolRunner ToolRunner を使うことで、引数から Map や Reduce を 実行するノード数の指定などできる
  27. 27. Driver(3) import 類は省略します
  28. 28. run メソッド run メソッドの中に以下のような処理を記述する  引数の数のチェック  設定のインスタンス生成  入出力のパスの設定  入力ファイルの読み込み形式  使用する Map や Reduce の設定  出力の型の設定  ジョブの実行  etc
  29. 29. 引数の数のチェック 引数の数をチェックして、必要に応じて ToolRunner のprintGenericCommandUsage メソッドを使って メッセージを表示する
  30. 30. 設定のインスタンス生成 ジョブの設定情報を管理する JobConf クラスの インスタンスを生成する 自身のオブジェクトの設定の取得 実行する Driver のクラス名 ジョブの名前の設定
  31. 31. 入出力のパスの設定 引数のどれが入力と出力に当たるのか記述する 引数の文字列からパスを生成し conf に セット
  32. 32. 入力ファイルの読み込み形式 JobConf クラスの setInputFormat(class 名) メソッド を使うと、引数の class 名に応じた形式でファイル の読み込みをすることができる 例  TextInputFormat.class  key をバイトオフセット、value を1行のテキストとして読み 込む  デフォルトの形式(指定しないとこの形式になる)  KeyValueTextInputFormat.class  1行を「key セパレータ value」とみなして読み込む  デフォルトのセパレータは「タブ」
  33. 33. 使用する Map や Reduce の設定 JobConf クラスの setMapperClass(class 名) メソッ ドでどの Map を使うのか設定できる(Reduce も同 様)
  34. 34. 出力の型の設定 Map と Reduce(ジョブ) の出力の key と value の 型を 設定することができる
  35. 35. ジョブの実行 JobClient.runjob(設定情報を持つ JobConf のオブジェ クト)を実行することで、ジョブが実行される
  36. 36. etc その他 Map , Reduce を実行するノードの数や、タ スクの失敗を何パーセントまで許容するかなどを JobConf の オブジェクトに持たせて実行できる
  37. 37. k-means 実装
  38. 38. 注意 その2 以降は新しく出てきたプログラミング技法以外の説 明を細かくは行いません
  39. 39. k-means アルゴリズム概要 k-menas アルゴリズムは「クラスタの割り当て」と 「クラスタの重心を求める」という処理を繰り返 し、最適な重心を求めるアルゴリズム 39
  40. 40. ジョブフロージョブ1:初期化ジョブ2:割り当てたクラスタの重心を求めるジョブ3:各レコードを、各クラスタの重心に一番近いク ラスタに 割り当て直す レコー ド集合 :入力 :出力 ジョブ ジョブ ジョブ 終了開始 1 2 3 :フロー :終了時入力 出力 処理3の ジョブ ジョブ ジョブ 結果がファイ ファイ 1結果 2結果 3結果 ル ル 最終出力40
  41. 41. 入力ファイル(1) 今回はクラスタリングのサンプルデータとして有名 な アヤメのデータを用いる  1行の内容(1レコード)  がく片,がく片幅,花びら,花びらの幅,アヤメの品種
  42. 42. 入力ファイル(2) 今回は簡単にするために1行のフォーマットを以下 の ように変更する  がく片 がく片幅 花びら 花びらの幅 半角スペース 5.1 3.5 1.4 0.2 4.9 3.0 1.4 0.2 4.7 3.2 1.3 0.2 4.6 3.1 1.5 0.2 5.0 3.6 1.4 0.2 5.4 3.9 1.7 0.4 …
  43. 43. ジョブ1概要 処理  各レコードに対して、ランダムにクラスタを割り当てる 入力(クラスタリングするデータファイル)  key : 入力ファイルの形式による  value : 1レコード 出力(ランダムにクラスタを割り当てられたレコー ド)  key : 割り当てられたクラスタ番号  value : 1レコード 43
  44. 44. ジョブ1実装 ファイルの読み込み形式  TextInputFormat Map 処理  key に乱数でクラスタ1~3の番号を割り振る Reduce 処理  何もしない(デフォルト Reducer)
  45. 45. ジョブ2概要 処理  割り当てられたクラスタの重心を求める 入力(ランダムにクラスタを割り当てられたレコー ド)  key : クラスタ番号  value : 1レコード 出力(クラスタの重心)  key : クラスタ番号  value : クラスタの重心の位置 45
  46. 46. ジョブ2実装 ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  何もしない(デフォルト Mapper) Reduce 処理 1. 同じ key に対してレコードのそれぞれの要素の平均を計 算 2. 計算結果を連結(半角スペースで区切る) 3. “center”という文字列をクラスタ番号の前につけ、key にする
  47. 47. ジョブ3概要 処理  各レコードを、一番近いクラスタに割り当て直す 入力1(クラスタの重心)  key : クラスタ番号  value : クラスタの重心の位置 入力2(クラスタリングするデータファイル)  key : <要検討>  value : 1レコード 出力(クラスタを割り当て直したレコード)  key : 割り当てたクラスタ  value : 1レコード 47
  48. 48. ジョブ3検討 問題となりそうなところ  2つの形式のデータの入力はどうする? 入力形式は統一する (TextInputFormat と KeyValueTextInputFormat は混ぜて使えない)  クラスタの重心のデータはすべての Reduce を行うノー ドに 配布する必要があるがどうする?  すべてに配布しないと各レコードがどのクラスタに近いのか 比較できない JobConf のインスタンスに値を持たせることができる 48
  49. 49. ジョブ3概要修正 処理  各レコードを、一番近いクラスタに割り当て直す 入力1(クラスタの重心)  key : クラスタ番号  value : クラスタの重心の位置 入力2(クラスタリングするデータファイル)  key : クラスタ番号  value : 1レコード 出力(クラスタを割り当て直したレコード)  key : 割り当てたクラスタ  value : 1レコード 49
  50. 50. JobConf インスタンスへの値の持たせ方 Driver の中で JobConf インスタンスの set(文字 列 , 値) メソッドを使うことで、 第一引数の文字列に、第二 引数の値を持たせることができる 持たせた値は Map や Reduce の中で、get(文字列) メソッドを使うことで持たせた値を取り出すことが できる
  51. 51. Map や Reduce で JobConf を参照する Map や Reduce で JobConf を参照するには configure(JonConf インスタンス) メソッドを使う configure メソッドは map や reduce メソッドが呼び 出される前に呼ばれるメソッド
  52. 52. JobConf に値を持たせるときの注意 Map や Reduce で値を書き換えたり、新たに持たせ る ことはできない 持たせる値が多くなる場合はメモリが足りなくなる ので、ジョブを追加する
  53. 53. ジョブ3実装(1) ファイルの読み込み形式  KeyValueTextInputFormat Driver 処理  クラスタの中心のデータファイルを開いて3つのレコー ドを取り出し、それぞれ JobConf に持たせる Map 処理  何もしない(デフォルト Mapper)
  54. 54. ジョブ3実装(2) Reduce 処理  configure メソッド内でクラスタの中心のデータを取り出 す  reduce メソッド内で入力と3つのクラスタの中心データ との 距離をそれぞれ計算し、距離が最小のクラスタに key を 変える
  55. 55. 残った問題(1) ジョブ3の終了後、条件によって処理を終了するか、 ジョブ2の処理に戻るか分岐する問題  終了条件 1. 予め決めた回数クラスタの割り当てを行う 2. クラスタを割り当て直した時に割り当ての変化が無い ループ処理 ジョブ ジョブ 2 3 55
  56. 56. 残った問題(2) この処理を実装  割り当ての変化のチェックはどこで行う? ジョブ3の reduce でのクラスタの割り当て直しで key が変わったかどうかチェックすればいい reduce から Driver へ情報を渡すには? (JobConf へ値は持たせられない) Reporter を使う ループ処理 ジョブ ジョブ 2 3
  57. 57. Reporter map や reduce メソッドでジョブに共通のカウンタ を増減できる
  58. 58. Reporter 使い方(カウントアップ) 使うカウンタの名前を列挙型(enum)を定義する map や reduce メソッドの中で Reporter クラスのイ ンスタンスから getCounter(定義したカウンタ名) で カウンタを取り出す カウンタを incriment(数値) で値を増減させる
  59. 59. Reporter 使い方(カウンタの参照) ジョブ実行の runjob メソッドの返り値 RunningJob クラスのインスタンスを変数に代入 そのインスタンスから getCounters メソッドでカウ ンタの リストを取り出す カウンタのリストから定義したカウンタの値を getCounter メソッドで取り出す
  60. 60. ジョブ3実装(2)に追加 Reduce 処理  configure メソッド内でクラスタの中心のデータを取り出 す  reduce メソッド内で入力と3つのクラスタの中心データ との 距離をそれぞれ計算し、距離が最小のクラスタに key を 変える  key が変わった場合にカウンタを1増やす
  61. 61. ジョブ3概要修正(2) 処理  各レコードを、一番近いクラスタに割り当て直す 入力1(クラスタの重心)  key : クラスタ番号  value : クラスタの重心の位置 入力2(現在のクラスタの情報)  key : クラスタ番号  value : 1レコード 出力(クラスタを割り当て直したレコード)  key : 割り当てたクラスタ  value : 1レコード 61
  62. 62. ジョブ3実装(1)に追加 ファイルの読み込み形式  KeyValueTextInputFormat Driver 処理  クラスタの中心のデータファイルを開いて3つのレコード を取り出し、それぞれ JobConf に持たせる  ジョブを実行した後、カウンタを取り出し、カウンタの値 が0(クラスタの割り当てに変化が無い)なら処理続行の フラグを変える Map 処理  何もしない(デフォルト Mapper)
  63. 63. ループ処理 ループ処理を一つのジョブとし、そのジョブから ジョブ2と3を繰り返し呼び出す ループのジョブ ループ処理 ジョブ ジョブ 2 3
  64. 64. ジョブの中から別のジョブを呼ぶメリット 一つのジョブで制御する場シェルに直接書く場合 合hadoop jar kmeans.jar Job2 in1 hadoop jar kmeans.jarout1 IterateJobhadoop jar kmeans.jar Job3 in2 …out2 jar ファイルを処理ノードへ コピーする回数を削減でき る64
  65. 65. 紹介した技法(k-means) JobConf 経由からのジョブ全体への値渡しの方法 Reporter のカウンタの使用方法 ジョブの中からジョブを呼び出す方法
  66. 66. TF-IDF 実装
  67. 67. TF-IDF アルゴリズム概要 文書中の単語に関する重み付けのアルゴリズム  その単語がその文書でどれくらい特徴的であるかを 単語ごと文書ごとに数値化(tfidf 値)  出てくる文書が少なく、特定の文書での出現回数が多い単語ほ ど その文書での数値が大きい  キーワード抽出や Web 検索へ応用できる 例:ある文書中の tfidf 値 “犬” : 0.3 文書 “花” : 0.6 “アヤメ” : 0.5 67 …
  68. 68. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 68
  69. 69. 入力ファイル(前回の資料より) 入力ファイルから文書名を取得する必要があるので、 今回の入力ファイルは説明を簡単にするため以下の フォーマットを用いる 入力ファイル 文書名1@バイトオフセット 文章 文書名1@バイトオフセット 文章 文書名1@バイトオフセット 文章 文書名1@バイトオフセット 文章 文書名2@バイトオフセット 文章 文書名2@バイトオフセット 文章 文書名2@バイトオフセット 文章 … 69
  70. 70. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 70
  71. 71. ジョブ1概要 処理  文書名のリスト作成 入力(文書データ)  key : 文書名@バイトオフセット  value : 1行の文 出力(文書名のリスト)  key : 文書名  value : 空文字列 71
  72. 72. ジョブ1実装 ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  “@”より前(文書名)を key に、value に空文字列を入れ る Reduce 処理  key をそのまま、value に空文字列を入れる
  73. 73. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 73
  74. 74. ジョブ2概要 処理  文書名を数える 入力(文書名のリスト)  key : 文書名  value : 空文字列 出力(文書数)  key : 文書数  value : 文書数 74
  75. 75. ジョブ2実装 ファイルの読み込み形式  TextInputFormat Map 処理  key と value に数字の1を入れる(同じオブジェクトを 入れる) Reduce 処理  1の数を数えて、同じ数を key と value に入れる
  76. 76. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 76
  77. 77. ジョブ3概要 処理  文書で出現した単語のリスト作成 入力(文書データ)  key : 文書名@バイトオフセット  value : 1行の文 出力(文書で出現した単語のリスト)  key : 文書名  value : 単語 77
  78. 78. ジョブ3実装 ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  value を単語に切り分けて、英単語以外を除外し、アル ファベットの大文字を小文字にする(①)  key の“@”より後ろを①の単語に置き換え、出力の key に、value を空文字列にする Reduce 処理  “@”より前(文書名)を key に、後ろ(単語)を value にする
  79. 79. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 79
  80. 80. ジョブ4概要 処理  ジョブ3で作成した、文書で出現した単語のリストか ら、単語の出現した文書数を求める 入力(文書で出現した単語のリスト)  key : 文書名  value : 単語 出力(単語の出現した文書数)  key : 単語  value : 出現した文書数 80
  81. 81. ジョブ4実装 ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  入力の key と value を入れ替える Reduce 処理  Iterator から取り出した文書名の数を数える
  82. 82. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 82
  83. 83. ジョブ5概要 処理  文書中の単語の出現回数を求める 入力(文書データ)  key : 文書名@バイトオフセット  value : 1行の文 出力(文書中の単語の出現回数)  key : 単語@文書名  value : key の文書中の単語の出現回数 83
  84. 84. ジョブ5実装 ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  value の文を単語に分割する  分割した単語@<key の “@”より前の文書名>を key に し、 数字の1を value にする Reduce 処理  value の1の数を数える
  85. 85. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 85
  86. 86. ジョブ6概要 処理  ジョブ4(単語が出現した文書数)とジョブ5(文書中の単語 の出現回数)の結果を結合する 入力1(単語の出現した文書数)  key : 単語  value : 出現した文書数 入力2(文書中の単語の出現回数)  key : 単語@文書名  value : key の文書中の単語の出現回数 出力(単語の出現した文書数 + 文書中の単語の出現回 数)  key : 単語@文書名  value : key の文書中の単語の出現回数@出現した文書数 86
  87. 87. ジョブ6実装(1) ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  入力1の key の後ろに “@000” を付ける  入力2は何もしない Shuffle & Sort 処理  key の中の“単語”にハッシュを用いて、Reducer への分配 を行う(集約はしない)  ソートは key 全体で行う
  88. 88. Shuffle & Sort の書き換え Shuffle & Sort を自分で作る場合、Partitioner(key を どの Reducer へ振り分けるのか決める)や WritableComparable(どの順番でソートするか決め る)を作成し、そのクラスを Driver で設定する 今回作る自作 Partitioner は HashPartitioner クラス を 継承し、Partitioner インターフェイスを実装する Driver での設定は setPartitionerClass メソッドを 使って設定する
  89. 89. ジョブ6実装(2) Reduce 処理  “@000”が key に含まれる場合はその value の値を、 “@000”が key に含まれない value の後ろに結合する
  90. 90. @000 の意味 Shuffle & Sort のソートの結果、同じ単語の key の 中で 先頭になるようにするために “@000” にする これにより key に “@000” がついている value の値 を 変数に入れて、以降に入力としてやってくる value の後ろに値をすぐ結合できる
  91. 91. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 91
  92. 92. ジョブ7概要 処理  文書中の単語の総数を求める 入力(文書データ)  key : 文書名@バイトオフセット  value : 1行の文 出力(文書中の単語の総数)  key : 文書名  value : 文書中の単語の総数 92
  93. 93. ジョブ7実装 ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  key の@より前(文書名)を出力の key に、value の文を 単語に分割し、その数を数えて出力の value にする(予 め集計しておくことで Reduce の入力の Iterator に入る 数値の個数を減らす) Reduce 処理  value の数値の合計を計算する
  94. 94. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 94
  95. 95. ジョブ8概要 処理  ジョブ6(単語の出現した文書数 + 文書中の単語の出現回数)と ジョブ7(文書中の単語の総数)の結果を結合する 入力1(単語の出現した文書数 + 文書中の単語の出現回数)  key : 単語@文書名  value : key の文書中の単語の出現回数@出現した文書数 入力2(文書中の単語の総数)  key : 文書名  value : 文書中の単語の総数 出力(単語の出現した文書数 + 文書中の単語の出現回数 +文書中の単語の総数)  key : 単語@文書名  value : key の文書中の単語の出現回数@出現した文書数 @文書中の単語の総数 95
  96. 96. ジョブ8実装 ファイルの読み込み形式  KeyValueTextInputFormat Map 処理  入力1は key の@の前後を入れ替える  入力2の key の後ろに “@000” を付ける Shuffle & Sort 処理  ジョブ6と同じ処理をする Reduce 処理  key は@の前後を入れ替える  “@000”が key に含まれる場合はその value の値を、“@000”が key に含まれない value の後ろに結合し、それを出力の value にする
  97. 97. ジョブフロー ジョブ ジョブ ジョブ 文書数を求める 1 2 9 文書名の 文書名を数 式に代入 リスト作成 える して計算 単語が出現した文書数を求める ジョブ 入力 ジョブ 出力 4 ジョブ ジョブ 3 文書で出現し リストから ファイルファイ 6 8 ル た 単語が出現した 値をまとめ 値をまとめ (tfidf 単語のリスト 文書数を求める る1 る2 値) ジョブ 5 文書中の単語の 出現回数を求める ジョブ 7 文書中の単語の 総数を求める 97
  98. 98. ジョブ9概要 処理  式に代入して tfidf 値を計算 入力1(文書数)  key : 文書数  value : 文書数 入力2(単語の出現した文書数 + 文書中の単語の出現回数 +文書中の単語の総数)  key : 単語@文書名  value : key の文書中の単語の出現回数@出現した文書数 @文書中の単語の総数 出力(tfidf 値)  key : 単語@文書名  value : tfidf 値 98
  99. 99. ジョブ9実装 ファイルの読み込み形式  KeyValueTextInputFormat Driver 処理  入力1のファイルを開いて、文書数の値を JobConf に持たせ る Map 処理  configure メソッド内で JobConf から文書数を取り出す  map メソッド内で tfidf を求める式に値を代入して、その値を value に、key はそのまま Reduce 処理  何もしない(デフォルト Reducer)
  100. 100. ジョブ9補足 デフォルトの Mapper を使い、Reduce 処理で tfidf 値を計算しても良いが、Map 処理で計算しておく と、Shuffle & Sort でソートされた結果がファイルに 書きだされる
  101. 101. 紹介した技法(TF-IDF) Partitioner の書き換えによる Reduce への値の割り 振り方の変更の方法 一つの key と value のペアに複数の情報を持たせる 方法 ソート順を意識した key の設定方法
  102. 102. まとめ
  103. 103. 本日紹介した技法 JobConf 経由からのジョブ全体への値渡しの方法 Reporter のカウンタの使用方法 ジョブの中からジョブを呼び出す方法 Partitioner の書き換えによる Reduce への値の割り振り 方の変更の方法 一つの key と value のペアに複数の情報を持たせる方法 ソート順を意識した key の設定方法

×