ラベルとそれに付随する要素リストを扱う Perl ワンライナー
2010-02-13-4
[Programming][NLP]
各行にラベルとそれに関する要素のリストを持つデータをよく使う。
類似文書検索や機械学習やクラスタリングなどに。
自分流の使い方を後で参照するためにメモ。
データの各行のフォーマットはこんな感じ:
サンプルデータ1 (a.txt):
以下、定番処理を Perl のワンライナーで記述。
表示のため複数行にしているのもあり。
類似文書検索や機械学習やクラスタリングなどに。
自分流の使い方を後で参照するためにメモ。
データの各行のフォーマットはこんな感じ:
各行の要素は数値の降順で並んでいる。^ラベル1\t要素1-1:数値1-1,要素1-2:数値1-2,要素1-3:数値1-3,...$ ^ラベル2\t要素2-1:数値2-1,要素2-2:数値2-2,要素2-3:数値2-3,...$ ^ラベル3\t要素3-1:数値3-1,要素3-2:数値3-2,要素3-3:数値3-3,...$ ...
サンプルデータ1 (a.txt):
サンプルデータ2 (a2.txt):ゆで卵 卵:3 カレー 米:4,牛:3,豚:3,鶏肉:3,ソース:2 釜玉 卵:2,うどん:2,醤油:1 焼き鳥 鶏肉:10,醤油:5,塩:4,豚:1 豚カツ 豚:27,ソース:7,塩:6,味噌:1 豚汁 豚:3,味噌:1,ネギ:1
ゆで卵 卵:1,塩:1,マヨネーズ:1 牛丼 牛:8,米:3 豚汁 豚:10,味噌:10,ニンジン:5,ネギ:1
以下、定番処理を Perl のワンライナーで記述。
表示のため複数行にしているのもあり。
フォーマットチェック
perl -ne 'die if !/^(.+?)\t(([^,]+?(:\d[\d.]*?)?[,\n])+)$/;' a.txt
平均要素数
実行結果:perl -nlaF, -e '$n+=@F;END{print$n/$.}' a.txt
3.33333333333333
要素数を指定してカット
実行結果:perl -pe 's/^(([^,]+?[,\n]){3}).*$/$1/;s/,$//' a.txt
ゆで卵 卵:3 カレー 米:4,牛:3,豚:3 釜玉 卵:2,うどん:2,醤油:1 焼き鳥 鶏肉:10,醤油:5,塩:4 豚カツ 豚:27,ソース:7,塩:6 豚汁 豚:3,味噌:1,ネギ:1
要素数分布
実行結果:perl -nle '@c=split/,/;$n{@c}++; END{map{$m=$n{$_}if$m<$n{$_}}keys%n; $m=$m>60?60/$m:1; print join"\n",map{"$_:$n{$_}\t".("|"x($n{$_}*$m))}sort{$b<=>$a}keys%n }' a.txt
5:1 | 4:2 || 3:2 || 1:1 |
転置インデックスの作成
実行結果:perl -nle '($l,$s)=split/\t/; map{/^(.+):(.+)$/;$h{$1}{$l}+=$2}(split(/,/,$s)); END{for$i(sort keys%h){ print"$i\t".join",",map{"$_:$h{$i}{$_}"} sort{$h{$i}{$b}<=>$h{$i}{$a}}keys%{$h{$i}}} }' a.txt
(ref. [を] 転置インデックスによる検索システムを作ってみよう![2007-11-26-5])うどん 釜玉:2 ソース 豚カツ:7,カレー:2 ネギ 豚汁:1 卵 ゆで卵:3,釜玉:2 味噌 豚汁:1,豚カツ:1 塩 豚カツ:6,焼き鳥:4 牛 カレー:3 米 カレー:4 豚 豚カツ:27,豚汁:3,カレー:3,焼き鳥:1 醤油 焼き鳥:5,釜玉:1 鶏肉 焼き鳥:10,カレー:3
マージ
実行結果:perl -nle '($l,$s)=split/\t/; map{/^(.+):(.+)$/;$h{$l}{$1}+=$2}(split(/,/,$s)); END{for$i(sort keys%h){print"$i\t".join",", map{"$_:$h{$i}{$_}"}sort{$h{$i}{$b}<=>$h{$i}{$a}}keys%{$h{$i}}} }' a.txt a2.txt
ゆで卵 卵:4,マヨネーズ:1,塩:1 カレー 米:4,鶏肉:3,豚:3,牛:3,ソース:2 焼き鳥 鶏肉:10,醤油:5,塩:4,豚:1 牛丼 牛:8,米:3 豚カツ 豚:27,ソース:7,塩:6,味噌:1 豚汁 豚:13,味噌:11,ニンジン:5,ネギ:2 釜玉 うどん:2,卵:2,醤油:1
共通ラベルの数
実行結果:perl -nle '$h{$1}++if/^(.+)\t/; END{$n=grep{$h{$_}==2}keys%h;print$n}' a.txt a2.txt
2