Help us understand the problem. What is going on with this article?

[Python]一元配置分散分析を自動化した

More than 1 year has passed since last update.

背景

研究の一環で,一元配置分散分析を行う必要が出た.

最初はそのままF検定をしていたが,正規性を仮定できないことがわかりKruskal-Wallis検定で書き直したのだが,プログラムを書いてる途中

「自動化(パラメトリックかノンパラメトリックかを引数から指定して実行できるように)したい」

と思ったため,F検定とKruskal-Wallis検定を自動で判別して行う関数を作ることにした.(もちろん,正規性を仮定した場合の検定も行うように引数を設定した)

ソースコード

ということで作った.F値とp値と有意差の有無を返す.scipyが必要.

Auto_ANOVA.py
import scipy.stats as stats

#パラメトリック,ノンパラメトリックな一元配置分散分析を行う関数Auto_ANOVA
def Auto_ANOVA(*data, param = None, message = True, bart_alpha = 0.05, alpha = 0.05):

    #入力引数
    #*data      : 分析を行うデータ(2つ以上)
    #
    #param      : 正規性の仮定(ブールで設定.Default = None)
    #      True  -> F検定
    #      False -> Kruskal-Wallis検定
    #      None  -> Bartlett検定によりF検定あるいはKruskal-Wallis検定を判断(メッセージを表示)
    #
    #message    : メッセージの表示(ブールで設定.Default = True)
    #        True  -> 正規性の仮定とBartlett検定の結果が合致しない場合にメッセージを表示.
    #        False -> 分布の仮定にしたがった検定結果のみを出力
    #
    #bart_alpha : Bartlett検定(複数群の分布の正規性を検定)の有意水準.Default = 0.05
    #
    #alpha      : ANOVAの有意水準.Default = 0.05

    #データが2群未満の場合
    if len(data) < 2:
        #エラーを返して終了
        raise ValueError('need at least two array to calculate')
    else:
        #正規性を仮定する場合
        if param == True:
            #メッセージの表示がTrueのとき
            if message == True:
                #Bartlett検定の結果が仮定に沿わない場合
                if stats.bartlett(*data).pvalue < bart_alpha:
                    #メッセージの表示
                    print('Warning : Bartlett test returned a significant difference.')
                    print('          Please consider to practice non-parametric ANOVA.')

            #F検定を行う
            f, p = stats.f_oneway(*data)

        #正規性を仮定しない場合
        elif param == False:
            #メッセージの表示がTrueのとき
            if message == True:
                #Bartlett検定の結果が仮定に沿わない場合
                if stats.bartlett(*data).pvalue >= bart_alpha:
                    #メッセージの表示
                    print('Warning : Bartlett test did not return a significant difference.')
                    print('          Please consider to practice parametric ANOVA.')

            #Kruskal-Wallis検定を行う
            f, p = stats.kruskal(*data)

        #Noneのとき
        else:
            #正規性仮説が棄却される場合
            if stats.bartlett(*data).pvalue < bart_alpha:
                #メッセージを表示
                print('Message : Bartlett test returned a significant difference.')
                print('          This function practices non-parametric ANOVA.')

                #Kruskal-Wallis検定
                f, p = stats.kruskal(*data)

            #正規性仮説が採択される場合
            else:
                #メッセージを表示
                print('Message : Bartlett test did not return a significant difference.')
                print('          This function practices parametric ANOVA.')

                #F検定
                f, p = stats.f_oneway(*data)

        #有意差の有無(ブール)
        significance = (p < alpha)

        #出力引数
        #f          : F値
        #p          : p値
        #significance : 有意差の有無
        return f, p, significance

実行例

クラウドディレクトリが表示されているので一部の表示は省略します.

データが1群しかないとき

In[11]:Auto_ANOVA(data['A'])
Traceback (most recent call last):

ValueError: need at least two array to calculate

正規性仮説が棄却されるデータ群で正規性を仮定したとき

In [12]: Auto_ANOVA(data['A'], data['B'], data['C'], param = True)
Warning : Bartlett test returned a significant difference.
          Please consider to practice non-parametric ANOVA.
Out[12]: (82.66483050065293, 1.4223527656560074e-17, True)

正規性仮説を採択されるデータ群で正規性を仮定しないとき

In [16]: Auto_ANOVA(a, b, c, param = False)
Warning : Bartlett test did not return a significant difference.
          Please consider to practice parametric ANOVA.
Out[16]: (5.113453820598124, 0.07755818033256319, False)

正規性仮説が棄却されるデータ群で正規性を仮定しないとき

In [17]: Auto_ANOVA(data['A'], data['B'], data['C'], param = False)
Out[17]: (44.28108457517796, 2.423732342504476e-10, True)

正規性仮説を採択されるデータ群で正規性を仮定したとき

In [18]: Auto_ANOVA(a, b, c, param = True)
Out[18]: (1.7262842891039714, 0.17972497466220155, False)

正規性仮説が棄却されるデータ群で正規性の仮定を設定しないとき

In [19]: Auto_ANOVA(data['A'], data['B'], data['C'])
Message : Bartlett test returned a significant difference.
          This function practices non-parametric ANOVA.
Out[19]: (44.28108457517796, 2.423732342504476e-10, True)

正規性仮説が採択されるデータ群で正規性の仮定を設定しないとき

In [20]: Auto_ANOVA(a, b, c)
Message : Bartlett test did not return a significant difference.
          This function practices parametric ANOVA.
Out[20]: (1.7262842891039714, 0.17972497466220155, False)

まとめ

といった形です.本格的にxlsxデータからデータを引っ張ってPythonで統計をとったのはコレが初めてですが,Rよりもだいぶ書きやすい印象でした.データサイエンティストに愛される言語であるのもうなずけます.

Pythonは思いつきをすぐにプログラムできるので楽しく勉強できています.この勢いで思いつきをどんどん実装していきたいです.他人の役に立つかは別として.w

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away