SECTION 1: LEARNING OBJECTIVES

By the end of this lesson, you will be able to:

  1. Understand the fundamentals of statistical inference and its application in financial decision-making.

  2. Construct and interpret confidence intervals for financial metrics (means, proportions, differences).

  3. Perform hypothesis tests for comparing financial metrics across groups.

  4. Apply t-tests for comparing means in financial data.

  5. Use ANOVA for comparing multiple groups in financial analysis.

  6. Perform chi-square tests for categorical financial data.

  7. Apply non-parametric tests for non-normal financial data.

  8. Interpret p-values and confidence intervals for regulatory and business decision-making.


SECTION 2: SAMPLING AND SAMPLING DISTRIBUTIONS

2.1 The Central Limit Theorem

The Central Limit Theorem (CLT) states that the distribution of sample means approaches a normal distribution as sample size increases, regardless of the population distribution.

python
# ============= CENTRAL LIMIT THEOREM =============

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

print("="*60)
print("CENTRAL LIMIT THEOREM DEMONSTRATION")
print("="*60)

# Create a highly skewed population (lognormal)
np.random.seed(42)
population = np.random.lognormal(2, 1, 10000)

print(f"\n📊 Population Statistics:")
print(f"  Mean: {population.mean():.2f}")
print(f"  Median: {np.median(population):.2f}")
print(f"  Skewness: {pd.Series(population).skew():.3f}")

# Draw samples of different sizes
sample_sizes = [5, 10, 30, 100]
n_samples = 1000

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

for i, sample_size in enumerate(sample_sizes):
    row = i // 2
    col = i % 2
    
    # Draw multiple samples and calculate means
    sample_means = []
    for _ in range(n_samples):
        sample = np.random.choice(population, size=sample_size, replace=True)
        sample_means.append(sample.mean())
    
    # Plot distribution of sample means
    ax = axes[row, col]
    ax.hist(sample_means, bins=30, edgecolor='black', alpha=0.7, density=True)
    
    # Overlay normal distribution
    mu = np.mean(sample_means)
    sigma = np.std(sample_means)
    x = np.linspace(mu - 4*sigma, mu + 4*sigma, 100)
    y = stats.norm.pdf(x, mu, sigma)
    ax.plot(x, y, 'r-', linewidth=2, label='Normal Fit')
    
    # Add vertical line for population mean
    ax.axvline(population.mean(), color='black', linestyle='--', label=f'Population Mean: {population.mean():.2f}')
    
    ax.set_title(f'Sample Size: {sample_size}', fontsize=12)
    ax.set_xlabel('Sample Mean')
    ax.set_ylabel('Density')
    ax.legend()
    ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('central_limit_theorem.png', dpi=300)
plt.show()

print("\n💡 Key Insight:")
print("  • As sample size increases, distribution of sample means becomes more normal")
print("  • Mean of sample means approaches population mean")
print("  • Standard deviation of sample means decreases (Standard Error)")

2.2 Standard Error and Confidence Intervals

python
# ============= STANDARD ERROR AND CONFIDENCE INTERVALS =============

def calculate_confidence_interval(data, confidence=0.95):
    """Calculate confidence interval for the mean."""
    n = len(data)
    mean = np.mean(data)
    std = np.std(data, ddof=1)
    se = std / np.sqrt(n)
    
    # t-value for confidence level
    t_value = stats.t.ppf((1 + confidence) / 2, n - 1)
    
    margin = t_value * se
    ci_lower = mean - margin
    ci_upper = mean + margin
    
    return {
        'mean': mean,
        'std': std,
        'se': se,
        'ci_lower': ci_lower,
        'ci_upper': ci_upper,
        'margin': margin
    }

# Apply to banking data
print("\n" + "="*60)
print("CONFIDENCE INTERVALS FOR BANKING METRICS")
print("="*60)

# Create sample data
np.random.seed(42)
n = 100

# Monthly transaction amounts for different customer segments
premium_transactions = np.random.normal(350, 80, n)
standard_transactions = np.random.normal(200, 60, n)
basic_transactions = np.random.normal(120, 40, n)

