◆ EXPLORATORY DATA ANALYSIS · CLINICAL CARDIOLOGY ◆

Heart Disease Prediction

Advanced, Statistically Rigorous EDA · UCI Cleveland Dataset · 303 Patients

🫀 Cardiology 📊 Binary Classification 🧪 Statistical Testing 🔬 Clinical Insights
Dataset
UCI Heart Disease
Records
303 patients
Features
13 clinical
Target
Binary (0/1)
▸ PROBLEM CONTEXT

Cardiovascular disease kills 17.9 million people annually — 32% of all global deaths (WHO, 2023). This notebook performs a deep, statistically validated EDA on the UCI Cleveland dataset to discover which clinical markers most strongly predict coronary artery disease (CAD), forming the analytical foundation for a robust ML pipeline.

◆ TABLE OF CONTENTS

Data Foundation

1 · Environment Setup

2 · Data Ingestion & Schema

3 · Data Quality Audit

Univariate Exploration

4 · Continuous Feature Distributions

5 · Categorical Feature Frequencies

6 · Target Class Balance

Bivariate & Statistical

7 · Continuous vs Target (Mann-Whitney U)

8 · Categorical vs Target (Chi-Square)

Multivariate & Advanced

9 · Correlation & Multicollinearity

10 · Outlier & Skewness Analysis

11 · Feature Engineering Preview

12 · Clinical Conclusions

01

Environment Setup

