R&Dトレンドレポート

第9回MapReduce処理をやってみよう![準備編]

MapReduce処理の向き不向き

さて、前回構築したHadoop環境ですが、それを使ってのMapReduce処理の実装をしてみましょう。が、その前に、どのような処理が向いているのか確認してみたいと思います。

MapReduceは計算フレームワークですが、HDFSと組み合わせることにより、特に大規模データの分散処理に有用なものとなります(小さい入力データについて処理を分散させることも可能です⁠⁠。

入力に使用されるデータの種類は

  • テキスト
  • XML
  • バイナリ
  • データベースから

という風にいくつかの入力を受け付けることが可能です。今回はテキストファイルを入力としたMapReduceを行いたいと思います。

大規模なテキストデータ

入力となるテキストデータを今回はインターネット上のコンテンツから取得したいと思います。

2ちゃんねるという巨大掲示板サイトは、みなさんご存じかと思います。2ちゃんねるではさまざまなジャンルの掲示板が存在していますが、実況板はテレビ番組を見ながら突っ込みを入れるというスタイルの掲示板となっており、番組内での過激なシーンや発言があると掲示板上では一気に書き込みが増えます。

インターネットユーザの嗜好に偏った部分もありますが、共通のコンテンツに対しリアルタイムで発言するというスタイルが非常におもしろいと感じます。

今回の題材では、2ちゃんねるの実況板への書き込みデータを使用し、いくつかの解析を行いたいと思います(データ量はそれほど多くないですが⁠⁠。

解析

ある番組に実況データを解析し、以下の事を行いたいと思います。

  • ある時間単位でどのような単語が多く書き込まれたか?

複数の人間が1つのコンテンツを視聴しているわけですが、それなりにシーンに直結した発言が多く見られるのではないだろうか。ここでは閾値を10分程度に見ておきます。

処理の流れ

①データ取得・登録

2ちゃんねるからダウンロードしたログデータをHDFSに保存します。これはMapReduce処理のインプットとなるデータです。ここでは1行1レスポンスというフォーマットで保存します。

②Map処理

①のデータを入力としてMap処理がスタートします。Map処理では、以下のことを行います。

  • データの正規化(アスキーアートの削除)
  • キーとバリューへの分割(unixtimeを10分で丸めた値をキー、品詞解析した単語をバリューにする)

この処理は各サーバに分割されたファイルについて実行されます。

③Reduce処理

②で処理された結果を受けて実行されます。キーごとに単語数を集計し、上位2単語程度を当該時間帯でよく発言されたものとする。

基本的には上記のような流れで進めてみたいと思います。

データフォーマット

2ちゃんねるのデータは以下のような形式になっています。

  • 文字コードはUTF-8
  • CSV形式
  • 行セパレータは\nとする(改行区切り⁠⁠。
例)
1283124797,4,名無しでいいとも!,y+yK12Lz,,sage, 絵心があるなw

左から、
書き込みunixtime
レス番号
名前
ID
ID2
メールアドレス
書き込みテキスト

データ取得プログラム

2ch.pl
#!/usr/bin/perl

use strict;
use WWW::2ch;
use Data::Dumper;
use Encode;
use Encode::Guess qw/ euc-jp shiftjis 7bit-jis /;


my $ch2url = {
        1=>"http://hayabusa.2ch.net/livenhk/","http://hayabusa.2ch.net/livenhk/",
        2=>"http://hayabusa.2ch.net/liveetv/","http://hayabusa.2ch.net/liveetv/",
        4=>"http://hayabusa.2ch.net/liventv/","http://hayabusa.2ch.net/liventv/",
        6=>"http://hayabusa.2ch.net/livetbs/","http://hayabusa.2ch.net/livetbs/",
        8=>"http://hayabusa.2ch.net/livecx/","http://hayabusa.2ch.net/livecx/",
        10=>"http://hayabusa.2ch.net/liveanb/","http://hayabusa.2ch.net/liveanb/",
        12=>"http://hayabusa.2ch.net/livetx/","http://hayabusa.2ch.net/livetx/",
};

my $url =  $ch2url->{$ARGV[0]} or die "引数にチャンネル番号を入れてね";{$ARGV[0]} or die "引数にチャンネル番号を入れてね";

my $bbs = WWW::2ch->new(url => $url, cache => '/tmp/www2ch-cache');new(url => $url, cache => '/tmp/www2ch-cache'); $url, cache => '/tmp/www2ch-cache'); '/tmp/www2ch-cache');
$bbs->load_setting;load_setting;
$bbs->load_subject;load_subject;

#print STDERR Dumper $bbs->subject;subject;

foreach my $dat ( $bbs->subject->threads )subject->threads )threads )
{
        # threadのキー
        my $key = $dat->key;key;
        my $title = $dat->title;title;

        &u8(\$title);

        $dat->load;load;
        foreach my $res ( $dat->reslist )reslist )
        {
                my $resid = $res->resid;resid;
                my $body = $res->body_text;body_text;
                my $name = $res->name;name;
                my $time = $res->time;time;
                my $be = $res->be;be;
                my $mail = $res->mail;mail;
                my $id2 = $res->id;id;

                &u8(\$resid);
                &u8(\$body);
                &u8(\$name);
                &u8(\$mail);

                $body =~ s/\n//g;

print $time,",",$resid,",", $name, ",",  $id2,",", $be, ",", $mail,",", $body, "\n";
        }
}


sub u8
{
        my ($t) = @_;

        Encode::from_to($$t, "shiftjis", "utf8");

}

データ取得方法

$ ./2ch.pl 4 > 2ch_4.csv 2ch_4.csv

このように引数にチャンネル番号を指定して起動します。標準入力に出力されますので、保存したいファイル名でデータを保存します(ここでは2ch_4.csvとしています⁠⁠。

HDFSへのデータ登録

hユーザで登録を行います。

$ hadoop dfs -put 2ch_4.csv

これでHDFSにデータの登録ができました。

データの確認

$ hadoop dfs -ls 

drwxr-xr-x   - h supergroup           4123 2010-10-12 16:53 /user/h/2ch_4.csv

このような出力が出れば問題ありません。

$ hadoop dfs -cat 2ch_4.cvs

とするとファイルの中身が出力されると思います。

取り急ぎ今回はここまで。次回から実際にプログラムを書いていきます!

おすすめ記事

記事・ニュース一覧