print("\n📊 Monthly Transaction Amounts:")
print(f"  Premium: Mean={premium_transactions.mean():.2f}, Std={premium_transactions.std():.2f}")
print(f"  Standard: Mean={standard_transactions.mean():.2f}, Std={standard_transactions.std():.2f}")
print(f"  Basic: Mean={basic_transactions.mean():.2f}, Std={basic_transactions.std():.2f}")

# Calculate confidence intervals
for segment, data in [('Premium', premium_transactions), 
                      ('Standard', standard_transactions), 
                      ('Basic', basic_transactions)]:
    ci = calculate_confidence_interval(data, confidence=0.95)
    print(f"\n{segment} Segment (95% CI):")
    print(f"  Mean: ${ci['mean']:.2f}")
    print(f"  Standard Error: ${ci['se']:.2f}")
    print(f"  CI: [${ci['ci_lower']:.2f}, ${ci['ci_upper']:.2f}]")
    print(f"  Margin of Error: ±${ci['margin']:.2f}")

# Visualize confidence intervals
fig, ax = plt.subplots(figsize=(10, 6))

segments = ['Premium', 'Standard', 'Basic']
means = [np.mean(premium_transactions), np.mean(standard_transactions), np.mean(basic_transactions)]
cis = [calculate_confidence_interval(data, 0.95) for data in [premium_transactions, standard_transactions, basic_transactions]]

for i, (segment, mean, ci) in enumerate(zip(segments, means, cis)):
    ax.errorbar(i, mean, yerr=ci['margin'], fmt='o', capsize=5, capthick=2, 
                markersize=10, color='blue', ecolor='red', elinewidth=2)
    ax.text(i, mean + ci['margin'] + 5, f'${mean:.0f}', ha='center', va='bottom')

ax.set_xticks(range(len(segments)))
ax.set_xticklabels(segments)
ax.set_ylabel('Monthly Transaction Amount ($)')
ax.set_title('95% Confidence Intervals by Customer Segment', fontsize=14)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('confidence_intervals.png', dpi=300)
plt.show()

SECTION 3: HYPOTHESIS TESTING

3.1 One-Sample t-Test

A one-sample t-test compares the mean of a sample to a known value.

python
# ============= ONE-SAMPLE T-TEST =============

print("\n" + "="*60)
print("ONE-SAMPLE T-TEST")
print("="*60)

# Example: Is the average credit score different from 700?
credit_scores = np.random.normal(685, 50, 100)
known_mean = 700

# Perform one-sample t-test
t_stat, p_value = stats.ttest_1samp(credit_scores, known_mean)

print(f"\n📊 Credit Score Analysis:")
print(f"  Sample Mean: {credit_scores.mean():.2f}")
print(f"  Hypothesized Mean: {known_mean}")
print(f"  Sample Std: {credit_scores.std():.2f}")
print(f"  Sample Size: {len(credit_scores)}")
print(f"  T-Statistic: {t_stat:.3f}")
print(f"  P-Value: {p_value:.4f}")

if p_value < 0.05:
    print(f"  Result: REJECT null hypothesis (p < 0.05)")
    print(f"  Interpretation: The average credit score IS significantly different from {known_mean}")
else:
    print(f"  Result: FAIL TO REJECT null hypothesis (p >= 0.05)")
    print(f"  Interpretation: No significant difference from {known_mean}")

# Visualize
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Histogram with hypothesized mean
ax = axes[0]
credit_scores.hist(bins=20, ax=ax, edgecolor='black', alpha=0.7)
ax.axvline(credit_scores.mean(), color='red', linestyle='--', linewidth=2, label=f'Sample Mean: {credit_scores.mean():.2f}')
ax.axvline(known_mean, color='blue', linestyle='--', linewidth=2, label=f'Hypothesized Mean: {known_mean}')
ax.set_title('Credit Score Distribution', fontsize=12)
ax.set_xlabel('Credit Score')
ax.set_ylabel('Frequency')
ax.legend()
ax.grid(True, alpha=0.3)

# T-distribution
ax = axes[1]
x = np.linspace(-4, 4, 1000)
y = stats.t.pdf(x, len(credit_scores) - 1)
ax.plot(x, y, 'b-', linewidth=2)
ax.axvline(t_stat, color='red', linestyle='--', linewidth=2, label=f'T-statistic: {t_stat:.3f}')
ax.axvline(-t_stat, color='red', linestyle='--', linewidth=2)

