perlで手軽に統計量を計算する
perlとは
wikipediaによると以下のように説明されています。
Perl(パール)とは、ラリー・ウォールによって開発されたプログラミング言語である。実用性と多様性を重視しており、C言語やsed、awk、シェルスクリプトなど他のプログラミング言語の優れた機能を取り入れている。ウェブ・アプリケーション、システム管理、テキスト処理などのプログラムを書くのに広く用いられている。
このsed, awk, シェルスクリプトとの相性の良さから、perlで作成されたツールをシェルスクリプト内で呼び出すような使われ方を良く見かけます。
(音声認識ツールキットのKaldiでも、中身を覗くとperlのツールがたくさんあり、シェルスクリプト内で呼び出すように使われています。)
perlで統計量計算
今回作成したツールは、コマンドライン上の標準出力をperlに入力して動作するものになっています。
合計、行の数(=データの数)、平均、標準偏差を算出する仕様になっています。
使い方は後述します。
#!/usr/bin/perl use strict; use warnings; use utf8; binmode STDIN, ':utf8'; binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; my $sum; my $count; my @arr; while( <STDIN> ){ chomp; $sum += $_; $count++; @arr = (@arr, $_); } print "SUM : $sum \n"; print "COUNT : $count \n"; my $mean = $sum / $count; print "MEAN : $mean \n"; my $dist_sum; for ( @arr ){ my $dist_sq = ($_ - $mean) ** 2; $dist_sum += $dist_sq; } my $sd = sqrt($dist_sum / $count); print "SD : $sd \n";
使い方
Macであればターミナル上で動作します。
WindowsではWSL(Windows Subsystem for Linux)が使える環境であることが前提です。
また、前項のツールは、meansd_stdin.plというファイル名で保存し、ホームディレクトリ(~)の下に作成したtoolsフォルダの中に配置しています。
データの準備
今回はサンプルデータの王道、irisデータセットを使いたいと思います。
以下からダウンロードしました。
https://archive.ics.uci.edu/ml/datasets/Iris
iris.dataをダウンロードし、コマンドライン上でiris.dataがある場所に移動の上で以下のように入力すると、データの冒頭部分が見れると思います。
head iris.data
5.1,3.5,1.4,0.2,Iris-setosa 4.9,3.0,1.4,0.2,Iris-setosa 4.7,3.2,1.3,0.2,Iris-setosa 4.6,3.1,1.5,0.2,Iris-setosa 5.0,3.6,1.4,0.2,Iris-setosa 5.4,3.9,1.7,0.4,Iris-setosa 4.6,3.4,1.4,0.3,Iris-setosa 5.0,3.4,1.5,0.2,Iris-setosa 4.4,2.9,1.4,0.2,Iris-setosa 4.9,3.1,1.5,0.1,Iris-setosa
統計量の計算
今回作成したツールは、1列分のデータのみを受け付けるようになっています。
したがって、iris.dataから1列分だけ読み取るようにする必要があります。
今回は、3列目のデータを抜き出してみましょう。
以下のように入力すると、3列目だけを抜き取ることができます。
cat iris.data | cut -d , -f 3
1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 ...続く
cut コマンドは、各行のある部分だけを抜き出して出力してくれるコマンドです。
今回は、-dオプションで','を指定し、-fオプションで'3'を指定しているので、「,で区切られた3フィールド目を表示」するようにしています。
次に、このデータは最終行が空行になっているため、以下のように入力して空行を削除します。
cat iris.data | cut -d , -f 3 | sed '/^$/d'
sedコマンドは、置換したり削除したり、追加するときに便利なコマンドです。
こちらのページが非常に参考になります。
では、この3列目のデータを入力に、統計量を計算しましょう。
コマンドライン上で以下のように入力します。
cat iris.data | cut -d , -f 3 | sed '/^$/d' | ~/tools/meansd_stdin.pl
以下のように出力されるかと思います。
SUM : 563.8 COUNT : 150 MEAN : 3.75866666666667 SD : 1.75852918340552
おまけ
irisは、品種ごとに比較することを想定したデータセットなので、ある品種における統計量を見たくなるかもしれません。
そんなときは以下のように使用する行を絞り込みましょう。
cat iris.data | grep Iris-setosa | cut -d , -f 3 | sed -e '/^$/d' | ~/tools/meansd_stdin.pl
前項で紹介した入力内容との差分を取ると、grepコマンドが増えています。
grepコマンドは、文字列を指定して、それを含む行(あるいは含まない行)を絞り込むために使用します。
(指定している文字列「以外」の行に絞り込む場合は-vオプションを使います。)
以下のように、結果が変わります。
SUM : 73.2 COUNT : 50 MEAN : 1.464 SD : 0.171767284428671
以上です。