Contents/ Part XXVII · Capstone Projects: Statistical Testing/ Chapter 163

Which Markers Flag Heart Disease?

Capstone 4. Seven clinical markers, one disease label, and a trap that catches careful people: test enough things and something looks significant by luck alone. We build the full clinical dashboard, compare every marker between healthy and diseased patients, and then correct for testing seven at once, which changes the answer.

⏱️ ~17 min read
🧪 Multiple comparisons
📊 Chapter 163

The last three capstones ran one test each. Real screening studies run many at once: a panel of markers, all compared between the same two groups. That is efficient, and it is dangerous, because every extra test is another chance for pure noise to cross the significance line. This project does the screen properly, builds the dashboard, tests all seven markers, and then applies the correction that keeps the whole thing honest.

The brief
Setting
A cardiac clinic recorded seven routine markers for 575 patients, along with whether each was diagnosed with heart disease.
The question
Which of the seven markers actually differ between healthy and diseased patients?
Why it matters
Markers that survive scrutiny go into a screening protocol. Markers that do not are false leads that cost patients follow-up tests they never needed.
What we do
Run the two-group comparison seven times, show how the false-positive rate compounds across a family of tests, apply the Holm correction, and report which markers survive as intervals rather than as verdicts.
The multiple-comparisons problem: with a 5% false-positive rate per test, running many tests makes a family-wise false alarm almost inevitable. Corrections like Bonferroni (use α/k) and Holm raise the bar so the whole set of tests still has about a 5% chance of any false positive.
🫀
The finding, up front

Two markers truly separate the groups: Age and Cholesterol, both large and unmistakable. Blood pressure looked significant too (p = 0.02), which is tempting to believe, but it is a false alarm from testing seven markers, and it vanishes under correction. Age and cholesterol are the only two left standing.

1

The Question and the Design

A cardiac clinic recorded seven routine markers for 575 patients, along with whether each was diagnosed with heart disease. The screening question is: which markers actually differ between healthy and diseased patients? For each marker on its own this is the two-group comparison from Capstone 2. The new element is that we ask it seven times, which is where the trouble starts.

Framework stepThis project
GoalIdentify which of seven markers separate the healthy and disease groups.
HypothesesFor each marker, H₀: the healthy and disease means are equal. Seven tests, one family.
Data typeSeven continuous markers, one binary outcome (Disease).
DesignObservational cohort. Two independent groups per marker, tested and then corrected together.
2

The Clinical Dashboard

Before any test, four views answer most of the "what is going on here" questions: the age split by disease, a scatter of two markers colored by disease, the spread of every marker by group, and a correlation matrix that includes the disease label itself.

A four-panel clinical dashboard. Top-left: histograms of age by disease status, with the disease group clearly shifted to older ages. Top-right: a scatter of BMI versus systolic blood pressure colored by disease, forming one overlapping cloud with no separation. Bottom-left: standardized boxplots of all seven markers by group, where only Age and Cholesterol show a visible gap between the healthy and disease boxes. Bottom-right: a correlation matrix; in the Disease row, Age is 0.55 and Cholesterol is 0.42, while every other marker is near zero.
The four panels tell one story. Age (top-left) separates the groups clearly; the BMI-vs-blood-pressure cloud (top-right) does not. The standardized boxplots (bottom-left) show a visible gap only for Age and Cholesterol, and the correlation matrix (bottom-right) makes it numeric: in the Disease row, Age sits at 0.55 and Cholesterol at 0.42, while every other marker hovers near zero. Two signals, five quiet markers, which the formal screen now has to confirm without being fooled.
3

The Multiple-Comparisons Problem

Here is the trap. If a marker has no real association, a single test still calls it "significant" about 5% of the time by chance. Run that test seven times and the chance that at least one harmless marker lights up climbs fast, to about 30%.

Test more things, and a false alarm becomes likely 50% 25% 5%1 test 14%3 tests 23%5 tests 30%7 tests (ours) 40%10 tests Bonferroni fix: raise the bar to p < α/k = 0.05/7 = 0.007 per test

The cure is to raise the bar. Bonferroni divides the threshold by the number of tests, so here a marker must clear p < 0.05 / 7 = 0.007, not 0.05, to count. Holm gives the same protection while rejecting slightly more true effects. We apply both to the seven p-values at once and see what survives.

4

The Corrected Screen

Each marker gets a Welch two-sample t-test (healthy vs disease), with its effect size, and then the whole set of p-values is corrected together. Ranked by effect size, the result is stark.

MarkerHealthyDiseasep (raw)Cohen's dAfter correction
Age47.561.7< 0.0011.34survives ✓
Cholesterol197.8234.6< 0.0010.95survives ✓
Systolic BP129.7126.70.0210.20false alarm ✗
Diastolic BP82.083.20.1740.11not significant
Heart Rate74.973.80.2080.11not significant
Glucose97.498.80.4430.06not significant
BMI27.627.60.9190.01not significant

