統計解析パッケージPingouinを使ってみる

統計解析パッケージPingouinを使ってみる

Mediumを眺めていたらこんな記事を見かけました。


Pythonで利用できる統計解析ライブラリとしてはSciPyのstatsくらいしか知らなかったのですが、上の記事を読んでみるとPingouinがなかなか便利そうだなと感じました。

今回は実際にPingouinを使ってみた感想を述べたいと思います。
コードはGitHubにあげています。

Pingouinとは

Pingouinは統計解析パッケージの1つで、シンプルな記述であるにもかかわらず、網羅的な統計関数を利用できます。
Pythonで統計解析といえばSciPyがよく使われますが、例えばSciPyのttestだとt値とp値だけしか取得できません。
一方、Pingouinではt値とp値に加えて、自由度、効果量 (Cohenのd)、平均値の差の95%信頼区間、統計的検出力、検定のベイズ因子 (BF10)も取得できます。

Pingouinは以下のコマンドでインストールできます。

pip install pingouin

また、公式ドキュメントがまとまっているので、詳しく知りたい方はこちらをご参照ください。

Pingouinで分散分析をやってみる

PingouinでANOVA(analysis of variance:分散分析)をしてみます。
「分散」というワードが入っていますが、グループ間の平均値の差が有意なのかどうかを検証する分析手法になります。

以下はPingouinの公式ドキュメントに記載されている分析フローになります。

この分析フローに則って分析を進めていきます。

まず、以下のコマンドにより、Pingouinで利用できるデータセットの一覧を確認します。
INPUT:

import pingouin as pg
# 利用可能なデータセット一覧
pg.list_dataset()

OUTPUT:

datasetdescriptionusefulref
ancovaTeaching method with family income as covariateANCOVAwww.real-statistics.com
anovaPain threshold per hair coloranova – pairwise_tukeyMcClave and Dietrich 1991
anova2Fertilizer impact on the yield of cropsanovawww.real-statistics.com
anova2_unbalancedDiet and exercise impactanovahttp://onlinestatbook.com/2/analysis_of_variance/unequal.html
anova3Cholesterol in different groupsanovaPingouin
anova3_unbalancedCholesterol in different groupsanovaPingouin
chi2_independencePatients’ attributes and heart conditionschi2_independencehttps://archive.ics.uci.edu/ml/datasets/Heart+Disease
chi2_mcnemarResponses to 2 athlete’s foot treatmentschi2_mcnemarhttp://www.stat.purdue.edu/~tqin/system101/method/method_mcnemar_sas.htm (adapted)
circularOrientation tuning properties of three neuronscircular statisticsBerens 2009
cochranEnergy level across three daysCochranwww.real-statistics.com
cronbach_alphaQuestionnaire ratingscronbach_alphawww.real-statistics.com
cronbach_wide_missingQuestionnaire rating (binary) in wide format and with missing valuescronbach_alphawww.real-statistics.com
iccWine quality rating by 4 judgesintraclass_corrwww.real-statistics.com
mediationMediation analysislinear_regression – mediationhttps://data.library.virginia.edu/introduction-to-mediation-analysis/
mixed_anovaMemory scores in two groups at three time pointsmixed_anovaPingouin
mixed_anova_unbalancedMemory scores in three groups at four time pointsmixed_anovaPingouin
multivariateMultivariate health outcomes in drug and placebo conditionsmultivariate statisticswww.real-statistics.com
pairwise_corrBig 5 personality traitscorr – pairwise_corrDolan et al 2009
pairwise_ttestsScores at 3 time points per genderpairwise_ttestsPingouin
pairwise_ttests_missingScores at 3 time points with missing valuespairwise_ttestsPingouin
partial_corrScores at 4 time pointspartial_corrPingouin
penguinsFlipper length and boody mass for different species of penguins (Adelie – Chinstrap – Gentoo)everything!https://github.com/allisonhorst/palmerpenguins
rm_anovaHostility towards insectrm_anova – mixed_anovaRyan et al 2013
rm_anova_wideScores at 4 time pointsrm_anovaPingouin
rm_anova2Performance of employees at two time points and three areasrm_anova2www.real-statistics.com
rm_corrRepeated measurements of pH and PaCO2rm_corrBland et Altmann 1995
rm_missingMissing values in long-format repeated measures dataframerm_anova – rm_anova2Pingouin
tipsOne waiter recorded information about each tip he received over a period of a few months working in one restaurantregressionhttps://vincentarelbundock.github.io/Rdatasets/doc/reshape2/tips.html

