第6章 データのばらつき
1 データの分布
再び、seiseki.ipynb に戻り、各データのばらつきについて見てみます。 理科のようにデータのばらつきが大きいデータもあれば、算数のようにデータのばらつきが比較的少ないものもあります。
これを分かりやすく表示するにはグラフが一番です。 ヒストグラムを使います。ヒストグラムは範囲を区切って、その範囲に何件のデータがあるかを表すものです。「算数」のヒストグラムを表示してみます。
import seaborn as sns
sns.set_theme(font=["Meiryo"])
df.plot.hist(y="算数",bins=5)
df.plot.hist関数でヒストグラムを表示します。binsはいくつの範囲に分けて表示するかを指定します。
理科も表示してみます。
df.plot.hist(y="理科",bins=5)
理科の方がばらつきが多くなっていることが分かります。
箱ひげ図ではより違いが分かりやすいです。
df[["算数","理科"]].plot.box()
箱ひげ図の箱は中央の線が中央値を表します。そこから25%~75%のデータが入るのが箱です。箱の外の一番上の横線が最大値、下の横線が最小値を示します。これを見ると算数に比べ理科が大きくばらついていることが分かります。
この25%の線を第一四分位点、75%の線を第三四分位点といいます。第二四分位点は中央値と同じです。
25% 第一四分位点
50% 第二四分位点(中央値)
75% 第三四分位点
四分位点をpythonで求めるにはquantileを使います(基本統計量を表示する df.describe() でも分かります)。
# 第一四分位点
df["算数"].quantile(0.25)
問題
kdg.ipynb で男性と女性の箱ひげ図を表示しよう。
2 外れ値
大きく外れた値があると、データの平均値がかなり左右されます。
例えば成績のデータでは様々な事情で点数が極端に低い人がいた場合、それを計算に含めると平均点が大きく下がります。これを含めると授業全体の習熟度が評価できません。
さまざまな調査を行った際にはノイズや一時的な現象などでこのような大きく外れた値が存在することがあります。このような値を「外れ値」といい、対象から外したり、適切な値に補正するなどの処理をする必要があります。
外れ値の定義はさまざまですが、箱ひげ図でも使用する四分位範囲を使った方法がよく使われます。
箱ひげ図の箱の大きさの1.5倍以上、箱から離れているものを外れ値と見なします。
箱の大きさ=第三四分位点-第一四分位点
箱の下辺=第一四分位点
箱の上辺=第三四分位点
# 第一四分位点
q1= df["国語"].quantile(0.25)
# 第三四分位点
q3= df["国語"].quantile(0.75)
# 箱の範囲
hako = q3 - q1
# 下限
min = q1 - hako * 1.5
print('これより下は外れ値', min)
# 上限
max = q3 + hako * 1.5
print('これより上は外れ値', max)
国語の外れ値(下限以下)を抽出してみます。
# 下限以下
df[df["国語"]<= min]
3 標準偏差
算数と理科ではデータのばらつき方が大きく違いました。 このようなデータのばらつきを数値で表すのが分散です。 分散は各データの平均との差を2乗したものの平均です。
df.var(numeric_only=True)
以下のようになり、理科のばらつきが大きいことが分かります。
国語 270.132353
算数 55.492647
理科 601.750000
社会 67.816176
ただこの値は、データと平均の差を2乗しているので、単位は点とは言えません。これを元の単位とするため、ルートを取ります。これが標準偏差です。
df.std(numeric_only=True)
国語 16.435704
算数 7.449339
理科 24.530593
社会 8.235058
つまり、算数は平均点と約7.4点の幅でばらつきがあることがわかります。
4 正規分布
標準偏差は正規分布と組み合わせるとデータの正常・異常が分かります。正規分布とは平均が最も多く、そこから次第に減っていく分布です。一般的な事象は(特にデータ量が多ければ)正規分布に従うことが多いです。
例えば、たくさんの人の身長を調べると正規分布になるでしょう。 今回のデータでは算数が正規分布に近い分布をしています。
df.plot.hist(y="算数",bins=10)
正規分布の場合、平均から標準偏差内に全データの約68%が収まることが分かっています。
例えば算数の平均は 68.6点で、標準偏差は7.4 です。ということは61.2点~76.0 点の範囲に全データの約68%があることになります。 実際に範囲内にどれだけのデータが入っているかを確認してみます。
heikin = df["算数"].mean()
std = df["算数"].std()
min = heikin - std
max = heikin + std
dfs = df[(df["算数"] >= min) & (df["算数"] <= max)]
len(dfs)/len(df)
実際には70.5%で理論値にほぼ近いことが分かります。
また、理論値では平均から標準偏差の2倍の範囲に95.4%のデータが収まります。
例えば算数の平均は 68.6点で、標準偏差は7.4 で2倍は14.8です。ということは53.8点~83.4点の範囲に全データの約95.4%があることになります。
算数のデータでは全データがこの範囲に収まりました。
このように、正規分布を前提とした場合、標準偏差が分かればそのデータが普通なのか、それとも大きく外れたデータなのかが分かるのです。
5 正規分布の計算
scipyライブラリのnormモジュールのcdf関数を使うとそれが下から何%の範囲かを得ることが出来ます。
from scipy.stats import norm
cdf = norm.cdf(x=値, loc=平均値, scale=標準偏差)
算数の80点が下位から何%かを計算してみます。
from scipy.stats import norm
heikin = df["算数"].mean()
std = df["算数"].std()
cdf = norm.cdf(x=80, loc=heikin, scale=std)
cdf
91.79・・・% です。 1-cdf とすれば上から何%かがわかります。
normモジュールのppf関数を使うと、逆に下位から何%の地点がいくつの値かが分かります。
norm.ppf(q=パーセント, loc=平均値, scale=標準偏差)
算数で下位から90%の地点が何点かを計算します。
norm.ppf(q=0.9, loc=heikin, scale=std)
79.15・・点であることがわかります。