分散処理プラットフォーム hadoop による wikipedia データの 解析 森 竜也...
Post on 19-Dec-2015
231 views
TRANSCRIPT
分散処理プラットフォーム Hadoopによる Wikipedia データの解析
森 竜也(東京電機大学)
2010.11.7
1
概要• Wikipedia で配布されているデータファイル
• 日本語版で 6.5GB ほどの巨大な XML ファイル 1個に全ページ内容が記述されている
• 公式には SQL ダンプに変換して使用する
• オープンソースの分散処理プラットフォームHadoop による処理方法を紹介
2
何ができるか?• 例えば– ページ名やページの種別を出力する– 記事中に挙げられている参考文献を集める– テレビ番組の記事を抽出する
などプログラミング次第で色々できるしかし得手不得手はある
3
見出し• Wikipedia の配布データ• Hadoop とは• Hadoop プログラム入門• Wikipedia データへの応用• 実例• Medawiki との比較• ダウンロード
4
Wikipedia の配布データ
5
ダウンロードサイト• http://download.wikimedia.org/jawiki/latest/
6
jawiki-latest-interwiki.sql.gz
jawiki-latest-pages-meta-current.xml.bz2
jawiki-latest-pages-meta-current.xml
• 全ページ内容が記述されている XML ファイル
• 6.5GB• page 要素が Wikipedia1 ページ分の情報
7
<mediawiki> <siteinfo> ヘッダー情報 </siteinfo> <page> ページ内容 1</page> <page> ページ内容 2</page> <page> ページ内容 3</page> ・ ・ ・ <page> ページ内容 n</page></mediawiki>
ページ要素1,880,711 個
page 要素
8
<page> <title>Hadoop</title> <id>1805248</id> <revision> <id>34222653</id> <timestamp>2010-09-28T14:57:34Z</timestamp> <contributor> <username>Tire works</username> <id>456732</id> </contributor> <minor/> <comment> バージョンを更新。 </comment> <text xml:space="preserve"> 記事本文…… </text> </revidion></page>
title 要素ページタイトル
id 要素ページ ID
text 要素記事本文
Wiki 形式の生データ
公式で紹介されている使い方1. MediaWiki のインポート機能で取り込む2. 変換ツールを使用して SQL ダンプに変換– xml2sql, mwdumper
• Hadoop を利用した手法– 簡単なプログラミングで分散処理が可能
9
Hadoop とは
10
Hadoop とは• Apache で開発されている分散コンピュー
ティングプラットフォーム• Google の GFS(Google File System) と
MapReduce の Java によるクローン• もちろんオープンソース• 分散処理、分散ファイルシステムなど– Hadoop を活用するためのサブプロジェクト有
11Hadoop マスコット
特徴• スケーラビリティ
• Hadoop で使用するのは普通、一般的な性能のマシン• 5 台分の処理能力が必要なら 5 台• 100 台分の処理能力が必要なら 100 台• というように必要に応じた規模のクラスタを構成できる
• Yahoo! や facebook 、楽天などでも利用– 数千台のマシン、数 TB のデータ– Wikipedia の数 GB のデータは Hadoop の利用例からすれば小さ
いほう
12
Hadoop プログラム入門
13
MapReduce
• Hadoop で使用する分散処理のアルゴリズム
• map 処理と reduce 処理の 2 段階で key とvalue のデータ組を出力、集約する
14
map reduce
MapReduce
• 元データがレコード単位に分割されて map に配布される
• map でデータを加工し key と value の組データを出力
• reducer は key 毎にまとめられた value 群を受け取り、新たな key と value の組を出力
15
map reduce
MapReduce の例• 学校のテスト結果• 1 人分の結果を書いたカードがある• 手作業で組ごとの平均点を求めるには?
16
1 組 20 番 75 点
組ごとの平均点を算出• どうするか?
17
1 組 5 番 80 点1 組 20 番 75 点
3 組 12 番 90 点
3 組 3 番 35 点
1 組 4 番 20 点
2 組 7 番 20 点
3 組 15 番 90 点
2 組 10 番 75 点
2 組 31 番 50 点
1 組 25 番 80 点
組ごとの平均点を算出• 当然
1. 組ごとにカードを分ける2. 組ごとに点数を足す3. 平均点 = 合計点 / カードの枚数
18
1 組 5 番 80 点
1 組 20 番 75 点
1 組 4 番 20 点
1 組 25 番 80 点
2 組 7 番 20 点
2 組 10 番 75 点
2 組 31 番 50 点
3 組 12 番 90 点
3 組 3 番 35 点
3 組 15 番 90 点
255 145 215
255/4=63.75 145/3=48.33 215/3=71.66
MapReduce にあてはめる• 1 人分のデータを map に配布• map は組を key, 点数を value にして出力• reduce は組ごとにグループ化されたデー
タ群を受け取れるので、平均点を算出
19
・・・・・・
1 組 63.752 組 48.333 組 71.663 組 7 番 20 点
2 組 15 番 90 点
1 組 4 番 20 点1 20, 80, 75,80
2 20, 75, 50
3 35, 90, 90
1 20
3 20
2 90
処理対象データ
20
3 44 63 1 32 89 2 33 74 1 21 36 3 1 99
・・・
2 42 84
組 番号 点数
MapReduce プログラム実装• map を行う Mapper クラスの定義• reduce を行う Reducer クラスの定義• 実行時の設定である Job オブジェクトの生
成
21
Mapper クラスと Reducer クラス• Hadoop 側で用意されている抽象クラス
Mapper と Reducer をオーバーライドして定義する
• 必要なのは 1 つのメソッドだけ– Mapper なら map メソッド– Reducer なら reduce メソッド
– 先ほどの平均点プログラムの場合……
22
平均点算出 Mapper
23
public class ScoreAverageMapper extends Mapper<LongWritable, Text, IntWritable, IntWritable> { protected void map(LongWritable key, Text value, Context context) throws IOException ,InterruptedException { String[] columns = value.toString().split("\t"); int classN = Integer.parseInt(columns[0]); int score = Integer.parseInt(columns[2]); context.write(new IntWritable(classN), new IntWritable(score)); };}
総称型で入出力データの型を定義 value が
入力ファイル 1 行分
key が組value が点数として出力
平均点算出 Reducer
24
public class ScoreAverageReducerextends Reducer<IntWritable, IntWritable, IntWritable, DoubleWritable> { protected void reduce(IntWritable key, Iterable<IntWritable> values, Context context)throws IOException ,InterruptedException { int sum = 0; int students = 0; for (IntWritable score : values) { sum += score.get(); students++; } context.write(key, new DoubleWritable((double)sum / (double)students)); };}
key が組key (組)と結びついている
value (点数)がIterable として取得できる
key が組value が平均点
として出力
Job オブジェクトの生成
25
Job job = new Job(getConf());job.setJarByClass(ScoreAverage.class);
job.setMapperClass(ScoreAverageMapper.class); Mapper クラスの指定job.setReducerClass(ScoreAverageReducer.class); Reducer クラスの指定
job.setMapOutputKeyClass(IntWritable.class); Mapper クラスの出力 key の型job.setMapOutputValueClass(IntWritable.class); Mapper クラスの出力 valueの型job.setOutputKeyClass(IntWritable.class); Reducer クラスの出力 key の型job.setOutputValueClass(DoubleWritable.class); Reducer クラスの出力 valueの型
job.setInputFormatClass(TextInputFormat.class); Mapper へのデータの与え方job.setOutputFormatClass(TextOutputFormat.class); 出力結果の形式
FileInputFormat.addInputPath(job, new Path(args[0])); 入力ファイルのパスFileOutputFormat.setOutputPath(job, new Path(args[1])); 出力ファイルのパス
return job.waitForCompletion(true) ? 0 : 1; 設定内容で MapReduce を実行
実際に動作させる• Hadoop の 3 つのモード– スタンドアロン• 開発用
–疑似分散• 動作確認用
– 分散環境• 実環境
26
Hadoop の利点 1
• 1 つの map, reduce タスクは、ほかのタスクの進捗状況を考慮する必要がない
• プログラミングが容易• 他人の書いた MapReduce を再利用可能
27
・・・・・・
1 組 63.752 組 48.333 組 71.66
この map タスクからすれば、他の map がどういう状況であろう
と、自分の作業には関係ない
Hadoop に向かないこと• MapReduce の実行には小さくないオー
バーヘッドが掛かる• リアルタイムで結果を求めれるような処
理には不向き– 例えば検索システム– ×検索の度に MapReduce でデータを解析–○あらかじめインデックスなどの 2 次的な
データを MapReduce で生成しておく
28
Wikipedia データへの応用
29
Wikipedia データへの応用• 平均点の時と同様に、この MapReduce の枠組みに当てはめて考える
30
map reduce
jawiki-latest-pages-meta-current.xml
Wikipedia データへの応用• page 要素( 1 ページ分のデータ)が
Mapper に配布する単位としてちょうど良さそうである
31
<mediawiki> <siteinfo> ヘッダー情報 </siteinfo> <page> ページ内容 1</page> <page> ページ内容 2</page> <page> ページ内容 3</page> ・ ・ ・ <page> ページ内容 n</page></mediawiki>
ページ要素1,880,711 個
InputFormat の定義• 入力ファイルを Mapper に与える形に分割
するクラス• 平均点プログラムでは TextInputFormat– 入力ファイルを 1 行ずつ切り出す–継承して page 要素を切り出す InputFormat を
定義
32
InputFormat
WikipediaXmlInputFormat
• 実際には TextInputFormat の機能を利用して 1 行ずつ読みだし、 page 要素の始まりから終わりまでを Mapper へ渡す
33
<mediawiki> <siteinfo> ヘッダー情報 </siteinfo> <page> ページ内容 1</page> <page> ページ内容 2</page> <page> ページ内容 3</page> ・ ・ ・ <page> ページ内容 n</page></mediawiki>
1 ページの分のデータを Mapper へ配布する
ページ名やページの種別を出力• 記事、カテゴリ、リダイレクトを抽出• ページ名は title 要素から取得• 判断基準– カテゴリ• ページ名が” Category:” で始まる
– リダイレクト• 本文が #REDIRECT [[転送先 ]] という記述
– 記事• それ以外
34
実行時間• 日本語版データファイル• 使用マシン– OS: CentOS 5– CPU: Xeon 3060 2.40GHz– メモリ : 4GB– マスタ 1 台、スレーブ 3 台
• ページの種別を抽出のに 3 分程度
35
記事中に挙げられている参考文献を集める
• Wikipedia では情報の出典を記載するガイドラインがある–残念ながらあまり守られていない……– (特に日本語版では)
• ISBN コードを集める–世界中を書籍を識別するためのコード– Wikipedia は書籍の出典に ISBN コードを記述
するのは任意
36
記事中に挙げられている参考文献を集める
• ページが記事であれば、本文から ISBNコードを抽出–正規表現によるパターンマッチ– ISBN (*[\d-]+)– 10桁の旧規格と、 13桁の新規格が混在– 新規格への変換手順があるので、新規格に統
一して出力
37
参考文献英語版 日本語版 ドイツ語版 フランス語版
外部リンクがある
42% 39% 52% 30%
参考文献のセクションがある
34% 6% 20% 10%
ISBN コードがある
6% 5% 14% 3%
38
• 書籍と、 Web上の資源で参照している割合が異なる
テレビ番組の記事を抽出する• 以下の基準でテレビ番組であるか判定す
る– カテゴリに”~番組”がある– テンプレートに”基礎情報 _ 番組”がある
39
MediaWiki との比較
40
MediaWiki との比較処理データ 分散処理 言語 Wiki 記法
Hadoop XML ファイル
可能 Java 自前で解析
MediaWiki データベース 不可能 PHP 標準の Parser
41
• MediaWiki は単独のマシン上で PHP と RDB を使う
• Hadoop は複数のマシン上で Java を使う
• 複雑な Wiki 文法を解析するのは困難
テンプレート• 与えた引数に応じて Parser が文字列を出
力する仕組み• {{Lang-en|United States of America}}– Lang-en というテンプレート–引数は” Lang-en|United States of America”
• Parser の出力は• 英語 : United States of America
42
なぜ Hadoop上でテンプレートを解析しにくいか 1
• 記事の• という記述を見ても、 Lang-en が呼び出さ
れていることは分かっても、 Lang-en がどのようなテンプレートかは分からない
43
{{Lang-en|United States of America}}
43
・・・・・・
1 組 63.752 組 48.333 組 71.66
Mapper は自分が与えらたデータのほかには参照できるデータがない
なぜ Hadoop上でテンプレートを解析しにくいか 2
• テンプレートは入れ子にできる• リンクやタグを書ける
44
MediaWiki との使い分け
45
処理データ 分散処理 言語 Wiki 記法Hadoop XML ファイ
ル可能 Java 自前で解析
MediaWiki データベース 不可能 PHP 標準の Parser• 複雑な文法を解析する場合は、 MediaWiki を利用したほうが効率的
• Java にも代替パーサがある• http://code.google.com/p/gwtwiki/• ある程度の文法はサポートされている
が、 Wikipedia で使われている多くの extension まではサポートしきれない
おわりに• 本日紹介したプログラムはソースコードと共に公開しています
• http://sourceforge.jp/projects/wik-ie/
• ご清聴ありがとうございました
46