Session 2: Exploratory Data Analysis - Fundamentals

Published course presentation · repository edition

Thierry Warin, PhD

HEC Montréal

Outline · The hour ahead

  1. Class Organization
  2. Quote of the day
  3. Introduction
  4. Measuring the center
  5. Measuring the spread
  6. Measuring the shape
  7. Measuring the shape (cont.)
  8. Conclusion

What session 2 is for

The mathematics

  • Distinguish mean, median and trimmed mean, and say which question each answers
  • Explain why the sample variance divides by \(n-1\)
  • Test skewness and excess kurtosis against \(2\sqrt{6/n}\) and \(4\sqrt{6/n}\)

The Python

  • Compute the moments directly, and check them against a library
  • Load the course panel with pd.read_parquet and .dropna, and say how many rows went
  • Take any quantile — median, quartile, percentile — with .quantile

The international business

  • Read a mean–median gap as evidence about a distribution’s shape
  • Choose the summary a manager should see when one country dominates the total
  • Say what heavy tails cost a plan built on an average

Your Python so far

Everything you need to type is on one sheet — how to start Python in VS Codium on your platform, how to make a file and run it, the DataFrame basics, and every name from sessions 1 to 2, each with a line showing it in use.

Python Cheatsheet · Session 02 (PDF) · in the repository at 02-…/PYTHON-CHEATSHEET.pdf

One sheet per package, functions explained with pictures: pandas · NumPy · SciPy · statsmodels

Print it, or keep it open beside the editor. Nothing on it is examinable; all of it is assumed.

Class Organization

Class Organization

  • Respect: Respect other participants and speakers.

  • Participation: Participate actively in discussions and activities.

  • Commitment: Be committed and involved in the learning process.

  • Collaboration: Collaborate with your peers and share your knowledge.

  • Confidentiality: Respect the confidentiality of shared information.

  • Cell phones are in backpacks, not on the table.

  • Computers are used for taking notes and following the course, not for personal messages or other activities.

Session Day and Time Building, Room Instructor Session Dates
Session 1 Wed 15:30–18:30 Décelles — Victoriaville Thierry Warin August 26, 2026
Session 2 Wed 15:30–18:30 Décelles — Victoriaville September 2, 2026
Session 3 Wed 15:30–18:30 Décelles — Victoriaville September 9, 2026
Session 4 Wed 15:30–18:30 Décelles — Victoriaville September 16, 2026
Session 5 Wed 15:30–18:30 Décelles — Victoriaville September 23, 2026
Session 6 Wed 15:30–18:30 Asynchronous — no room October 7, 2026
Session 7 Wed 15:30–18:30 Décelles — Victoriaville October 14, 2026
Session 8 Wed 15:30–18:30 Décelles — Victoriaville November 4, 2026
Session 9 Wed 15:30–18:30 Décelles — Victoriaville November 11, 2026
Session 10 Wed 15:30–18:30 Décelles — Victoriaville November 18, 2026
Session 11 Wed 15:30–18:30 Décelles — Victoriaville November 25, 2026
Session 12 Wed 15:30–18:30 Décelles — Victoriaville December 2, 2026

Quote of the day

It’s tough to make predictions, especially about the future

Yogi Berra

Introduction

Introduction

  • Statistics is a language, constructed by mathematicians.

  • The tools (formulas and processes) are constructs. They do not represent the truth, just the tools to get closer to the truth. They are the foundations that we use in our applications as a data analyst.

So, let us spend some time on the foundations first.

Introduction (cont.)

The magic in the data

Web app

Introduction - Differences between statistics and statistical learning?

Statistics: decision making under uncertainty.

Statistics is that branch of knowledge which deals with the multiplicity of data, its

  • collection,

  • analysis, and

  • interpretation

Statistical learning is a vast set of tools for understanding data

  • classified as supervised learning: building a statistical model for predicting, or estimating, and output based on one (single) or more (multiple) inputs.

  • classified as unsupervised learning: there are inputs, but no supervising output

The goal is to understand the models, intuitions, and strengths and weaknesses of the various approaches

Introduction - Differences between statistics and statistical learning? (cont.)

  • scalar, random variable, vector, matrix

  • quantitative values versus qualitative values

    • quantitative: numerical (continuous or discrete)

    • qualitative: categorical (nominal or ordinal)

graph TB
A[Types of data] --> B[Quantitative]; B --> D{Numerical}
A --> C[Qualitative]; C --> E{Categorical}

D --> F(Continuous)
D --> G(Discrete)

E --> H(Ordinal)
E --> I(Nominal)

Introduction - Differences between statistics and statistical learning? (cont.)

