正規分布に従う乱数を求める

正規分布に従う乱数をPerlで求めてみましょう。重みのパラメーターの初期値として、Xavierの初期値Heの初期値がありますが、この二つは、どちらも正規分布に従う乱数です。

正規分布は中心が高く、右と左に行けば行くほど、低くなるような分布です。左右は対象でなめらかなグラフです。(x, y)座標でひとつの正規分布を表現すると以下のようになります。

(-4, 0.00001)
(-3, 0.001)
(-2, 0.05)
(-1, 0.2)
(0, 0.4)
(1, 0.2)
(2, 0.05)
(3, 0.001)
(4, 0.00001)

正規分布は、平均と標準偏差を指定すると形が決まります。

平均は、最も高いy座標におけるx座標に一致します。上の例の場合は0です。標準偏差と呼ばれる値が小さいほど、とがった形になります。

正規分布に従う乱数とは、その名のとおりです。中心付近の値が登場する確率が高くなります。randnの計算式については、計算方法の内容は私にはよくわかっておりません。

use strict;
use warnings;

# 正規分布に従う乱数を求める関数
# $ave は平均, $sigma は標準偏差、
sub randn {
  my ($ave, $sigma) = @_;
  my ($r1, $r2) = (rand(), rand());
  while ($r1 == 0) { $r1 = rand(); }
  return ($sigma * sqrt(-2 * log($r1)) * sin(2 * 3.14159265359 * $r2)) + $ave;
}

my $ave = 0;
my $sigma = 1;

# 正規分布に従う乱数を発生させる
for (0 .. 100) {
  my $randn = randn($ave, $sigma);
  print "$randn\n";
}

出力結果のサンプルです。

-0.312900844794695
0.368516508387452
0.588564026974205
-0.832093759572302
-0.373563467435626
0.128322638304041
-0.228427968297216
-0.245046689515676
0.315406051382644
0.658932693772217
0.569456859322423
1.49604255431358
-0.563332708600982
-0.130983698272141
-0.65316083654429
2.21759497277892
-1.13077911035109
0.416355154057237
-0.992338158849582
-0.0415533205367665
-0.139471145014137
-0.555637591105884
0.0610479864678622
-1.83754633603067
-0.355777559590925
-0.733515417984692
-0.586761757878687
-2.56732797838226
-0.0958678885297631
0.610464417758399
-0.400757637198111
2.16917680131624
0.304382226761163
-0.706898412159972
-0.0105635240353556
1.18621562931325
-0.806053955712314
0.0788339133990966
-0.0878677608626948
0.0499876673082178
-0.91469235675378
-0.583570118757101
1.75119496540262
0.717132303416223
-2.33651905151149
0.601256117559849
-0.160805082740475
-1.69726845564479
2.12940182097853
0.165837725238895
-0.255632364287032
-0.163546251052526
-1.33104254345012
0.227482582090221
-0.0967166218513033
-1.32755710603693
0.316919938301281
-0.0212234397436275
0.725093722651192
1.68315876861612
1.74955853858043
0.0842186232602491
-0.145906364613128
1.47917785353059
-0.511611505685728
-0.210334896278017
0.672454440669521
1.64492760302033
1.37283258241519
0.79094523781063
-0.283363372457433
1.18971415501877
0.387045143982198
-0.623982153431303
0.469061730743257
-0.683712125388351
-0.836530854874499
0.638136701054174
0.231606572497369
1.45980005894014
1.06610004144032
0.297129643450955
1.59304995448786
0.979957182081171
1.22931022126118
-0.027647841530499
2.02384036594018
-0.458393546179776
-0.399941978668047
2.01279648101146
1.1528225003866
-1.5332801324075
-1.20378561557291
0.459610546599193
0.570946364435492
0.987438393052072
1.74715213041814
0.0301710690716359
0.456481012707392
-0.713494905933569
-1.10745100942014
Perlテキスト処理のエッセンス
  • 初級者向け・テキスト処理と正規表現の基本をマスター
業務に役立つPerl
  • 実務者向け・ログ解析など日本語を含むテキスト処理の実践!
Perlクラブ
  • 仲間と出会い
    ゆとりあるエンジニアライフを送る