Read it top to bottom. Age (Cohen's d about 1.3) and Cholesterol (d about 0.95) are in a different league, and both clear even the strict Bonferroni bar. Now look at Systolic BP: its raw p-value is below 0.05, so a naive reading calls it "significant", yet its effect size is tiny and it does not survive correction. It is the false alarm the previous section predicted, and blood pressure is exactly the marker a reader expects to matter for heart disease, which is what makes it such a convincing trap.

A horizontal bar chart of effect size (Cohen's d) per marker, sorted. Age (about 1.34) and Cholesterol (about 0.95) are drawn in green and labeled 'survives correction'. Systolic BP (about 0.20) is gold and labeled 'raw-significant only (false alarm)'. Diastolic BP, Heart Rate, Glucose, and BMI are short gray bars labeled 'not significant'.
Effect size per marker. Green markers survive correction for seven tests; the gold bar (Systolic BP) is significant only until you account for multiple comparisons; the gray bars never reached significance. Effect size and correction together separate two real signals from five quiet markers.
Two habits, one honest screen

First, correct for the number of tests, so a lone chance crossing does not get reported as a discovery. Second, read the effect size, not just the p-value: Systolic BP's d of 0.2 was never worth much even before correction. Reporting the one marker that crossed 0.05 out of seven, and staying quiet about the other six, is exactly how false findings reach print.

5

The Verdict, and Why Association Is Not Cause

Two markers genuinely distinguish diseased from healthy patients here: age and cholesterol. But this is observational data, a snapshot of who has the disease, with no intervention, so a real association is still a long way from a cause. The clearest reason is confounding, and age is the obvious culprit.

Age is a confounder: it lifts both the marker and the disease Age a marker (cholesterol) heart disease observed association part of the marker's link to disease is just age riding along; to separate them, adjust for age (regression), not seven separate tests
6

Multiple Comparisons in Data Science & AI

The moment you test many things at once, this problem appears, and modern data work tests a great many things.

Where it appearsThe many tests
Feature screeningChecking hundreds of features for association with a target; some will look predictive by chance.
A/B testingWatching many metrics or many segments on one experiment inflates the odds of a spurious "win".
Model comparisonBenchmarking many models on one test set; the apparent best can be luck without correction.
Genomics and beyondThousands of tests at once, where corrections (and the false discovery rate) are standard practice.
Practice note

When the number of tests is huge, controlling the family-wise error with Bonferroni gets too conservative, and teams switch to controlling the false discovery rate (the Benjamini-Hochberg procedure), which limits the share of "discoveries" that are false rather than the chance of any false positive. The instinct is the same one this capstone teaches: the more you test, the higher your bar has to be.

7

The Correction, Seen as Intervals

Multiple-comparison corrections are usually presented as a shrinking p-value threshold, which is abstract. The same correction has a concrete visual form: the confidence intervals get wider. Seven markers tested at a family-wise 5 percent means each individual interval must be a 99.29 percent interval rather than a 95 percent one.

MarkerCohen's d95% CI99.29% CI (adjusted)Verdict
Age+1.34+1.16 to +1.52+1.09 to +1.59survives
Cholesterol+0.95+0.78 to +1.12+0.71 to +1.19survives
Systolic BP−0.20−0.36 to −0.03−0.42 to +0.03crosses zero
Diastolic BP+0.11−0.05 to +0.28−0.11 to +0.34never significant
Glucose+0.06−0.10 to +0.23−0.16 to +0.29never significant
Heart rate−0.10−0.27 to +0.06−0.33 to +0.12never significant
BMI+0.01−0.16 to +0.17−0.22 to +0.24never significant
A forest plot of seven markers. Each has a thick bar for its 95 percent interval and a thin bar for the wider 99.29 percent adjusted interval. Age and cholesterol sit far to the right of the dashed zero line under both. Systolic BP's thick bar is entirely left of zero while its thin bar crosses it.
Thick bar = the ordinary 95% interval. Thin bar = the 99.29% interval a family of seven demands. Systolic blood pressure is the case to study: its thick bar clears zero and its thin bar does not. Nothing about the data changed; the standard of evidence did.
The same decision, told a better way

Age and cholesterol are untouched by the widening. Their intervals stay far from zero either way, which is what a robust finding looks like: it does not depend on how generous you are being with the threshold. Systolic blood pressure depends on it entirely. Reporting the intervals rather than the p-values makes that distinction visible to a reader who has never heard of Holm's procedure.

🐍

The full project, step by step

The companion notebook builds the four-panel dashboard, cleans the cohort with a printed audit trail, runs the seven Welch t-tests, applies the Bonferroni and Holm corrections to the whole set with statsmodels, and draws the effect-size screen. It also shows the family-wise-error arithmetic and the point-biserial correlations that tell the same story from the correlation angle. Every number in this chapter comes from its output, with a plain-language note after each result.

📓 View Notebook (code & outputs) ▶ Open in Colab ⬇ View / Download on GitHub
Download the project files

The dataset (capstone-heart-disease-markers.xlsx) holds the cohort on the patients sheet, with a codebook and notes, and keeps the missing values, impossible entries, and duplicate rows so you can practice the cleaning. Two written reports accompany it: a plain-language brief for a clinical audience (which markers are worth pursuing, why blood pressure did not make the cut), and a technical report, a journal-style write-up with full methods, the multiple-comparison correction, the effect-size screen table, and references, including the confounding and false-discovery discussion.

🎓 Key Takeaways

  • Testing many markers inflates false positives: seven tests at 5% give about a 30% chance of at least one false alarm.
  • Correct the whole set: Bonferroni (p < α/k) and Holm keep the family-wise error near 5%.
  • Only Age and Cholesterol survived (d = 1.34 and 0.95); Systolic BP was significant raw (p = 0.02) but a false alarm that correction rejected.
  • Read the effect size, not just the p-value: the false alarm had a tiny effect from the start.
  • Association is not cause: this is observational data, and age confounds the markers, so a regression that adjusts for age is the honest next step.
8

Quiz: Test Yourself

Eight questions on this capstone, from the dashboard to the false alarm. Answer them, hit Check Answers, and keep refining until you score 100%. Your progress is saved.