Pythonプログラミング(ステップ7・リスト・基本的な代表値の計算)
このページでは、基本的な代表値や散布度を計算するアルゴリズムをまとめておく。
以下では、$N$件のデータが配列(リスト)で $$ X = [x_0, x_1, \cdots, x_{N-1}] $$ のように与えられている場合を想定する。添字は0から始まり、$N-1$が末尾。
Pythonコードに翻訳する際には、変数名はわかりやすいものに適宜変更すること(例: $\mu$はmu
など)
アルゴリズムの学習のため、なるべく小さなステップに分解して記述したが、Pythonに標準的に内蔵されている機能を使うことで、 基本的な統計量は簡単に求めることができる。そのやり方については、左側の欄に付記した。 また、リスト(配列)操作については、こちらのページも併せて参照のこと。
平均
PythonのリストX
の要素数は
N=len(X)
で得られる。また、X
の総和は、シンプルに
s=sum(X)
で得られる。
平均は最も基本的な代表値である。「総和」のアルゴリズムで総和を求め、それをデータ件数で割ればよい。
平均を求めるアルゴリズム
Input: 配列 $X$
Output: 平均値 $\mu$
1: $N \leftarrow$ データ件数
2: $s \leftarrow 0$
3: $i$ を0から、$N$未満まで、1ずつ増やしながら、5:までを繰り返す:
4: $s \leftarrow s + x_i$
5: 反復ここまで
6: $\mu \leftarrow s / N$
7: $\mu$を出力
最大値・最小値
PythonのリストX
の要素の最大値は
max(X)
で、最小値は
min(X)
で得られる。
最大値・最小値求めるアルゴリズム
Input: 配列 $X$
Output: 最小値 $min$, 最大値 $max$
01: $N \leftarrow$ データ件数
02: $min \leftarrow x_0$
03: $max \leftarrow x_0$
04: $i$ を1から、$N$未満まで、1ずつ増やしながら、9:までを繰り返す:
05: もし $x_i \lt min$ ならば:
06: $min \leftarrow x_i$
07: もし $x_i \gt max$ ならば:
08: $max \leftarrow x_i$
09: 反復ここまで
10: $min$, $max$を出力する
中央値(メジアン)
Pythonで整数の除算は //
を用いる。
リストX
を昇順に並べ替えるには
X.sort()
でよい。降順は
X.sort(reverse=True)
statistics
モジュールを使うことで、リストX
のメジアンは
import statistics ... med=statistics.median(X)
で得られる。
データをまず整列し、データの件数が奇数の場合は、$N/2$番目の要素。 件数が偶数の場合は中央の2つの平均。 アルゴリズム中で、除算 $/$ は整数の除算であることに注意(例:$7/2$は3)。
メジアンを求めるアルゴリズム
Input: 配列 $X$
Output: メジアン $m$
1: $N \leftarrow$ データ件数
2: $X$の要素を小さい順に並べ替える
3: もし $N$ が奇数ならば:
4: $m \leftarrow x_{N/2}$
5: そうでなければ:
6: $m \leftarrow \frac{x_{(N/2)-1} + x_{N/2}}{2}$
7: $m$を出力
四分位数
まずメジアンを求め、第2四分位数とする。 次に、メジアンより小さい (メジアンは含まない)データと、メジアンより大きい(メジアンは含まない)データそれぞれについてのメジアンを求め、第1、第3四分位数とする。
四分位数を求めるアルゴリズム
Input: 配列 $X$
Output: 第1, 第2, 第3四分位数 $q_1, q_2, q_3$
01: $N \leftarrow$ データ件数
02: $X$の要素を小さい順に並べ替える
03: もし $N$ が奇数ならば:
04: $q_2 \leftarrow x_{N/2}$
05: $q_1 \leftarrow$ ( $x_0,\cdots,x_{(N/2)-1}$のメジアン)
06: $q_3 \leftarrow$ ( $x_{(N/2)+1},\cdots,x_{N-1}$のメジアン)
07: そうでなければ:
08: $q_2 \leftarrow \frac{x_{(N/2)-1} + x_{N/2}}{2}$
09: $q_1 \leftarrow$ ( $x_0,\cdots,x_{(N/2)-1}$のメジアン)
10: $q_3 \leftarrow$ ( $x_{N/2},\cdots,x_{N-1}$のメジアン)
11: $q_1, q_2, q_3$を出力
最頻値(モード)
statistics
モジュールを使うことで、リストX
のモードは
import statistics ... mod=statistics.mode(X)
で得られる。
以下のアルゴリズムでは、まず配列を昇順並べ替え、連続して同じ値が出現する回数をカウントしながら、出現回数が最大の値を求めている。
モードを求めるアルゴリズム
Input: 配列 $X$
Output: モード $m$
01: $N \leftarrow$ データ件数
02: $X$の要素を小さい順に並べ替える
03: $c \leftarrow 0$, $c_{max} \leftarrow x_0$
04: $i$ を1から、$N$未満まで、1ずつ増やしながら、11:までを繰り返す:
05: もし $x_{i-1} = x_i$ ならば:
06: $c \leftarrow c + 1$
07: そうでなければ:
08: もし $c \gt c_{max}$ ならば:
09: $c_{max} \leftarrow c$
10: $mode \leftarrow x_{i-1}$
11: 繰り返しここまで
12: $mode$を出力
標本分散
statistics
モジュールを使うことで、リストX
の標本分散は
import statistics ... v=statistics.variance(X)
で得られる。
分散は最も基本的な散布度である。分散の平方根が標準偏差。
分散を求めるアルゴリズム
Input: 配列 $X$
Output: 分散 $v$
01: $N \leftarrow$ データ件数
02: $s \leftarrow 0$, $q \leftarrow 0$
03: $i$ を0から、$N$未満まで、1ずつ増やしながら、6:までを繰り返す:
04: $s \leftarrow s + x_i$
05: $q \leftarrow q + {x_i}^2$
06: 反復ここまで
07: $\mu \leftarrow s / N$
08: $w \leftarrow q / N$
09: $v \leftarrow w - \mu^2$
10: $v$を出力
リストの要素それぞれに、ある演算を施したいケースはよくある。
例えば、リストX
の二乗和は、要素をそれぞれ二乗したリストを作成し、そちらのリストの総和を求めればよい。
ラムダ式による無名関数と、map( )
関数を組み合わせると、これらのステップは
X2 = list( map(lambda x:x**2, X) ) sum2 = sum(X2)
と記述できる。map(関数,リスト)
は、リストの要素それぞれの関数を作用させ、新しいリスト型のオブジェクトを生成する。
そして、list( )
で、それを通常のリストに変換する。
lambda:変数名:式
は、変数をコロン(:)の右側に記述した式に変換するような「無名関数」。
この記法を用いると、例えば、リストX
の不偏分散は
N=len(X) mu=sum(X)/N u2 = sum(map(lambda x:(x-mu)**2, X))/(N-1)
で求められる。