【Python】で調和平均と絶対平均計算
目的
前回、一般的に平均として使われる算術平均に加え、○○率の平均などの計算に向いている幾何平均の定義と計算方法について勉強しました。
今回は、さらにそれ以外の平均の考え方である調和平均と絶対平均についてもコードを書きながら勉強したいと思います。
調和平均
A君とB君がいます。距離2L[km]を二人で均等に分けて走ることにし、A君がL[km]、B君もL[km]走ることにしたとします。
ただし、A君とB君の走る速さは違うものとします。
つまり、A君は時速a[km]、B君は時刻b[km]で走ります。
この時、二人の走る速さの平均はいくつになるか?
このような問題を考えるときに調和平均という考え方を使います。
が、まずは普通の平均である単純な算術平均を使った場合の計算を考えてみます。以下で計算できるかと思います。
\frac{a+b}{2}
しかし、これは正しいでしょうか・・・?
結論からいうと正しいとは言えません。
理由は別の考え方をしてみると分かります。
A君がL[km]走るのにかかる時間はL/a[h]、B君がL[km]走るのにかかる時間はL/b[h]になります。そのため、二人で2L[km]走るのにかかる時間は
\frac{L}{a}+ \frac{L}{b}
ということになります。そして、二人で走った距離の合計は2L[km]です。そのため、平均速さを計算すると以下になるはずです。
2L \div\left(\frac{L}{a}+ \frac{L}{b }\right) = \frac{1}{\frac{1}{2}(\frac{1}{a}+\frac{1}{b})}
上記からわかるように、平均速度は二人の走る速度の逆数の平均のさらに逆数をとったものになります。
このような考え方で計算された平均を調和平均と呼びます
そして、これは算術平均の計算式と異なることになります。
では両者の考え方の違いとは何でしょうか。
算術平均ではA君の速さaとB君の速さbを足して2で割っています。これは言うなれば、速さ\frac{a+b}{2}という速さのC君を新たに定義して、C君に2Lを走らせるというような考え方になります。
一方調和平均の計算はA君とB君の所要時間をそれぞれ計算し、距離÷時間という速さの基本式によって算出する考え方です。
平均速さを知りたい、という場合に上記の2つのうちどちらの考え方の答えを知りたいか、というと後者の考え方で導かれた答えのほうが自然かと思います。
これが調和平均の用途です。
では実際にpythonで計算してみます。
上記の例で、A君時速7[km]、B君時速10[km]とした際の速さの平均について、算術平均と調和平均をそれぞれ求めます。コードとしては以下のような形で記述しました。
01 02 03 04 05 | import numpy as np from scipy import stats print ( '算術平均:' ,np.mean([[ 7 , 10 ]])) #&# 31639 ;&# 34899 ;&# 24179 ;&# 22343 ;: 8.5 print ( '調和平均:' ,stats.hmean([ 7 , 10 ])) #&# 35519 ;&# 21644 ;&# 24179 ;&# 22343 ;&# 65306 ; 8.23529411764706 |
この例では算術平均より調和平均のほうが少し小さい値になりました。
絶対平均
絶対平均は単純です。算術平均のように足し算して数で割るのですが、足しこむ値に絶対値を使うのが絶対平均です。
用途としては、誤差を平均するような場合です。算術平均だと誤差の符号の正負で値が打ち消し合ってしまう場合がありますので、絶対平均を使う場合が多いかと思います。
pythonだと次のようなコードで計算できます。
01 02 03 04 05 06 07 | import numpy as np x = np.array([ - 3 , 2 , 3 , 4 , 6 , 5 , 9 , 4 ]) abs_m = abs (x).mean() m = x.mean() print ( '絶対平均:' ,abs_m) #&# 32118 ;&# 23550 ;&# 24179 ;&# 22343 ;&# 65306 ; 4.5 print ( '算術平均:' ,m)&# 12288 ;#&# 31639 ;&# 34899 ;&# 24179 ;&# 22343 ;&# 65306 ; 3.75 |
また、pythonによる計算方法として、直接的に絶対値を計算するのではなく、二乗平方根の平均値として計算することもできます。
この二乗平方根の平均値はRMSと呼ばれます。
01 02 | RMS = np.sqrt(x * x).mean() print ( 'RMS:' ,RMS)&# 12288 ;#RMS&# 65306 ; 4.5 |
I always emailed this web site post page to all my friends, because if like
to read it afterward my links will too.