今回はPingouinパッケージに内包されているanova(生まれつきの髪色と感じる痛みの閾値との関係)データセットを対象に解析していきます。
まず今回使用するデータセットを読み込みます。
INPUT:

df = pg.read_dataset('anova')
df.head()

OUTPUT:

SubjectHair colorPain threshold
01Light Blond62
12Light Blond60
23Light Blond71
34Light Blond55
45Light Blond48

簡単にデータセットの分布を確認します。

sns.barplot(x='Hair color', y='Pain threshold', data=df)


グループ(生まれつきの髪色)ごとに痛みの閾値の平均値が異なることがわかります。
このグループ間の平均値の差が有意かどうかを以降の分析していきます。

今回利用するデータは繰り返しがなくグループ間で独立なので、分析フローの「BETWEEN(groups are independent)」に分岐し、分散の等質性(グループ間の分散:バラツキに差がないこと)を検定します。
INPUT:

# 分散の等質性の検定
pg.homoscedasticity(data=df, dv='Pain threshold', group='Hair color')

OUTPUT:

Wpvalequal_var
levene0.3927430.760016TRUE

有意水準を0.05としたとき、pval(p値)が有意水準を上回ります。
したがって、分散が等質であるという帰無仮説を棄却できないので、グループ間の分散が等質であるとみなすことになります。

グループ間の分散が等質な場合、古典的な一元配置分散分析(one-way ANOVA)を実行します。
ちなみに、データに含まれる因子が髪の色の1つだけなので、「一元」配置と呼ばれます。
※もし、グループ間の分散が等質でない場合、一元配置分散分析ではなくウェルチの検定を実行します。
INPUT:

# 一元配置分散分析
pg.anova(data=df, dv='Pain threshold', between='Hair color')

OUTPUT:

Sourceddof1ddof2Fp-uncnp2
0Hair color3156.7914070.0041140.575962

p-uncが有意水準0.05を下回るので、2つ以上のグループの標本が同じ平均値を持つ母集団から取られているという帰無仮説が棄却されます。
したがって、グループ間の少なくとも1組は平均値に有意差があるということになります。
ですが、このままだと具体的にどのグループ間の平均値に有意差があるのかがわからないので、さらにTukeyの多重比較によってどのグループ間で差があるのかを確認します。
INPUT:

# Tukeyの多重比較
pg.pairwise_tukey(data=df, dv='Pain threshold', between='Hair color')

OUTPUT:

ABmean(A)mean(B)diffseTp-tukeyhedges
0Dark BlondDark Brunette51.237.413.85.1686232.6699570.0476681.525213
1Dark BlondLight Blond51.259.2-85.168623-1.5478010.413344-0.884182
2Dark BlondLight Brunette51.242.58.75.4821531.5869680.3913530.946285
3Dark BrunetteLight Blond37.459.2-21.85.168623-4.2177580.001-2.409395
4Dark BrunetteLight Brunette37.442.5-5.15.482153-0.9302910.75912-0.554719
5Light BlondLight Brunette59.242.516.75.4821533.0462490.0177751.816432

上の結果から、p値が有意水準0.05を下回る次のグループ間で平均値に有意差があると言えます。

  • Dark BlondとDark Brunette
  • Dark BrunetteとLight Blond
  • Light BlondとLight Brunette

最後に

冒頭でも述べましたが、Pingouinではt値やp値意外の指標も得られるため、簡易に統計解析する場合はPingouinを使った方が良さそうです。(もちろん、深い分析をする際にはRを使うべきですが。)
また、公式ドキュメントを見たところ、Paired plotやBland-Altman plotといった可視化も簡単にできるようです。
データサイエンティストなら知っておいて損はないパッケージだと思います。