Java以外でMapReduceする
前回はJavaのネイティブプログラミングでMapReduceを実践してみましたが,
それぞれの処理の入出力は標準入出力を使用しますが,
PerlでMapReduceする
今回はPerlを使用しますが,
ネイティブな環境とストリーミングの違いはSort&Shuffleの出力
- キー,
[バリュー1,バリュー2,バリュー3]
だったのに対し,
- キー,
バリュー1 - キー,
バリュー2 - キー,
バリュー3
というふうに出力されます。
それではMap, ReduceをPerlで書いてみましょう。
まず準備としてMeCabのPerlのモジュールを導入します。MeCab本体は前回までの準備で入っているものとします。
MeCabのサイトからmecab-perl-0.
$ perl Makefile.PL $ make $ make test # make install
この作業は全てのサーバで必要になります。
MapプログラムをPerlで書く
それではJavaで書いたプログラムをPerl化する作業に入りましょう。入力と出力は変わりません。前回の入出力を転載しておきます。
入力
1287144100 299 名無しさんにズームイン! LnjhWICN sage 迫力ねえよ,香川w
1287144803 300 名無しさんにズームイン! 3M/Iym08 sage 利根川なんかちがう。
1287144804 301 名無しさんにズームイン! xueZONEO sage 利根川キター!
出力
1287144000 迫力
1287144000 ねえ
1287144000 よ
1287144000 ,
1287144000 香川
1287144000 w
1287144600 利根川
1287144600 なんか
1287144600 ちがう
1287144600 。
1287144600 利根川
1287144600 キター
1287144600 !
キーがunixtime
リスト1 Mapプログラム
#!/usr/bin/perl
#
#
use strict;
use MeCab;
use Data::Dumper;
use Encode qw(encode decode);
use utf8;
use constant TIMESEC=>600;
# 標準入力から読み込み
while (<STDIN>)
{
chomp; # 改行削除
my @line = split(/¥t/, $_); # タブでスプリット
# 時刻を丸める。
my $time = int($line[0]/TIMESEC)*TIMESEC;
my $body = $line[6];
$body = decode("utf8", $body);
if( my $buf = isAA($body) )
{
next;
}
$body = noGomi($body);
my $mecab = MeCab::Tagger->new();
my $node = $mecab->parseToNode($body);
while( $node = $node->{next} )
{
next if ( ! defined $node->{surface} );
my $surface = $node->{surface};
next if ( isGomi($surface) );
my($hinsi, $hinsi2) = (split( /,/, $node->{feature} ))[0..1];
if ( $hinsi eq encode("utf8", "名詞" ) && $hinsi2 ne encode("utf8", "非自立"))
{
# キーバリューで出力。セパレータはタブ。
print $time, "¥t", $surface,"\n";
}
}
}
sub isAA
{
my $s = shift;
$s =~ /.*[/ ̄_\ ]{2,}.*/;
return $&;
}
sub noGomi
{
my $s = shift;
$s =~ s/(h?ttp:¥/¥/|h?ttps:¥/¥/|sssp:¥/¥/){1}[¥w¥.-¥/:¥#¥?¥=¥&¥;¥%¥~¥+]+|>?>[0-9- ]+//g;
return $s;
}
sub isGomi
{
my $s = shift;
return $s =~ /^[¥゚¥/¥?¥!¥(¥),0-9a-zA-Z0-9$%”!#&,;:?|{}@`*+_?><∴∀Д▼△▲▽]/;
}
動作確認
基本的に標準入力,
$ cat 2ch_4.txt | perl ./J2chMap.pl 1287144000 迫力 1287144000 ねえ 1287144000 よ 1287144000 香川 1287144000 w ・ ・ $
コマンドラインで入力データをパイプで渡すことで簡単にテストが可能です。Mapの出力であるキーバリューが確認できればOKです