# Shade critical regions
alpha = 0.05
t_critical = stats.t.ppf(1 - alpha/2, len(credit_scores) - 1)
ax.fill_between(x, 0, y, where=(x > t_critical), color='red', alpha=0.3, label='Rejection Region')
ax.fill_between(x, 0, y, where=(x < -t_critical), color='red', alpha=0.3)

ax.set_title('T-Distribution', fontsize=12)
ax.set_xlabel('T-Statistic')
ax.set_ylabel('Density')
ax.legend()
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('one_sample_ttest.png', dpi=300)
plt.show()

3.2 Two-Sample t-Test

A two-sample t-test compares the means of two groups.

python
# ============= TWO-SAMPLE T-TEST =============

print("\n" + "="*60)
print("TWO-SAMPLE T-TEST")
print("="*60)

# Example: Compare transaction amounts between Premium and Standard customers
premium_transactions = np.random.normal(350, 80, 100)
standard_transactions = np.random.normal(200, 60, 100)

# Perform two-sample t-test
t_stat, p_value = stats.ttest_ind(premium_transactions, standard_transactions)

print(f"\n📊 Transaction Amount Comparison:")
print(f"  Premium: Mean={premium_transactions.mean():.2f}, Std={premium_transactions.std():.2f}")
print(f"  Standard: Mean={standard_transactions.mean():.2f}, Std={standard_transactions.std():.2f}")
print(f"  Difference: {premium_transactions.mean() - standard_transactions.mean():.2f}")
print(f"  T-Statistic: {t_stat:.3f}")
print(f"  P-Value: {p_value:.4f}")

if p_value < 0.05:
    print(f"  Result: REJECT null hypothesis")
    print(f"  Interpretation: Premium customers have significantly different transaction amounts")
else:
    print(f"  Result: FAIL TO REJECT null hypothesis")
    print(f"  Interpretation: No significant difference in transaction amounts")

# Visualize
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Box plots
ax = axes[0]
data = [premium_transactions, standard_transactions]
ax.boxplot(data, labels=['Premium', 'Standard'])
ax.set_title('Transaction Amounts by Segment', fontsize=12)
ax.set_ylabel('Amount ($)')
ax.grid(True, alpha=0.3)

# Histograms
ax = axes[1]
ax.hist(premium_transactions, bins=20, alpha=0.5, label='Premium', edgecolor='black')
ax.hist(standard_transactions, bins=20, alpha=0.5, label='Standard', edgecolor='black')
ax.axvline(premium_transactions.mean(), color='blue', linestyle='--', label=f'Premium Mean: {premium_transactions.mean():.2f}')
ax.axvline(standard_transactions.mean(), color='orange', linestyle='--', label=f'Standard Mean: {standard_transactions.mean():.2f}')
ax.set_title('Transaction Amount Distributions', fontsize=12)
ax.set_xlabel('Amount ($)')
ax.set_ylabel('Frequency')
ax.legend()
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('two_sample_ttest.png', dpi=300)
plt.show()

3.3 Paired t-Test

A paired t-test compares two related samples (e.g., before and after).

python
# ============= PAIRED T-TEST =============

print("\n" + "="*60)
print("PAIRED T-TEST")
print("="*60)

# Example: Impact of financial education on credit scores
np.random.seed(42)
n_customers = 50

# Before education
before_scores = np.random.normal(640, 50, n_customers)

# After education (some improvement)
improvement = np.random.normal(20, 15, n_customers)
after_scores = before_scores + improvement

# Perform paired t-test
t_stat, p_value = stats.ttest_rel(before_scores, after_scores)

print(f"\n📊 Financial Education Impact:")
print(f"  Before: Mean={before_scores.mean():.2f}, Std={before_scores.std():.2f}")
print(f"  After: Mean={after_scores.mean():.2f}, Std={after_scores.std():.2f}")
print(f"  Average Improvement: {after_scores.mean() - before_scores.mean():.2f}")
print(f"  T-Statistic: {t_stat:.3f}")
print(f"  P-Value: {p_value:.4f}")

if p_value < 0.05:
    print(f"  Result: REJECT null hypothesis")
    print(f"  Interpretation: Financial education significantly improved credit scores")
