先生の数が減少する

ゆうき( @BASEBALLY15 )です^^

近年,大学ではデータサイエンスが必修化されつつありますよね.

そうなんですよね^^

そこで,今回は, Pythonを使って『仮説検定』を行ってみようと思います^^

統計学を勉強したことがある方は,一度は聞いたことがあるかもしれませんね^^

仮説検定とは?

科学的分析や実際の実務の上で,原因の究明,犯罪の推理などで,仮説を立ててそれを証明することを言います.

基本的に,『帰無仮説』と『対立仮説』を立てて証明を行っていきます.

例)池の魚の死亡数が急に増えた.「死亡数が増えたのは,水が古くなったからだ」と主張する人がいる.

この主張(検定)を確かめるために古い水に魚を入れると,再び,大量の魚が死んでしまうかもしれない.

そこで,以下のように『帰無仮説』と『対立仮説』を立てる.

  • 帰無仮説・・・魚の死亡数は水の古さとは関係ない.
  • 対立仮説・・・魚の死亡数は水が古くなったからだ.

仮にきれいな水の池で,魚が健康的な場合,『帰無仮説』は間違っていると言える.

つまり,『対立仮説』が成立するのである.

このような流れで,仮説検定を行います.

Pythonを使って仮説検定を行ってみよう

今回は,

『平成から令和にかけて,先生の数が減少しているのは偶然なのかどうか』

ということについて,仮説検定を行っていきたいと思います.

その中でも,小学校(primary school)について,仮説検定を行っていきます.

使ったデータ

今回は,『e-Start-政府統計の総合窓口-』のデータを使って検定を行いました.

以下に,csvファイルにまとめたものを載せておきます.

扱いやすいように,編集しています.

ダウンロードすると,このようなデータを扱うことが出来ます.

Yearprimary schoolJunior high schoolhigh school
0昭和23年28223616928368707
12430215118272775381
22530552018200882932
32631351318118491603
427322573183900100881

それでは,コードを見ていきましょう^^

ライブラリ

import numpy as np

import pandas as pd

from pandas import Series, DataFrame

import matplotlib.pyplot as plt

import seaborn as sns

from  scipy import stats

#ノンパラメトリック検定を行うためのライブラリ
from scipy.stats import brunnermunzel

%matplotlib inline

今回扱うデータが,仮に正規分布に従っていない場合に,通常の検定方法とは異なる検定(ノンパラメトリック検定)をしないといけないので,そのためのライブラリもインポートしておきます.

ちなみに,正規性がある場合は,t検定を行います.

コード

まずは,csvファイルを読み込みます.

#csvファイルの読み込み
teachers_data = pd.read_csv("Number of teachers.csv")

#読み込んだファイルを表示
teachers_data

すると,このように,学校ごとに先生の数が表示されます.

Yearprimary schoolJunior high schoolhigh school
0昭和23年28223616928368707
12430215118272775381
22530552018200882932
32631351318118491603
427322573183900100881

今回の検定では,有意水準を5%に設定します.

(画像をクリックすると,引用元を確認できます.)
#5%
significance_level = 0.05

正規性があるのかを確かめてみよう

検定を行う上では,重要なことがあります.それは,

使いたいデータに正規性があるかどうかを確かめること

です.

正規性が認められた場合のみ,t検定を行うことが出来ます.

それでは,そのコードを見てみましょう⤵

def check(n):
    ###推移を描写###
    plt.scatter(teachers_data.index, n)

    plt.title("Changes in the number of teachers")
    
    plt.xlabel("index")
    
    plt.ylabel("Number of people")
     

    #縦の補助線を引く(x=41(平成の始めり)の所に引く)
    ymin, ymax = n.min(), n.max()
    
    plt.vlines(41, ymin, ymax, "red", linestyles="dashed")

    plt.pause(0.01)
    
    
   
    ###ヒストグラムを描写###
    plt.hist(n, bins=20, alpha=0.5, color="r")

    plt.title("Histogram of the number of teachers")

    plt.xlabel("class")

    plt.ylabel("value")

    plt.pause(0.01)
    
    
    ###QQプロットを描写###
    stats.probplot(n, dist="norm", plot=plt)

    plt.pause(0.01)

    
    ###シャピロウィルク検定(p値を求める)###
    w_value, p_value = stats.shapiro(n)

    print("\nシャピロウィルク検定の結果,P値は{}%です.\n".format(100*p_value))
    
    #もし,p値が5%以上なら
    if float(p_value) >= float(significance_level):

        print("正規性があるので,\nt検定を使います.!")

  #それ以外なら    
    else:
        print("正規性が無いので,\nノンパラメトリック検定を行います.")
        

仮に正規性がある場合は,t検定を使うので,以下のように関数を作っておきます.

### t検定用 ###
def t_test(name):

    a = teachers_data[teachers_data.index<41][name]

    b = teachers_data[teachers_data.index>=41][name]
    
    # t検定を行う
    statistic, p_value = stats.ttest_ind(a, b, equal_var=False)
    
  #もし,p値が5%よりも低いなら, 
    if float(p_value) <= float(significance_level): 

        print("t検定の結果,P値は{}%です.".format(100*p_value))

        print("よって,平成から『有意に減少した』と言える.")

  #それ以外なら,
    else:
        print("t検定の結果,P値は{}%です.".format(100*p_value))

        print("よって,平成から減少したのは偶然だ!")

次に,正規性が認められなかった場合にノンパラメトリック検定を行う必要があるので,

以下のように関数を用意しておきます.

###ノンパラメトリック検定用(Brunner-Munzel検定を行う)###
def nonparametric_test(name):

    a = teachers_data[teachers_data.index<41][name]

    b = teachers_data[teachers_data.index>=41][name]
    
    #ノンパラメトリック検定を行う
    statistic, p_value = brunnermunzel(a, b)
    
  #もしも,p値が5%よりも低いなら,
    if float(p_value) <= float(significance_level): 

        print("ノンパラメトリック検定の結果,P値は{}%です.".format(100*p_value))

        print("よって,平成から『有意に減少した』と言える.")

    #それ以外なら,
    else:
        print("ノンパラメトリック検定の結果,P値は{}%です.".format(100*p_value))

        print("よって,平成から減少したのは偶然だ!")

このように,関数を作っておくことで,学校ごとに仮説検定を行う際に,短いコードで済みます.

仮説検定の結果

上で作ったcheck()関数を呼び出す
check(teachers_data["primary school"])

このコードを記述すると,いかのように3つのグラフと仮説検定の結果が表示されます.

仮説検定の推移
仮説検定のヒストグラム
仮説検定のQQプロット

シャピロウィルク検定の結果,P値は0.13290387578308582%です.

正規性が無いので, ノンパラメトリック検定を行います.

どうやら,正規性が無いようなので,ノンパラメトリック検定を行います.

上で準備したnonparametric_test()関数を呼び出します.

nonparametric_test("primary school")

ノンパラメトリック検定の結果,P値は1.0727432506323797%です.

よって,平成から『有意に減少した』と言える.

ノンパラメトリック検定を行った結果,

『平成から令和にかけて,先生の数が減少しているのは偶然ではない』

ということが分かりました.

終わりに

今回は,先生の数の減少について仮説検定を行いました.

検定は,大学などで研究を行う際に重要な要素なので,

このブログを参考に,みなさんも勉強してみてください^^

それでは・・・

Q &A

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA