
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:
- 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)
- Normal Distribution: The dependent variable should be approximately normally distributed within each group
- 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:
- Easily test our ANOVA assumptions with built-in functions
- Conduct a one-way ANOVA with minimal code
- 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.
