Statistics::ZScore 書いた

うう、1日に3つ目のエントリ、だいぶ疲れてきた。

なので手短に紹介します。

Statistics::Zscore - Simple scoring module that uses statistics STANDARD SCORE.
http://search.cpan.org/~miki/Statistics-Zscore/

これは統計学で出てくる「標準化」とか「正規化」とかいわれる処理をモジュールにしたものです。
エクセルだとstandardizeなんて関数になってますね。

(そのデータの値 - 平均値)/ 標準偏差 

で求められる値です。

詳しい説明は省きますが、要するに基軸の異なる複数の値(例えばキロと円とか)を線形結合してスコアとして使いたい、といったことを実現するために書いたモジュールです。

もっと一般的な例で言うとまさに学力の偏差値とかがそうですね。

国語と英語と数学と、どれも平均点とか違うわけです。難易度というか、分布状況が異なっている、つまりは基軸がそろっていないわけですね。それを単純に点数だけ足し合わせると、「A君とB君とC君とだれが一番優秀なの」といった判断をするときに誤りがでてしまう。だから「偏差値」というものがでてくるんですね。

この偏差値をスコアに見立ててあげて、あとはおのおの好きなように重みをかけてあげて足し合わせれば、「総合スコア」になるわけです。

早速使い方です。

use Statistics::Zscore;

my $z = Statistics::Zscore->new;
my $zscore = $z->standardize( \@array );

これがシンプルな使い方です。
単純に配列リファレンスを渡すとその配列の値を標準化した配列のリファレンスを返します。

これをベースにもう少し便利な使い方がこれです。

use Statistics::Zscore;

my $z = Statistics::Zscore->new;
my $result = $z->combine(
    data => {
        yamada => [ 95, 33, 65, 84 ],
        suzuki => [ 75, 45, 80, 78 ],
        tanaka => [ 44, 72, 84, 65 ],
    },
    weight => [ 0.25, 0.25, 0.4, 0.1 ],         
    data_num => 4
);

print Dumper $result;

yamadaさんとsuzukiさんとtanakaさんの4教科の成績とそれらの4教科の「重み」などを指定して、combineメソッドを呼び出しています。結果はこうです。

$VAR1 = {
          'yamada' => '-0.349298206036912',
          'suzuki' => '0.143540692271982',
          'tanaka' => '0.20575751376493'
        };

この場合だと0を平均として-0.5から0.5ぐらいの間に分布されるようにスコアリングされています。

「これだとちょっと扱いづらいな」という場合はいくつかのオプション引数を定義することでスコアのレンジが変わってきます。

use Statistics::Zscore;

my $z = Statistics::Zscore->new;
my $result = $z->combine(
    data => {
        yamada => [ 95, 33, 65, 84 ],
        suzuki => [ 75, 45, 80, 78 ],
        tanaka => [ 44, 72, 84, 65 ],
    },
    weight => [ 0.25, 0.25, 0.4, 0.1 ],         
    data_num => 4,
    scale   => 100, # 100倍
    plus    => 50,  # プラス方向に50
    decima  => 2    # 小数点2桁まで
);

print Dumper $result;

結果はこうなります。こうすると実際の「偏差値」っぽくなりますね。

$VAR1 = {
          'yamada' => '15.07',
          'suzuki' => '64.35',
          'tanaka' => '70.58'
        };

データの件数が少ないので隔たり具合がおかしい気がしますが、
もっとたくさんのデータをもってスコアリングすればより本物っぽくなってきます。

四方山話

このモジュールですが、最初はZscoreって名前でリリースしました。
が、程なくJerrad PierceというCPAN authorから
「統計関係のモジュールなのになんでStatisticsネームスペースじゃないの?」という旨のメールが届きました。

たしかにいきなり「Zscore」というよりも「Statistics::Zscore」の方がしっくり来るかなと思って改名したしだいです。

Jerrad曰く「namespace pollution is evil」だそうです。
そうですね。おっしゃるとおりでした、はい。

まとめ

まとめます。

スコアリングをする際には、それらの値だけを単純に足し合わせたりすると、不公平な結果になるし、それらに任意の重み付けとかしたいならば、なおさら正規化(標準化)が必要になるよ。

そんなことを唱えると「このひとって賢そう」 → 「モテ男になる」という結果につながります。

ぜひ使ってみてちゃぶだい。