カテゴリー
【シェルスクリプトで機械学習】Awkで機械学習で使える高速データ処理〜ガウス分布ノイズの生成方法
※ 当ページには【広告/PR】を含む場合があります。
2020/12/08
2022/09/30
はじめに
np.arange
numpy
scipy
Awkで使える基礎的な数学関数
関数名 | 備考 |
---|---|
int(x) | 整数への丸めを行う関数。四捨五入ではないので注意 |
sqrt(x) | xの正の平方根を返す。 |
exp(x) | 自然対数eのx乗を返す。xが範囲外であればエラー |
log(x) | xが正の場合にはxの自然対数を返す。xが範囲外であればエラー |
sin(x) | xの正弦を返す。xの単位はラジアンに注意 |
cos(x) | xの余弦を返す。xの単位はラジアンに注意 |
atan2(y, x) | y/xのアークタンジェントを返す。返り値はラジアン |
rand() | 0から1の範囲の乱数を返す。ただし0と1は含まれない |
srand(x) | シード値xから乱数を生成して返す。同一のシード値からは同一の乱数が返ることに注意 |
$ awk -v seed="${RANDOM}" '
function roll(n) { return 1 + int(rand() * n) }
BEGIN{
srand(seed);
print(roll(6))
}
'
#実行する度に違う目が出る
5
srand(seed)
等間隔の配列を作成する
np.arange
$ awk '
#start(下限)とstop(上限)の範囲をstep間隔に刻んだ配列を返す
function arange(start, stop, step) {
count = 0;
x = start;
while (x <= stop) {
varr[count] = x;
count++;
x = x + step;
}
}
BEGIN {
#例として0から6までを0.5間隔で刻んだ配列を計算
arange(0, 6, 0.5);
arr_len = length(varr);
for (i = 0; i < arr_len; i++) {
print i, varr[i];
}
}
'
#👇実行後
0 0
1 0.5
2 1
3 1.5
4 2
5 2.5
6 3
7 3.5
8 4
9 4.5
10 5
11 5.5
12 6
正規分布関数
Eq. (1)
$ awk '
#start(下限)とstop(上限)の範囲をstep間隔に刻んだ配列を返す
function gauss(val, mu, sigma) {
PI = 3.14159265359; #👈円周率は適当な精度で...
a_part = 1.0 / sqrt(2.0 * PI * sigma^2);
b_part = -1.0 * (val - mu)^2 / (2 * sigma^2);
return a_part * exp(b_part)
}
BEGIN {
print gauss(0, 0, 1)
}
'
#👇実行後
0.398942
正規分布に基づく乱数(正規乱数)の生成
$ awk -v seed="${RANDOM}" '
function box_muller(mu, sigma, arr_len_) {
PI = 3.14159265359; #👈円周率は適当な精度で...
count = 0;
while(count < arr_len_) {
x1 = rand();
x2 = rand();
#👇cosかsinかどちらかを選択
tmp_rand_val = sqrt(-2 * log(x1)) * cos(2 * PI * x2);
# tmp_rand_val = sqrt(-2 * log(x1)) * sin(2 * PI * x2);
gauss_arr[count] = mu + sigma*tmp_rand_val;
count++;
}
}
BEGIN{
#👇シード値をリセット(Awkの場合には重要)
srand(seed);
#標準正規分布N(0,1)に従う乱数10点の配列を計算
box_muller(0, 1, 10);
arr_len = length(gauss_arr);
for (i = 0; i < arr_len; i++) {
print i, gauss_arr[i];
}
}
'
#実行
0 1.28016
1 -0.435245
2 -0.962477
3 -1.56287
4 0.710585
5 -0.512278
6 0.4468
7 -1.43556
8 0.0096908
9 1.02674
ガウス分布ノイズの検証
$ awk -v inp_mu=0.0 -v inp_sigma=1.0 '
function arange(start, stop, step) {
count = 0;
x = start;
while (x <= stop) {
varr[count] = x;
count++;
x = x + step;
}
}
function gauss(val, mu, sigma) {
PI = 3.14159265359;
a_part = 1.0 / sqrt(2.0 * PI * sigma^2);
b_part = -1.0 * (val - mu)^2 / (2 * sigma^2);
return a_part * exp(b_part)
}
BEGIN {
OFS=","
arange(-4, 4, 0.1);
arr_len = length(varr);
for (i = 0; i < arr_len; i++) {
print i, varr[i], gauss(varr[i], inp_mu, inp_sigma);
}
}
' | awk -F "," '
BEGIN {
OFS=",";
count = 0;
}
{
xarr[count] = $2;
yarr[count] = $3;
if(ymax<$3) ymax=$3;
count++;
}
END {
xarr_len = length(xarr);
for (i = 0; i < xarr_len; i++) {
print i, xarr[i], yarr[i] / ymax
}
}
' > norm_dist_strict.csv
$ awk -v seed="${RANDOM}" -v iter=1000000 -v inp_mu=0.0 -v inp_sigma=1.0 '
function box_muller(mu, sigma, arr_len_) {
PI = 3.14159265359;
count = 0;
while(count < arr_len_) {
x1 = rand();
x2 = rand();
tmp_rand_val = sqrt(-2 * log(x1)) * cos(2 * PI * x2);
gauss_arr[count] = mu + sigma * tmp_rand_val;
count++;
}
}
BEGIN{
srand(seed); #シード値をリセット
box_muller(inp_mu, inp_sigma, iter);
arr_len = length(gauss_arr);
for (i = 0; i < arr_len; i++) {
print gauss_arr[i];
}
}
' | awk -v binsize=0.2 '
BEGIN {
OFS=","
}
{
if(binsize <= 0) exit
if($1 < 0) {
frequency[int($1 / binsize) - 1] ++;
} else {
frequency[int($1 / binsize)] ++;
}
}
END {
for(i in frequency) {
print (i + 0.5) * binsize, frequency[i] | "sort -n";
}
}
' | awk -F "," '
BEGIN {
OFS=",";
count = 0;
}
{
xarr[count] = $1;
yarr[count] = $2;
if(ymax<$2) ymax=$2;
count++;
}
END {
xarr_len = length(xarr);
for (i = 0; i < xarr_len; i++) {
print i, xarr[i], yarr[i] / ymax
}
}
' > norm_dist_exp.csv
まとめ
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー