たつをの ChangeLog : 2010-06-21

SUFARY に付属している sang というプログラムの Perl 版「sang.pl」を作りました。
オリジナルCコード(sang.c)に書いてある説明を改変して載せておきます。
使い方は同じです。

sang.pl  ---  Suffix Array を用いて N-gram 統計をとるプログラム

USAGE   sang.pl -n NUM -t NUM FILENAME
OPTION
-n NUM : NUM で n-gram の n を指定する。
-t NUM : threshold: NUM以下の頻度のものは表示しない

n-gram には改行は含まれない。

[実行例]
% cat test
ABCBACABBAACABCABCACABACABBACBACACAAABACCAB
% makeary -q test                 ● arrayファイルの作成
% sang -n 6 -t 1 test             ● 6-gram で頻度が 1 より大きいものを表示
2 ACABBA
2 BACABB
% ./sang.pl -n 3 -t 4 test        ● trigram で頻度が 4 より大きいものを表示
6 ACA
5 BAC
6 CAB

■コード(sang.pl):
#!/usr/bin/perl
use strict;
use warnings;
use SUFARY;
use Encode;
use Getopt::Std;
use utf8;
use open ':utf8';
binmode STDOUT, ":utf8";

my %opts = ();
getopts("n:t:", \%opts);
my $ng = $opts{n} || 4;
my $threshold = $opts{t} || 3;
my $fn = shift @ARGV;
my $sa = SUFARY->new($fn);

my $n_ctr = 0;
my @ktoks = ();
for (my $i = 0; $i < $sa->{arraysize}; $i++) {
    my $pos = $sa->get_position($i);
    my ($from, $len) = $sa->get_line_info($pos);
    my $s = $sa->get_string($pos, $from + $len - $pos);
    $s =~ s/^([^\n]+)\n.*$/$1/;
    my @ttoks = map {Encode::decode_utf8($_)}
       ($s =~ m{([\x00-\x7f]|[\xC0-\xDF][\x80-\xBF]|
       [\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3})}gsx);
    if (cmp_tok(\@ktoks, \@ttoks) >= $ng) {
       $n_ctr++;
    } else {
       output();
       $n_ctr = 1;
    }
    @ktoks = @ttoks;
}

output() if $n_ctr >= 1;

sub output {
    return if $n_ctr <= $threshold;
    print "$n_ctr ".join("", @ktoks[0..($ng-1)])."\n";
}

sub cmp_tok {
    my ($k_ref, $t_ref) = @_;
    my $i;
    for ($i = 0; $i < @$k_ref and $i < @$t_ref; $i++) {
       last if $k_ref->[$i] ne $t_ref->[$i];
    }
    return $i;
}

■実行例:
インデックス作成。
対象ファイルは utf-8。
mkipu8.pl[2007-06-10-3]を使う。
% ./mkipu8.pl a.txt > a.txt.ary
% mkary -so a.txt
N-gram カウント。
4-gram で頻度は3よりも大きいものを出力。
% ./sang.pl -n 4 -t 3 a.txt 
4 100円
5 「ぬんな
10 ぬんなり
4 ました。
4 まったり
5 んなり」

ref.
- SUFARY 臨時復旧ページ http://ta2o.net/tools/sufary/
(SUFARYの入手はここから。)
- [を] SUFARY用インデクサのPerl版の雛形[2007-06-10-3]
(mkipu8.pl のソースはここに。)
- [を] 自分マイニング! - Blogでよく使うフレーズは?[2005-01-18-3]
(sang を使ったデータマイニング例。)

先週の水曜日の夕方、原宿でG原夫妻とお茶しました。
竹下通りと平行に走る暗渠「ブラームスの小径」の入口にあるクリスティにて。

クリスティ(原宿) クリスティ(原宿)

クリスティー 原宿本店
http://gourmet.livedoor.com/restaurant/21793/
場所:東京都渋谷区神宮前1-16-1

10年ほど前に廣瀬さん(最近コメント頂いた!お元気ですか!)につれていって頂いたお店です[2000-04-17-2]
最後に廣瀬さんに会ったのはNHKホールでのパットメセニーのライブで、ライブ後もクリスティに行ったなあ。あれからもう8年になるのですね……。

- PMG LIVE REPORT 2002-09-20
http://ta2o.net/doc/zb/0009.html

竹下通りの近くなのに落ち着いた雰囲気の店なので、それから何回も利用しています。
もちろん紅茶もおいしいし。
オススメです。

それはそうと、原宿駅でG原夫妻を待つ間、歩道橋に登って街を撮影。
表参道方面や原宿駅方面や体育館方面など。
参道なう
原宿なう
森とか体育館とか

ビール以外の発泡酒・第三のビールの試し飲みシリーズ。

今回はサッポロのノンアルコールビールです。
あまり売っているのを見かけないですよね。
スーパーやコンビニで取り扱っているのを見たことがありません。
これは恵比寿ガーデンプレイス(サッポロビールのおひざもと)で買いました。

スーパークリア(サッポロ)
サッポロビール | サッポロスーパークリア
http://www.sapporobeer.jp/product/others/superclear/index.html

味は甘い系。
ホッピーっぽいかも。
まあいいかな、って感じです。
私の中ではキリン「フリー」[2009-05-25-1]の首位は変わらず。

■最近の発泡酒・第三のビール試し飲みシリーズ:
- [を] ジョッキ のみごたえ辛口 生(サントリー)[2010-05-30-2]
- [を] 休む日の Alc. 0.00%(キリン)[2010-05-01-5]
- [を] ホッピー(ホッピービバレッジ)[2010-04-30-5]
- [を] 7種のホップ リラックス(サントリー)[2010-04-21-1]
- [を] ストロングオフ(アサヒビール)[2010-04-18-5]
- [を] サウザン(キリン)[2010-03-26-1]
- [を] 琥珀の贅沢(サントリー)[2009-12-14-1]
- [を] 麦搾り(アサヒビール)[2009-09-24-4]
- [を] ホップの真実(キリン)[2009-09-10-2]
- [を] ポイントゼロ(アサヒビール)[2009-09-07-5]
- [を] ザ・ブリュー(サントリー)[2009-08-09-1]
- [を] 冷製SAPPORO(サッポロ)[2009-07-20-1]
- [を] コクの時間(キリン)[2009-07-02-1]
- [を] クリアアサヒ(アサヒビール)[2009-06-24-3]
- [を] 豊か<生>(サントリー)[2009-06-02-1]
- [を] キリンフリー(キリン)[2009-05-25-1]
- [を] 金麦(サントリー)[2009-05-15-1]
- [を] ストロングセブン(キリン)[2009-05-11-1]
- [を] 麦とホップ(サッポロ)[2009-05-10-1]
- [を] アサヒ オフ(アサヒビール)[2009-05-08-1]
- [を] ダイエット<生>クリアテイスト(サントリー)[2009-04-26-1]
- [を] ザ・ストレート(サントリー)[2009-04-20-2]

たつをの ChangeLog
Powered by chalow