else:
    print(f"  Result: FAIL TO REJECT null hypothesis")
    print(f"  Interpretation: No significant improvement detected")

# Visualize
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Before and after distributions
ax = axes[0]
ax.hist(before_scores, bins=15, alpha=0.5, label='Before', edgecolor='black')
ax.hist(after_scores, bins=15, alpha=0.5, label='After', edgecolor='black')
ax.axvline(before_scores.mean(), color='blue', linestyle='--', label=f'Before Mean: {before_scores.mean():.2f}')
ax.axvline(after_scores.mean(), color='orange', linestyle='--', label=f'After Mean: {after_scores.mean():.2f}')
ax.set_title('Credit Score Distribution - Before vs After', fontsize=12)
ax.set_xlabel('Credit Score')
ax.set_ylabel('Frequency')
ax.legend()
ax.grid(True, alpha=0.3)

# Paired differences
ax = axes[1]
differences = after_scores - before_scores
ax.hist(differences, bins=15, edgecolor='black', alpha=0.7)
ax.axvline(0, color='red', linestyle='--', linewidth=2, label='No Change')
ax.axvline(differences.mean(), color='blue', linestyle='--', linewidth=2, label=f'Mean Improvement: {differences.mean():.2f}')
ax.set_title('Distribution of Improvements', fontsize=12)
ax.set_xlabel('Score Improvement')
ax.set_ylabel('Frequency')
ax.legend()
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('paired_ttest.png', dpi=300)
plt.show()

SECTION 4: ANALYSIS OF VARIANCE (ANOVA)

ANOVA compares means across three or more groups.

python
# ============= ANALYSIS OF VARIANCE (ANOVA) =============

print("\n" + "="*60)
print("ANALYSIS OF VARIANCE (ANOVA)")
print("="*60)

# Example: Compare transaction amounts across all three segments
np.random.seed(42)
premium = np.random.normal(350, 80, 100)
standard = np.random.normal(200, 60, 100)
basic = np.random.normal(120, 40, 100)

# Perform one-way ANOVA
f_stat, p_value = stats.f_oneway(premium, standard, basic)

print(f"\n📊 Transaction Amount by Segment:")
print(f"  Premium: Mean={premium.mean():.2f}, Std={premium.std():.2f}")
print(f"  Standard: Mean={standard.mean():.2f}, Std={standard.std():.2f}")
print(f"  Basic: Mean={basic.mean():.2f}, Std={basic.std():.2f}")
print(f"\n  F-Statistic: {f_stat:.3f}")
print(f"  P-Value: {p_value:.4f}")

if p_value < 0.05:
    print(f"  Result: REJECT null hypothesis")
    print(f"  Interpretation: There is a significant difference between at least two segments")
    
    # Post-hoc analysis (Tukey's HSD)
    from statsmodels.stats.multicomp import pairwise_tukeyhsd
    
    # Prepare data for post-hoc
    all_data = np.concatenate([premium, standard, basic])
    all_groups = np.concatenate([['Premium']*100, ['Standard']*100, ['Basic']*100])
    
    tukey = pairwise_tukeyhsd(all_data, all_groups, alpha=0.05)
    print("\n  Post-hoc Analysis (Tukey's HSD):")
    print(tukey)
    
else:
    print(f"  Result: FAIL TO REJECT null hypothesis")
    print(f"  Interpretation: No significant difference between segments")

# Visualize
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Box plots
ax = axes[0]
data = [premium, standard, basic]
ax.boxplot(data, labels=['Premium', 'Standard', 'Basic'])
ax.set_title('Transaction Amounts by Segment', fontsize=12)
ax.set_ylabel('Amount ($)')
ax.grid(True, alpha=0.3)

# Violin plots
ax = axes[1]
sns.violinplot(data=[premium, standard, basic], ax=ax)
ax.set_xticklabels(['Premium', 'Standard', 'Basic'])
ax.set_title('Transaction Amount Distributions', fontsize=12)
ax.set_ylabel('Amount ($)')
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('anova_analysis.png', dpi=300)
plt.show()

SECTION 5: CHI-SQUARE TESTS

Chi-square tests are used for categorical data.

python
# ============= CHI-SQUARE TESTS =============

print("\n" + "="*60)
print("CHI-SQUARE TESTS")
print("="*60)