Numerical Examples Visualizations
Discrete: data have a finite number of values Number of balls in a jar Bar charts, line graphs
Continuous: data have an infinite number of values Distance, time Histograms, line graphs
Categorical Examples Visualizations
Nominal: identified by particular names or categories and cannot be organized in any order Gender, colors, locations Bar charts
Ordinal: identified by particular names or categories and can be ordered Rankings Bar charts

Introduction - Differences between statistics and statistical learning? (cont.)

  • Outcomes associated with random experiments (probabilistic) called random variables:

\[ X, Y, Z \]

  • Observed values:

\[ x, y, z \]

Let \(X\) be a r.v. taking values in the sample space \(S=\left\{x_{1},\, x_{2},\,\ldots,x_{k}\right\}\)

\[ p(x_{i})=\Pr(X=x_{i}), \quad i=1,2,\ldots,k \]

\[ \sum_{i=1}^{k}p(x_{i}) = p(x_{1})+p(x_{2})+\cdots+p(x_{k}), = 1 \]

Introduction - Differences between statistics and statistical learning? (cont.)

Three Basic Features

  • Center: middle or general tendency

  • Spread: small means tightly clustered, large means highly variable

  • Shape: symmetry versus skewness, kurtosis

Make the difference between a sample and a population!

Measuring the center

Measuring the center

In what follows, we will look into the following concepts:

Basics:

  • The sample mean
  • The sample median

Extensions:

  • The trimmed mean
  • The sample quantile
  • The sample percentile

The basics: the sample mean

R.V.’s mean

\[ \mu = \sum_{i=1}^{k} x_{i} p(x_{i}) \\\\ = x_{1} \times p(x_{1}) + \cdots + x_{k} \times p(x_{k}) \]

  • the mean is a center or average value of \((X)\)

  • \((\mu)\) can be any number or decimal

  • \((\mu)\) is the “first moment about the origin”

Sample mean

\[ \overline{x} = \frac{x_{1} + x_{2} + \cdots+x_{n}}{n} \\\\ = \frac{1}{n}\sum_{i = 1}^{n} x_{i} \]

  • Good: natural, easy to compute, nice properties
  • Bad: sensitive to extreme values

The basics: the sample mean (cont.)

Wait!

Greek letters are for the RV and latin letters are for the sample?

The basics: the sample mean

# In the VS Codium terminal, with .venv active:  python
import statsmodels.api as sm

# 21 observations from an ammonia-oxidation plant — ships with statsmodels,
# so there is nothing to download.
mydata = sm.datasets.stackloss.load_pandas().data
stack_loss = mydata["STACKLOSS"]
stack.loss
42
37
37
28
18
18
19
20
etc.
stack_loss.mean()
np.float64(17.523809523809526)

The basics: the sample median

How to find it

  • sort the data into an increasing sequence of \(n\) numbers

  • \(\tilde{x}\) lies in position \((n + 1)/2\)

  • Good: resistant to extreme values, easy to describe

  • Bad: not as mathematically tractable, need to sort the data to calculate

stack_loss.median()
np.float64(15.0)

Extensions

How to find it

  • “trim” a proportion of data from both ends of the ordered list

  • find the sample mean of what’s left

  • Good: also resistant to extreme values, has good properties, too

  • Bad: still need to sort data to get rid of outliers

from scipy import stats

stats.trim_mean(stack_loss, 0.05)
np.float64(16.789473684210527)
  • Quantile: approximately \(100 \times p\%\) of the data fall below the value \(\tilde{q}_{p}\)
stack_loss.quantile(0.75)
np.float64(19.0)

So, \(75%\) of the data (.75*21=16) fall below the value \(19\).

stack_loss.quantile([0, 0.25, 0.80])
0.00     7.0
0.25    11.0
0.80    20.0
Name: STACKLOSS, dtype: float64
  • Percentile: the percentage of observations that fall below a given data point

stats.norm.cdf(1800, loc=1500, scale=300)
np.float64(0.8413447460685429)

Measuring the spread

Measures of spread

In what follows, we will look into the following concepts:

  • The sample variance

  • The sample standard deviation

  • The sample interquartile range (IQR)

Measures of spread

The sample variance \(s^{2}\):

\[ s^{2} = \frac{1}{n - 1}\sum_{i = 1}^{n}(x_{i} - \overline{x})^{2} \]

The sample standard deviation is \((s = \sqrt{s^{2}})\)

  • Good: tractable, nice mathematical/statistical properties

  • Bad: sensitive to extreme values

print(stack_loss.var(ddof=1))
print(stack_loss.std(ddof=1))
103.46190476190478
10.171622523565489
[1] 10.17162

Interpretation of \(s\)

