見出し画像

#12 Pythonで始めるF検定 *バラツキを検定する

カイゼンによる成果;前後の測定値のバラツキには差があるのでしょうか? 目に見える平均値の変化だけでなく、「データの散らばり具合」にも注目することで、改善の効果をより深く理解できるかもしれません。

今回のテーマは「F検定」です。

t検定と同様、統計ソフトはもちろんのこと、エクセルでも検定は可能ですが、ここでは、比べる数値を入力すれば判断できる利点からアプリを作成します。


それでは、スタートです。
*執筆者は以下を参照してください。


使ったツール・準備したこと

  • Visual Studio Code環境下でのPython

やってみたこと|コード・ステップ紹介

実行した内容の簡単な流れ

ChatGPT 4oへのプロンプト;

t検定アプリと同様にF検定アプリを生成してください。その中には、正規性の検定も含めてください。F検定の出力は、正規分布の場合、そうでない場合の検定の両方のp値を表示してください。

試しに検定してみると・・・

t検定の際と同様に、データが正規分布か否かの検定も入れています(Shapiro-Wilk検定)。また、正規分布でない場合のデータも想定したバラツキの検定も入れています。それぞれp値が計算されていることがわかります。*今回の場合は、有意性は認められませんでした。

*正規分布ではない場合Levene検定を参照する。

今後の展開・アイデア

次回取り組みたいこと

・Feloを触ってみます。

■ 今日のコード

import tkinter as tk
from tkinter import messagebox
import re
from scipy import stats
import numpy as np

def run_f_test():
    try:
        raw_data1 = entry_data1.get("1.0", tk.END)
        raw_data2 = entry_data2.get("1.0", tk.END)

        cleaned_data1 = re.sub(r"[\s\n\t]+", ",", raw_data1.strip())
        cleaned_data2 = re.sub(r"[\s\n\t]+", ",", raw_data2.strip())

        data1 = [float(x) for x in cleaned_data1.split(',') if x.strip() != '']
        data2 = [float(x) for x in cleaned_data2.split(',') if x.strip() != '']

        if len(data1) < 2 or len(data2) < 2:
            messagebox.showerror("エラー", "両方の群に2点以上のデータを入力してください。")
            return
        if len(data1) > 30 or len(data2) > 30:
            messagebox.showerror("エラー", "各群のデータは最大30点までです。")
            return

        # 正規性検定(Shapiro-Wilk)
        p_norm1 = stats.shapiro(data1).pvalue
        p_norm2 = stats.shapiro(data2).pvalue

        norm_text = f"正規性p値(群1): {p_norm1:.3f}\n正規性p値(群2): {p_norm2:.3f}"

        # F検定(分散の比)
        var1 = np.var(data1, ddof=1)
        var2 = np.var(data2, ddof=1)
        f = var1 / var2 if var1 > var2 else var2 / var1
        dfn = len(data1) - 1 if var1 > var2 else len(data2) - 1
        dfd = len(data2) - 1 if var1 > var2 else len(data1) - 1
        p_f = 1 - stats.f.cdf(f, dfn, dfd)

        # 非正規分布でも使えるLevene検定
        _, p_levene = stats.levene(data1, data2)

        result_text = f"F検定p値(正規性前提): {p_f:.3f}\nLevene検定p値(非正規対応): {p_levene:.3f}"

        label_result.config(text=f"{norm_text}\n\n{result_text}")

    except ValueError:
        messagebox.showerror("入力エラー", "数値を正しく入力してください。")

root = tk.Tk()
root.title("F検定アプリ(正規性検定付き)")
root.geometry("500x550")

# データ入力欄1
tk.Label(root, text="群1のデータ(エクセルの列を貼り付け可能、最大30点):").pack()
entry_data1 = tk.Text(root, height=5, width=50)
entry_data1.pack()

# データ入力欄2
tk.Label(root, text="群2のデータ(エクセルの列を貼り付け可能、最大30点):").pack()
entry_data2 = tk.Text(root, height=5, width=50)
entry_data2.pack()

# 計算ボタン
btn_calc = tk.Button(root, text="F検定を実行", command=run_f_test)
btn_calc.pack(pady=10)

# 結果表示
label_result = tk.Label(root, text="", justify="left")
label_result.pack()

root.mainloop()

いいなと思ったら応援しよう!