We import all dependencies in one cell and configure the global plotting style to a dark jade green theme. A unified colour palette ensures visual consistency across every subsequent chart — a hallmark of professional analytical work. The deep dark background (#FFFFFF) provides excellent contrast for the jade/emerald accent colours without causing eye strain.
Libraries imported | Jade theme active | Dark mode on
  NumPy 1.26.4  |  Pandas 3.0.3  |  Seaborn 0.13.2
02

Data Ingestion & Schema

We load the dataset and define a semantic feature taxonomy. This is a critical step that beginners often skip — confusing a categorical integer (like cp = 0,1,2,3) for a continuous variable leads to incorrect statistical analyses and misleading visualisations.
Dataset shape : 303 rows x 14 columns
Memory usage  : 33.3 KB
age sex cp trestbps chol fbs restecg thalach exang oldpeak slope ca thal target
0 63 1 3 145 233 1 0 150 0 2.3 0 0 1 1
1 37 1 2 130 250 0 1 187 0 3.5 0 0 2 1
2 41 0 1 130 204 0 0 172 0 1.4 2 0 2 1
3 56 1 1 120 236 0 1 178 0 0.8 2 0 2 1
4 57 0 0 120 354 0 1 163 1 0.6 2 0 2 1
5 57 1 0 140 192 0 1 148 0 0.4 1 0 1 1
6 56 0 1 140 294 0 0 153 0 1.3 1 0 2 1
7 44 1 1 120 263 0 1 173 0 0.0 2 0 3 1
Semantic Type Clinical Description
Feature
age Continuous Patient age in years
sex Binary 1 = Male, 0 = Female
cp Nominal Chest-pain type: 0=typical angina, 1=atypical,...
trestbps Continuous Resting blood pressure at admission (mm Hg)
chol Continuous Serum cholesterol (mg/dl)
fbs Binary Fasting blood sugar > 120 mg/dl (1 = True)
restecg Nominal Resting ECG result (0=normal, 1=ST-T abnormali...
thalach Continuous Maximum heart rate achieved in stress test (bpm)
exang Binary Exercise-induced angina (1 = Yes)
oldpeak Continuous ST depression induced by exercise relative to ...
slope Ordinal Slope of peak-exercise ST segment (0=up, 1=fla...
ca Ordinal Number of major vessels coloured by fluoroscop...
thal Nominal Thallium stress test result (0=normal, 1=fixed...
target Binary Heart disease present (1) or absent (0) — pred...
03

Data Quality Audit

A professional EDA always starts by interrogating data quality before visualisation. We check three categories: duplicates, missing values, and clinically implausible ranges. Findings here directly influence the preprocessing pipeline.
WARNING: 1 duplicate row(s) found and removed.
No description has been provided for this image
Total missing cells: 0  |  All columns complete!

Feature            Min      Max  Low_viol  Hi_viol      Status
----------------------------------------------------------------
age              29.00    77.00         0        0          OK
trestbps         94.00   200.00         0        0          OK
chol            126.00   564.00         0        0          OK
thalach          71.00   202.00         0        0          OK
oldpeak           0.00     6.20         0        0          OK
04

Continuous Feature Distributions

Each continuous feature is displayed with a dual-panel view:
  • Histogram + KDE — shows shape, mean (amber), median (white), shaded ±1σ region, and a stats annotation box
  • Q-Q Plot — tests normality; points on the reference line = Gaussian, deviations = skew/heavy tails
Why Q-Q plots? Many ML pipelines apply StandardScaler assuming Gaussian input. Q-Q plots reveal departures from normality that demand Yeo-Johnson transforms instead.
  Mean Median Std Min Max Skewness Kurtosis CV (%)
Feature                
age 54.42 55.50 9.05 29.00 77.00 -0.20 -0.54 16.60
trestbps 131.60 130.00 17.56 94.00 200.00 0.72 0.89 13.30
chol 246.50 240.50 51.75 126.00 564.00 1.15 4.45 21.00
thalach 149.57 152.50 22.90 71.00 202.00 -0.53 -0.08 15.30
oldpeak 1.04 0.80 1.16 0.00 6.20 1.27 1.52 111.40
No description has been provided for this image
Key Findings:
  • age: Nearly symmetric — StandardScaler is appropriate
  • trestbps: Right-skewed (hypertensive tail) — Yeo-Johnson recommended
  • chol: Heavily right-skewed with extreme outliers >400 mg/dl — Box-Cox/log transform essential
  • thalach: Slightly left-skewed — StandardScaler acceptable
  • oldpeak: Strongly right-skewed (most patients = 0) — Yeo-Johnson required (handles zeros)
05

Categorical Feature Frequencies

Horizontal bar charts are used — a deliberate design choice since long category labels are readable without rotation. Each bar shows both raw count and percentage for full context at a glance.
No description has been provided for this image
06

Target Class Balance

Class imbalance is one of the first critical checks before training any classifier. A balanced dataset (~50/50) allows standard accuracy metrics to be trustworthy without corrective strategies like SMOTE or class weighting.
  Class 1 (Heart Disease  ): 164 samples  (54.3%)
  Class 0 (No Disease     ): 138 samples  (45.7%)
  Balance ratio: 0.841  |  Well balanced - no resampling needed.
No description has been provided for this image
07

Continuous Features vs Target — Mann-Whitney U

Why Mann-Whitney U instead of t-test?
Since several features (especially oldpeak, chol) are non-normally distributed (confirmed by Q-Q plots), Student's t-test assumptions are violated. Mann-Whitney U is a non-parametric rank-based test that makes no distributional assumptions — the statistically correct choice here.

The violin + KDE comparison design simultaneously shows distribution shape and summary statistics — significantly more informative than a plain box-plot.
No description has been provided for this image
Mann-Whitney U Test Results:
           U-stat   p-value Significance  Effect Size (d)  Disease Mean  No-Disease Mean
Feature                                                                                 
age       14394.0  4.63e-05  p<0.001 ***            0.444         52.59            56.60
trestbps  12931.0  3.22e-02     p<0.05 *            0.293        129.25           134.40
chol      12850.5  4.24e-02     p<0.05 *            0.163        242.64           251.09
thalach    5725.0  1.40e-13  p<0.001 ***            0.842        158.38           139.10
oldpeak   16722.5  3.35e-13  p<0.001 ***            0.860          0.59             1.59
08

Categorical Features vs Target — Chi-Square

100% Stacked Bars with Chi-Square + Cramer's V
Stacked bars normalised to 100% allow direct visual comparison of disease proportions regardless of group size. Cramer's V measures practical significance beyond the raw p-value.
No description has been provided for this image
Chi-Square Test Results:
          Chi2  df   p-value  Cramer's V  Sig
Feature                                      
thal     84.61   3  3.15e-18       0.529  ***
cp       80.98   3  1.89e-17       0.518  ***
ca       73.69   4  3.77e-15       0.494  ***
exang    55.46   1  9.56e-14       0.429  ***
slope    46.89   2  6.58e-11       0.394  ***
sex      23.08   1  1.55e-06       0.276  ***
restecg   9.73   2  7.71e-03       0.179   **
fbs       0.09   1  7.61e-01       0.017   ns
09

Correlation & Multicollinearity

No description has been provided for this image
High inter-feature correlations (|r| > 0.5):
  oldpeak    vs slope       r = -0.576
10

Outlier & Skewness Analysis

IQR-based outlier detection plus a side-by-side comparison of before and after Yeo-Johnson transform to demonstrate why power transforms are essential for skewed clinical measurements.
Feature           Q1     Q3    IQR   Lo_Fence  Hi_Fence   #Out   Pct%
---------------------------------------------------------------------------
age            48.00  61.00  13.00      28.50     80.50      0   0.0%
trestbps      120.00 140.00  20.00      90.00    170.00      9   3.0%
chol          211.00 274.75  63.75     115.38    370.38      5   1.7%
thalach       133.25 166.00  32.75      84.12    215.12      1   0.3%
oldpeak         0.00   1.60   1.60      -2.40      4.00      5   1.7%
No description has been provided for this image
No description has been provided for this image
11

Feature Engineering Preview

EDA findings motivate three clinically-grounded engineered features:
  • hr_reserve_pct — percentage of age-predicted max HR achieved (lower = impaired cardiac response)
  • ischaemia_load — oldpeak x (1 + exang): combined ischaemic burden score
  • chol_age_ratio — age-adjusted cholesterol burden
Feature-Target Correlation (engineered features highlighted):
  [NEW]  ischaemia_load          |r| = 0.481
         oldpeak                 |r| = 0.429
         thalach                 |r| = 0.420
  [NEW]  hr_reserve_pct          |r| = 0.363
         age                     |r| = 0.221
         trestbps                |r| = 0.146
  [NEW]  chol_age_ratio          |r| = 0.092
         chol                    |r| = 0.081
No description has been provided for this image
12

Clinical Conclusions & Modelling Recommendations

DATA QUALITY FINDINGS
Strengths
  • Zero missing values in any column
  • No clinically implausible range violations
  • Near-perfect class balance (54.6% / 45.4%)
  • 1 duplicate row removed
Cautions
  • Small dataset (302 rows) — high variance risk
  • 3 features are right-skewed — need transforms
  • Outliers in chol/trestbps — robust scaling
  • fbs is NOT a significant predictor
STRONGEST PREDICTORS (STATISTICALLY VALIDATED)
thal
Cramer's V = 0.52
cp
Cramer's V = 0.49
thalach
Mann-Whitney ***
oldpeak
Mann-Whitney ***
PREPROCESSING PIPELINE
Continuous: age, trestbps*, chol*, thalach, oldpeak* --> [Yeo-Johnson*] --> StandardScaler
Nominal: cp, restecg, thal --> OneHotEncoder(drop='first')
Binary: sex, fbs, exang --> PassThrough
Ordinal: slope, ca --> PassThrough
Engineered: hr_reserve_pct, ischaemia_load --> StandardScaler
fbs EXCLUDED: chi-square p=0.76, Cramer's V = 0.02
Recommended Models: SVM-RBF (maximise Recall) · Random Forest (feature importance) · XGBoost (best F1) · Logistic Regression (baseline)
Evaluation: Stratified 5-Fold CV · Primary = Recall (Class 1) · Secondary = F1-macro · Threshold tuning via PR curve

This EDA establishes a statistically rigorous, clinically grounded foundation for building a high-performance heart disease prediction model.
All feature decisions, transformations and model choices are evidence-driven — not arbitrary.
Authored as part of a professional data science portfolio — Kaggle & Upwork.