The empirical rule:

  • For nearly normally distributed data,

  • about \(68\%\) falls within 1 SD of the mean,

  • about \(95\%\) falls within 2 SD of the mean,

  • about \(99.7\%\) falls within 3 SD of the mean.

  • It is possible for observations to fall 4, 5, or more standard deviations away from the mean, but these occurrences are very rare if the data are nearly normal.

SAT scores are distributed nearly normally with mean 1500 and standard deviation 300.

Following the 68-95-99.7 Rule:

  • \(\sim 68\%\) of students score between 1200 and 1800 on the SAT.

  • \(\sim 95\%\) of students score between 900 and 2100 on the SAT.

  • \(\sim 99.7\%\) of students score between 600 and 2400 on the SAT.

\[ IQR = \tilde{q}_{0.75} - \tilde{q}_{0.25} \]

stack_loss.quantile(0.75) - stack_loss.quantile(0.25)
np.float64(8.0)
  • Good: resistant to outliers (see session 3)

  • Bad: only considers middle \(50\%\) of the data, equivalent to:

stack_loss.quantile([0.25, 0.75])
0.25    11.0
0.75    19.0
Name: STACKLOSS, dtype: float64

Measuring the shape

Measuring the shape

In what follows, we will look into the following concepts:

  • Skewness: degree of “symmetry”

  • Kurtosis: degree of “thickness”

Measuring the shape

Measuring the shape

  • Symmetric or skewed

    • right (positive) and left (negative) skewness
  • Kurtosis

    • leptokurtic - steep peak, heavy tails

    • platykurtic - flatter, thin tails

    • mesokurtic - right in the middle

  • All three can share the same mean and the same variance: kurtosis is about shape, not spread

Measuring the shape (cont.)

Wait!

Why are we looking at the distribution of the sample?

Is the study of the sample shape/distribution relevant because otherwise the tools designed by the statisticians would not work?

Measures of shape: sample skewness

The sample skewness \(g_{1}\):

\[ g_{1} = \frac{1}{n}\frac{\sum_{i = 1}^{n}(x_{i} - \overline{x})^{3}}{s^{3}} \]

Things to notice:

  • \(-\infty < g_{1} < \infty\)

  • sign of \(g_{1}\) indicates direction of skewness \(\pm)\)

Measures of shape

import numpy as np

def skewness(x):
    """g1, exactly as defined on the previous slide."""
    x = np.asarray(x, float)
    xbar, s = x.mean(), x.std(ddof=1)
    return ((x - xbar) ** 3).mean() / s ** 3

skewness(stack_loss)
np.float64(1.1564007167787318)

If \(\vert g_{1} \vert > 2\sqrt{6/n}\), then the data distribution is substantially skewed in the direction of the sign of \(g_{1}\)

# The same test on course data: GDP per capita across 30 European countries
import pandas as pd
core = pd.read_parquet("data/spine/core.parquet")
gdp = core["gdp_pc_eur"].dropna()

skewness(gdp)
np.float64(0.8805789352785794)
2 * np.sqrt(6 / len(gdp))
np.float64(0.2343499700593521)

The sample excess kurtosis \(g_{2}\):

\[ g_{2} = \frac{1}{n}\frac{\sum_{i = 1}^{n}(x_{i} - \overline{x})^{4}}{s^{4}} - 3 \]

Things to note:

  • \(-2 \leq g_{2} < \infty\)

  • \(g_{2} > 0\) indicates leptokurtosis

  • \(g_{2} < 0\) indicates platykurtosis

def excess_kurtosis(x):
    """g2, with the -3 that puts the normal distribution at zero."""
    x = np.asarray(x, float)
    xbar, s = x.mean(), x.std(ddof=1)
    return ((x - xbar) ** 4).mean() / s ** 4 - 3

excess_kurtosis(stack_loss)
np.float64(0.13435238060300536)

If \(\vert g_{2} \vert > 4\sqrt{6/n}\), then the data distribution is substantially kurtic.

# Renewable share: symmetric, but far from normal in the tails
ener = pd.read_parquet("data/spine/angle_a_country.parquet")
renew = ener["share_renew"].dropna()

excess_kurtosis(renew)
np.float64(-0.6560298273186116)
4 * np.sqrt(6 / len(renew))
np.float64(0.47866161858603057)

Conclusion

Conclusion

  • We have seen the basic concepts of exploratory data analysis
  • We have seen the basic concepts of measuring the center, spread and shape of a distribution
  • Every number today described one variable at a time
  • Session 03 puts two variables in the same sentence: it fits the smallest possible model, and then asks whether that model can be trusted

Before the next session

Required: the next session’s article, its Dataverse package, and the self-check. That is the pre-session deck.

Optional: the QMIB Lab for this session — a knowledge check on the hour you have just sat through: warin.ca/qmib-labs

Never a prerequisite, never marked for correctness. A completed report counts toward participation because attempting it is the engagement being measured.