# Example: Is there an association between customer segment and loan default?
np.random.seed(42)

# Create contingency table
n_customers = 500
segments = np.random.choice(['Premium', 'Standard', 'Basic'], n_customers, p=[0.15, 0.55, 0.30])

# Simulate defaults based on segment
default_prob = {'Premium': 0.02, 'Standard': 0.05, 'Basic': 0.10}
defaults = np.array([1 if np.random.random() < default_prob[seg] else 0 for seg in segments])

# Create contingency table
contingency = pd.crosstab(segments, defaults, margins=False)

print("\n📊 Contingency Table - Segment vs Default:")
print(contingency)

# Perform chi-square test
from scipy.stats import chi2_contingency
chi2, p_value, dof, expected = chi2_contingency(contingency)

print(f"\n  Chi-Square Statistic: {chi2:.3f}")
print(f"  P-Value: {p_value:.4f}")
print(f"  Degrees of Freedom: {dof}")

if p_value < 0.05:
    print(f"  Result: REJECT null hypothesis")
    print(f"  Interpretation: There is a significant association between segment and default")
else:
    print(f"  Result: FAIL TO REJECT null hypothesis")
    print(f"  Interpretation: No significant association between segment and default")

# Visualize
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Stacked bar chart
ax = axes[0]
contingency_pct = contingency.div(contingency.sum(axis=1), axis=0)
contingency_pct.plot(kind='bar', stacked=True, ax=ax)
ax.set_title('Default Rate by Segment', fontsize=12)
ax.set_xlabel('Segment')
ax.set_ylabel('Proportion')
ax.legend(['No Default', 'Default'], title='Status')
ax.grid(True, alpha=0.3)

# Heatmap of expected vs observed
ax = axes[1]
sns.heatmap(contingency, annot=True, fmt='d', cmap='Blues', ax=ax)
ax.set_title('Observed Frequencies', fontsize=12)
ax.set_xlabel('Default')
ax.set_ylabel('Segment')

plt.tight_layout()
plt.savefig('chi_square_analysis.png', dpi=300)
plt.show()

SECTION 6: NON-PARAMETRIC TESTS

Non-parametric tests are used when data is not normally distributed.

python
# ============= NON-PARAMETRIC TESTS =============

print("\n" + "="*60)
print("NON-PARAMETRIC TESTS")
print("="*60)

# Create skewed data (lognormal)
np.random.seed(42)
group_a = np.random.lognormal(3, 0.5, 100)
group_b = np.random.lognormal(3.5, 0.5, 100)

print("\n📊 Data with Non-Normal Distribution:")
print(f"  Group A: Mean={group_a.mean():.2f}, Median={np.median(group_a):.2f}, Skew={pd.Series(group_a).skew():.3f}")
print(f"  Group B: Mean={group_b.mean():.2f}, Median={np.median(group_b):.2f}, Skew={pd.Series(group_b).skew():.3f}")

# Mann-Whitney U test (non-parametric alternative to t-test)
u_stat, p_value = stats.mannwhitneyu(group_a, group_b, alternative='two-sided')

print(f"\n📊 Mann-Whitney U Test:")
print(f"  U-Statistic: {u_stat:.3f}")
print(f"  P-Value: {p_value:.4f}")

if p_value < 0.05:
    print(f"  Result: Significant difference between groups")
else:
    print(f"  Result: No significant difference between groups")

# Kruskal-Wallis test (non-parametric alternative to ANOVA)
# Add a third group
group_c = np.random.lognormal(4, 0.5, 100)
h_stat, p_value = stats.kruskal(group_a, group_b, group_c)

print(f"\n📊 Kruskal-Wallis Test:")
print(f"  H-Statistic: {h_stat:.3f}")
print(f"  P-Value: {p_value:.4f}")

if p_value < 0.05:
    print(f"  Result: Significant difference between at least two groups")
else:
    print(f"  Result: No significant difference between groups")

# Visualize
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Box plots
ax = axes[0]
data = [group_a, group_b, group_c]
ax.boxplot(data, labels=['Group A', 'Group B', 'Group C'])
ax.set_title('Non-Normal Data Comparison', fontsize=12)
ax.set_ylabel('Value')
ax.grid(True, alpha=0.3)

