How to Conduct One-Way ANOVA in Python Using Pingouin

How to Conduct One-Way ANOVA in Python Using Pingouin

Pingouin provides a comprehensive solution for conducting Analysis of Variance (ANOVA), complete with assumption checks and effect size calculations. In this article, we’ll walk through how to perform a one-way ANOVA using Pingouin’s intuitive interface and statistical tools.

Understanding One-Way ANOVA

Analysis of Variance (ANOVA) is a statistical test that helps determine whether there are significant differences between the means of three or more independent groups. The “one-way” designation indicates we’re examining the impact of a single factor (independent variable) on our outcome (dependent variable).

You should consider using one-way ANOVA when:

  • You have one categorical independent variable with three or more groups
  • You have one continuous dependent variable
  • You want to know if there are any statistically significant differences between the groups

Before running an ANOVA, your data should meet these key assumptions:

  1. Independence of Observations: Samples in each group should be independent (in our case, this is automatically satisfied since we generated random samples for each method)
  2. Normal Distribution: The dependent variable should be approximately normally distributed within each group
  3. Homogeneity of Variances: The variances of the dependent variable should be similar across groups

Creating Sample Data

Let’s simulate a study comparing exam scores across three different teaching methods. We’ll create three groups with different mean scores (75, 80, and 85) but the same standard deviation (10) to simulate realistic test score distributions. 

import pandas as pd
import numpy as np
import pingouin as pg

# Set random seed for reproducibility
np.random.seed(789)

# Generate sample data for three teaching methods
method_a = np.random.normal(75, 10, 30)  # Traditional
method_b = np.random.normal(80, 10, 30)  # Interactive
method_c = np.random.normal(85, 10, 30)  # Hybrid

# Create DataFrame
data = pd.DataFrame({
    'Score': np.concatenate([method_a, method_b, method_c]),
    'Method': ['Traditional'] * 30 + ['Interactive'] * 30 + ['Hybrid'] * 30
})

print(data)

Let’s take a quick Look at the sample data we created:

Score       Method
0   63.918886  Traditional
1   67.742814  Traditional
2   80.228043  Traditional
3   87.344419  Traditional
4   75.968959  Traditional
..        ...          ...
85  96.666695       Hybrid
86  80.025203       Hybrid
87  86.790118       Hybrid
88  73.415157       Hybrid
89  74.474901       Hybrid

[90 rows x 2 columns]

Our dataset now contains 90 scores (30 per teaching method), with the Hybrid method designed to have slightly higher scores than Interactive, which in turn has higher scores than Traditional.

Testing ANOVA Assumptions

1. Testing Normality

First, let’s verify that scores are normally distributed within each teaching method. Pingouin’s normality test uses the Shapiro-Wilk test, where p-values > 0.05 indicate normal distribution:

# Test normality for each group
normality = pg.normality(data=data, dv='Score', group='Method')
print("Normality Test Results:")
print(normality)
Normality Test Results:
                    W      pval  normal
Method                                 
Traditional  0.965418  0.422492    True
Interactive  0.957604  0.268694    True
Hybrid       0.963619  0.381937    True

The results show all three methods have p-values well above 0.05, confirming our data follows a normal distribution within each group. This isn’t surprising given we generated our data using normal distributions, but it is recommended to conduct this test before running ANOVA. 

2. Testing Homogeneity of Variances

Next, we’ll check if the variance in scores is similar across teaching methods using Levene’s test. First, we need to reshape our data to compare the variances properly:

# Test homoscedasticity
data['idx'] = np.tile(range(30), 3)
scores_wide = data.pivot(index='idx', columns='Method', values='Score')

homoscedasticity = pg.homoscedasticity(scores_wide)
print("\nHomoscedasticity Test Results:")
print(homoscedasticity)
Homoscedasticity Test Results:
               W      pval  equal_var
levene  0.051908  0.949445       True

The high p-value (0.949) in Levene’s test indicates very similar variances across groups. Again, this makes sense since we used the same standard deviation (10) for all groups, but this test would be essential with real data.

Conducting the ANOVA

With our assumptions verified, we can now perform the one-way ANOVA. Pingouin’s anova function provides a comprehensive output including effect size (partial eta-squared):

# Perform one-way ANOVA
results = pg.anova(data=data, dv='Score', between='Method')
print("\nPingouin ANOVA Results:")
print(results)
Pingouin ANOVA Results:
   Source  ddof1  ddof2         F     p-unc       np2
0  Method      2     87  7.392497  0.001084  0.145257

Let’s break down these results in detail:

  • Overall Significance (F-statistic and p-value):
    • The F-statistic (7.39) represents the ratio of variance between the groups to variance within the groups
    • With degrees of freedom df₁ = 2 (number of groups – 1) and df₂ = 87 (total observations – number of groups)
    • The p-value (0.001) is well below the conventional significance level of 0.05
    • This provides strong evidence that teaching methods have different effects on student scores
  • Effect Size (Partial Eta-Squared):
    • The partial eta-squared (np2 = 0.145) indicates that teaching method explains 14.5% of the total variance in test scores
    • In educational research, this is considered a moderate to large effect
    • For context: η² values of 0.01, 0.06, and 0.14 are typically considered small, medium, and large effects, respectively
  • Practical Implications:
    • These results suggest that choice of teaching method meaningfully impacts student performance
    • The effect size indicates that while teaching method matters, other factors (accounting for about 85.5% of the variance) also play important roles in student performance
    • This kind of analysis can help educators make evidence-based decisions about teaching methods while acknowledging other influential factors

Conclusion

Using Pingouin, we’ve been able to:

  1. Easily test our ANOVA assumptions with built-in functions
  2. Conduct a one-way ANOVA with minimal code
  3. Get comprehensive statistical output including effect sizes

This demonstrates Pingouin’s efficiency for conducting statistical analyses in Python, providing both the necessary assumption tests and detailed results in a clean, accessible format.

Leave a Reply

Your email address will not be published. Required fields are marked *