Skewness and Kurtosis Analysis

Interpretation Guidelines

Skewness

Excess Kurtosis (Fisher=True, normal = 0)

Pearson's Kurtosis (Fisher=False, normal = 3)

Python Example

# Example: Skewness and Kurtosis Analysis for Normality (scipy.stats.skew, kurtosis)
from scipy.stats import skew, kurtosis
import numpy as np
import matplotlib.pyplot as plt

def interpret_skew_kurt(skewness, kurtosis_value, excess_kurtosis):
    print(f"Skewness: {skewness:.4f}")
    print(f"Kurtosis (Pearson): {kurtosis_value:.4f}")
    print(f"Excess Kurtosis: {excess_kurtosis:.4f}")

    if abs(skewness) < 0.5:
        print(' - Skewness: Fairly symmetrical ✓')
    elif abs(skewness) < 1:
        print(' - Skewness: Moderately skewed')
    else:
        print(' - Skewness: Highly skewed ✗')

    if abs(kurtosis_value) < 0.5:
        print(' - Kurtosis: Normal tailedness ✓')
    elif kurtosis_value > 0.5:
        print(' - Kurtosis: Heavy tails (leptokurtic)')
    else:
        print(' - Kurtosis: Light tails (platykurtic)')

    if abs(excess_kurtosis) < 0.5:
        print(f" - Excess Kurtosis ({excess_kurtosis:.2f}): Normal tailedness ✓")
    elif excess_kurtosis > 0.5:
        print(f" - Excess Kurtosis ({excess_kurtosis:.2f}): Heavy tails (leptokurtic)")
    else:
        print(f" - Excess Kurtosis ({excess_kurtosis:.2f}): Light tails (platykurtic)")

# Generate sample data: normal and non-normal
data_normal = np.random.normal(loc=0, scale=1, size=1000)
data_non_normal = np.random.exponential(scale=2, size=1000)

# Plot histograms for visual inspection
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].hist(data_normal, bins=30, color='skyblue', edgecolor='black')
axes[0].set_title('Normal Data Histogram')
axes[1].hist(data_non_normal, bins=30, color='salmon', edgecolor='black')
axes[1].set_title('Non-Normal Data Histogram')
plt.tight_layout()
plt.show()

# Calculate skewness and kurtosis for normal data
skewness_norm = skew(data_normal)
kurt_norm = kurtosis(data_normal, fisher=False)  # Pearson's kurtosis (normal = 3)
excess_kurt_norm = kurtosis(data_normal, fisher=True)  # Excess kurtosis (normal = 0)

print('Normal Data:')
print(f'  Skewness: {skewness_norm:.4f}')
print(f'  Kurtosis (Pearson): {kurt_norm:.4f}')
print(f'  Excess Kurtosis: {excess_kurt_norm:.4f}')

interpret_skew_kurt(skewness_norm, kurt_norm, excess_kurt_norm)

# Calculate skewness and kurtosis for non-normal data
skewness_non_norm = skew(data_non_normal)
kurt_non_norm = kurtosis(data_non_normal, fisher=False)
excess_kurt_non_norm = kurtosis(data_non_normal, fisher=True)

print('\nNon-Normal Data:')
print(f'  Skewness: {skewness_non_norm:.4f}')
print(f'  Kurtosis (Pearson): {kurt_non_norm:.4f}')
print(f'  Excess Kurtosis: {excess_kurt_non_norm:.4f}')

interpret_skew_kurt(skewness_non_norm, kurt_non_norm, excess_kurt_non_norm)

Output
ML_AI/_feature_engineering/images/ske_kur-1.png
Normal Data:
Skewness: 0.1169
Kurtosis (Pearson): 3.4115
Excess Kurtosis: 0.4115
Skewness: 0.1169
Kurtosis (Pearson): 3.4115
Excess Kurtosis: 0.4115

Non-Normal Data:
Skewness: 1.8222
Kurtosis (Pearson): 7.3808
Excess Kurtosis: 4.3808
Skewness: 1.8222
Kurtosis (Pearson): 7.3808
Excess Kurtosis: 4.3808