# QQ plots for normality check
ax = axes[1]
stats.probplot(group_a, dist="norm", plot=ax)
ax.set_title('QQ Plot - Group A', fontsize=12)

plt.tight_layout()
plt.savefig('nonparametric_tests.png', dpi=300)
plt.show()

SECTION 7: BUSINESS RISK & FINANCIAL IMPACT

7.1 Statistical Inference in Banking Decision-Making

python
# ============= BUSINESS APPLICATIONS =============

print("\n" + "="*60)
print("BUSINESS APPLICATIONS OF STATISTICAL INFERENCE")
print("="*60)

applications = [
    {
        'application': 'Credit Scoring Model Validation',
        'test': 't-test',
        'use_case': 'Compare model predictions vs actual outcomes',
        'impact': 'Ensure model accuracy, comply with SR 11-7'
    },
    {
        'application': 'Marketing Campaign Effectiveness',
        'test': 'paired t-test',
        'use_case': 'Compare customer spending before and after campaign',
        'impact': 'Optimize marketing spend, increase ROI'
    },
    {
        'application': 'Customer Segment Analysis',
        'test': 'ANOVA',
        'use_case': 'Compare metrics across customer segments',
        'impact': 'Targeted product offerings, improve profitability'
    },
    {
        'application': 'Fraud Detection',
        'test': 'chi-square',
        'use_case': 'Test association between transaction characteristics and fraud',
        'impact': 'Improve fraud detection, reduce losses'
    },
    {
        'application': 'A/B Testing',
        'test': 'two-sample t-test',
        'use_case': 'Compare performance of different strategies',
        'impact': 'Data-driven decision making, optimize outcomes'
    }
]

for app in applications:
    print(f"\n📊 {app['application']}:")
    print(f"  Test: {app['test']}")
    print(f"  Use Case: {app['use_case']}")
    print(f"  Business Impact: {app['impact']}")

7.2 Regulatory Considerations

python
# ============= REGULATORY CONSIDERATIONS =============

print("\n" + "="*60)
print("REGULATORY CONSIDERATIONS")
print("="*60)

regulatory = {
    'SR 11-7': {
        'requirement': 'Model validation must include statistical testing',
        'implication': 'Document all hypothesis tests and their results'
    },
    'BASEL III': {
        'requirement': 'Risk models must be statistically sound',
        'implication': 'Use appropriate tests for model calibration'
    },
    'Fair Lending': {
        'requirement': 'No discrimination in lending decisions',
        'implication': 'Use statistical tests to check for bias'
    },
    'GDPR': {
        'requirement': 'Right to explanation of automated decisions',
        'implication': 'Statistical results must be interpretable and explainable'
    }
}

for reg, details in regulatory.items():
    print(f"\n📋 {reg}:")
    print(f"  Requirement: {details['requirement']}")
    print(f"  Implication: {details['implication']}")

SECTION 8: SUMMARY FOR THE DATA PRACTITIONER

8.1 The 1-Minute Elevator Pitch

“Statistical inference helps us make data-driven decisions with quantified uncertainty. We use confidence intervals to estimate population parameters, t-tests to compare group means, ANOVA to analyze multiple groups, and chi-square tests for categorical relationships. Non-parametric tests work when data isn’t normal. These techniques are essential for validating credit models, testing marketing effectiveness, and ensuring regulatory compliance. Proper statistical inference prevents costly business mistakes.”

8.2 Key Takeaways

  1. Central Limit Theorem enables inference even with non-normal data (with sufficient sample size).

  2. Confidence intervals quantify uncertainty in estimates.

  3. t-tests compare means (one-sample, two-sample, paired).

  4. ANOVA compares means across three or more groups.

  5. Chi-square tests analyze categorical data relationships.

  6. Non-parametric tests work when data isn’t normal.

  7. P-values indicate the strength of evidence against the null hypothesis.

  8. Sample size affects statistical power and precision.

  9. Business context is crucial for interpreting statistical results.

  10. Regulatory compliance requires documentation of statistical testing.

8.3 Recommended Next Steps

  1. Apply hypothesis tests to your banking data

  2. Build confidence intervals for key metrics

  3. Validate models using statistical tests

  4. Document statistical procedures for compliance

  5. Learn about power analysis for experiment design


[END OF LESSON 2]

 
Â