結論
pingouin なら 1 行で簡単に多変量正規性検定ができます。
import pingouin as pg
pg.multivariate_normality(data, alpha=0.5)
問題
python で統計解析を行いたいとき、SciPy を使うのがメジャーだと思います。
最初にデータが正規分布に従うかどうかを見ることが多いかと思いますが、SciPy ではシャピロウィルク[1, 2]がよく使われます。
from scipy.stats import shapiro
shapiro(data)
この方法ですと使えるデータは 1 つであり、2 群以上を見たいときは、各群を中心化し、その和で正規性検定を行う必要があります[3]。
中心化とは、各データから平均値を引くことで残差を求め、中心(平均)を 0 にすることを指します。
import numpy as np
from scipy.stats import shapiro
# データを 2 つ用意
x = np.random.normal(2, 2, 100)
y = np.random.normal(5, 10, 100)
# 平均値
mean_x = np.mean(x)
mean_y = np.mean(y)
# 中心化
centering_x = x - mean_x
centering_y = y - mean_y
centering = np.array([centering_x, centering_y])
shapiro(centering)
中心化を行うことで、データの分布は以下の様に(青→赤)変化します。
pingouin
以上の問題に対し、pingouin ですと、Henze-Zirkler test[4] で 1 行で多変量の正規性を検定することができます[5]。
import pingouin as pd
pg.multivariate_normality(data)
試しに、Kaggle のタイタニックデータを使って見てみましょう。
import pandas as pd
import pingouin as pg
# データ読み込み
df = pd.read_csv("./titanic.csv")
# Survived と Fare 変数
data = {"Survived": df.iloc[:, 1], "Fare": df.iloc[:, 9]}
data = pd.DataFrame(data)
# パラメトリック検定
pg.multivariate_normality(data, alpha=0.5)
このように、統計量(hz)、P 値(pval)、パラメトリックかどうか(normal)で返ってくるため、3 番目の返り値のみを使って条件分岐なども簡単に作ることもできます。
今後
今回は pingouin で多変量正規性検定の方法を見ました!
pingouin は優秀な統計ライブラリですが、まだ歴史が浅く、意外と日本語記事が少ないため、今後もいくつか取り扱っていく予定です。
修正
2023/10/15 初歩的なミス(用語の誤り、multivariate_normality の理解)がありましたので、修正しました。ご指摘いただきありがとうございました。
2023/10/17 Shapiro の中心化の話を追加しました。また、コードに一部誤りがあったため、修正しました。
2023/10/24 中心化について一部修正しました。
参考文献
[1]https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.shapiro.html
[2]https://python-man.club/nonpara_para_test/
[3]https://biolab.sakura.ne.jp/normality-for-t-test.html
[4]Henze, N., & Zirkler, B. (1990). A class of invariant consistent tests for multivariate normality. Communications in Statistics-Theory and Methods, 19(10), 3595-3617.
[5]https://pingouin-stats.org/build/html/generated/pingouin.multivariate_normality.html#pingouin.multivariate_normality