読者です 読者をやめる 読者になる 読者になる

jnobuyukiのブログ

JavaScriptとR言語を中心に研究活動に役立つwebアプリケーション技術について考えていきます。twitter ID: @j_nobuyuki

数量の正規化:方法の違いは何を意味するか?

大量のデータをまとめて、視覚的に表現すると、データが持つ特徴を直感的に理解できることがあります。今回は、データを視覚化する際に施される「正規化」について考えます。wikipediaの正規化の定義は以下のようになっています。

正規化(せいきか、英: normalization)とは、データ等々を一定のルール(規則)に基づいて変形し、利用しやすくすること。

この定義は非常に抽象度が高いですね。その理由についてwikipediaは以下のように述べています。

非常に多くの分野で使われている言葉で、分野によって意味も大きく異なるため、頻度が高い分野についてそれぞれ個別に説明する。

今回は、数量の正規化に話を限定します。しかし、数量の正規化に絞るだけでは、まだその意味がはっきりしません。正規化する方法が沢山あるからです。私の専門の心理学では、行動データとして得たものを多変量解析にかける前に正規化することがあります。定番の正規化法は

  • データの加算平均が0、分散が1になるように調整する

です。式で書くと以下のようになります。
 (x_i - \overline{x})/SD_x
 \overline{x}はx全体の平均値、 SD_x標準偏差
また、以下のような方法もあります。

  • データの最小値が0、最大値が1となるように調整する

です。式で書くと以下のようになります。
 (x_i - x_{min})/(x_{max} - x_{min})

このような正規化の方法の違いが何を意味するのかを考えてみましょう。

二つの正規化の類似性

この式は、基本的に非常によく似た変換がおこなわれます。第1に、ある点からの差として、各点の位置の違いが表現されます。第2に、値全体についての指標で割り算が行われています。こうすると、データに割り当てられた単位が相殺されるので、各データが分布の中でどこにあるかがよりはっきりと示されます。二つの正規化では、同じような変換をされているので、どちらの正規化でも各点の相対的な大きさの関係はかわりません。では、二つの方法の違いは何でしょうか?

二つの正規化は想定される分布が異なる

実は、この二つの正規化で、データを得るための仮想的な分布の形状が異なります。前者ではガウス分布が、そして後者では一様分布が想定されていると思います。

ガウス分布を仮定した正規化

ガウス分布は、釣鐘型の分布をしています。そして、平均と分散で分布全体を特徴づけることができます。
(式を書いてもいいのですが、この投稿の趣旨を理解する妨げにならないようあえて省略します)
大事なことは、分布の中心に近い値が観察されやすく、遠い値は観察されにくいということです。また、ある仮想的な範囲から、値をランダムにサンプルする場合、サンプルの数を増やすほど、サンプルの分布がガウス分布に近づくことが知られています(中心極限定理という名前がついています)。この性質があるので、ランダムサンプリングを伴う調査では、調査で扱われる指標がガウス分布をとると暗黙のうちに仮定されます。そうすると、分布の中心から極端に遠い値は、サンプルを得る過程での何らかのエラーによるものと考えることができて、解析から除外することもあります。

D3.jsを利用したGauss分布データの作成法

D3.jsではGauss分布を前提とした乱数を生成できます。引数として分布の平均(デフォルトは0)と標準偏差(デフォルトは1)を取ります。例として平均100で標準偏差が10となるような分布から、100個のデータを生成してみましょう。

var arr = [];
for(var i = 0;i < 100; i++){
arr[i] = d3.random.normal(100, 10)();
}

今arrという配列にデータが生成されています。次はこれを上記の式をもとにして、正規化します。

var mean = average(arr);
function variance(arr){
var mean_arr = average(arr);
var var_arr = 0;

for (var k = 0;k<arr.length;k++){
var_arr = var_arr + Math.pow(arr[k]-mean_arr,2);
}
return Math.sqrt(var_arr/(arr.length - 1));
}
var sd = variance(arr);

var arr_norm = [];
for (var j = 0; j < 100; j++){
	arr_norm[j] = (arr[j] - average(arr))/sd; 
}

この変換でarr_normという配列に正規化されたデータが保存されています。ここでオリジナルデータと正規化したデータを比べてみると以下のようになります。0を中心に左右対称にデータが分布しています。-2未満や2以上のデータの生起確率は5%以下です。そのようなデータははずれ値とみなされて、解析から除外されることがあります。

一様分布を仮定する場合

ガウス分布とは異なり、一様分布では、分布に含まれる各値が等しい確率で出現することを想定します。(逆にいえば、何の特徴も持たないと想定しています。)なので、分布の中心に近い値も遠い値も同じような確率で見つかることが期待されます。ガウス分布を仮定する場合とは異なり、サンプルの中心からどんなに離れた値で合っても、それが観察される確率がある程度あるので、サンプルを得る過程でのエラーを検出できません。

Math.random()を利用した一様分布データの作成法

特定の分布を前提とせずに乱数を生成するならMath.random()を利用できます。

var arr = [];
for(var i = 0;i < 100; i++){
arr[i] = Math.random()*100;
}

同じようにarrには0から100までの値が一様に現れる分布から100個のデータを生成してarrに保存しました。これを正規化すると以下のようになります。

var arr_norm = [];
for (var l = 0;l < arr.length, l++){
var arr_norm[l] = (arr[l]- Math.min(arr))/(Math.max(arr) - Math.min(arr));
}

オリジナルデータと正規化したデータを比べてみると以下のようになります。ガウス分布を仮定する場合とは異なり、正規化した後のデータは0が最小値、1が最大値を示しているにすぎません。

まとめ:正規化されたデータには、正規化した人の前提・仮定が含まれている

以上で考えてきたように、正規化は、データの持つ性質を分かりやすく示すのに役立ちます。そして、正規化の方法には、データの分布について、何を仮定するのか(もしくはしないのか)が背後にあります。データの正規化という言葉からは、客観的な操作のみが連想されますが、データの見方という主観が含まれることを忘れないようにしましょう。