Written research-methods assignments and reproducible data-analysis scripts — an independent, from-scratch implementation of 17-803 — Empirical Methods (Carnegie Mellon University, instructor Bogdan Vasilescu), part of a csdiy.wiki full-catalog build.
17-803 is CMU's graduate course on empirical research methods for software engineering: formulating research questions and theory, qualitative interviewing and coding, survey and experiment design, statistics, regression and mixed-effects modeling, and quasi-experimental causal inference (interrupted time series, difference-in-differences, synthetic control). It is a research-methods course, so this repository is a solution portfolio with two halves:
- Reproducible data-analysis scripts (
analyses/) that port the course's hands-on R solution notebooks to Python (pandas+statsmodels) and run on the course's real datasets, reproducing the R reference numbers. - Rigorous written assignments (
writeups/) covering the non-computational deliverables (study design, sampling, validity, qualitative coding, surveys, meta-analysis), grounded in the course's actual lecture topics and reading list.
The course publishes worked solutions as rendered R notebooks (e.g.
typingSpeed.pdf, GaltonFams.pdf, zscore.pdf, its.pdf); this repo treats
those as the ground truth and pins every Python port to their exact numbers
with a pytest suite.
Every number below is produced by a script in analyses/ and saved under
results/. Values match the course's R solution notebooks (verified by
tests/).
| Analysis | What it demonstrates | Key measured result (matches R) |
|---|---|---|
typing_speed |
Simpson's paradox; fixed- & mixed-effects | Pooled slope −0.63823, R² 0.4253, RSE 0.6605 (5 sig figs vs R); within-person slope flips positive |
regression_galton |
OLS build-up, standardized β, family LMM | childHeight~gender+father+mother: father 0.39284, mother 0.31761, R² 0.6354; family LMM R²m 0.630 / R²c 0.701 |
zscore_standardization |
standardized coefficients + VIF | scale(YearsEdu) $103.84 vs scale(Knowledge) $63.18/SD; VIFs all < 1.8; collinear-toy VIF 113.70 |
interrupted_time_series |
segmented regression + DiD | Durbin–Watson ≈0.20 (autocorrelation flagged); ITS-with-control treated effect ≈ −0.25, R² 0.988 |
Figures (in results/): Simpson's-paradox by-participant scatter, Galton
regression-to-the-mean, z-score distributions & standardized β bar chart, ITS
single-series segmented fit, and ITS treated-vs-control series.
Within each participant (colored lines) faster typing → more typos, yet pooling across participants the relationship reverses — the paradox a naive regression would get backwards.
Data-analysis scripts (verified reproductions of the course R notebooks):
- Typing Speed — Simpson's paradox, fixed-effects, and random-intercept
mixed models (
analyses/typing_speed/). - Galton Families regression — intercept-only → gender → multiple →
standardized → family random-effects LMM (
analyses/regression_galton/). - Standardized regression & multicollinearity — z-scored coefficients and
VIF on the Wooldridge WAGE2 data (
analyses/zscore_standardization/). - Interrupted time series — segmented regression, Durbin–Watson
autocorrelation, and ITS-with-control / difference-in-differences
(
analyses/interrupted_time_series/).
Written research-methods assignments (writeups/):
- 01 — Research questions & the role of theory.
- 02 — Interviewing & qualitative coding / thematic analysis (with a full worked thematic analysis).
- 03 — Survey design & mixed methods.
- 04 — Designing experiments, power analysis, & the four validity types.
- 05 — Regression, time series & causal inference (analytical companion to the code).
- 06 — Literature review, systematic review & meta-analysis.
cmu-17803-empirical/
├── analyses/
│ ├── typing_speed/typing_speed.py
│ ├── regression_galton/galton_regression.py
│ ├── zscore_standardization/standardization.py
│ └── interrupted_time_series/its_analysis.py
├── writeups/ # six written research-methods assignments (md)
├── src/empirical_common.py # shared data/results/plotting helpers
├── scripts/download_data.py # fetches course datasets at runtime
├── tests/test_analyses.py # pins every port to the R reference numbers
├── results/ # measured outputs: *.txt logs + *.png figures
├── data/ # datasets land here (gitignored, not redistributed)
├── requirements.txt
└── LICENSE
# Python repos use the shared csdiy env (Python 3.11):
# D:\Project\_csdiy\.venv-ml\Scripts\python.exe
python -m pip install -r requirements.txt # or reuse the shared venv
# 1. fetch the real course datasets (not redistributed in this repo)
python scripts/download_data.py
# 2. run each analysis (writes logs + figures to results/)
python analyses/typing_speed/typing_speed.py
python analyses/regression_galton/galton_regression.py
python analyses/zscore_standardization/standardization.py
python analyses/interrupted_time_series/its_analysis.py
# 3. verify every result against the course's R solution numbers
python -m pytest tests/ -vThere is no autograder for this research-methods course; the course's own rendered R solution notebooks are the ground truth. Verification here is threefold:
- Numeric reproduction. Each analysis prints numbers that match the R
notebooks — e.g. the typing-speed pooled fit matches
typingSpeed.pdfto five significant figures (intercept −0.09850, slope −0.63823, R² 0.4253); the Galton multiple regression matchesGaltonFams.pdfexactly (father 0.39284, mother 0.31761, R² 0.6354); WAGE2 standardized/VIF values matchzscore.pdf(VIF collinear toy = 113.6997). - A pytest suite (
tests/test_analyses.py, 9 tests passing) that asserts these reference values, so any drift fails CI. - Saved evidence in
results/— text logs of every model summary plus the generated figures.
$ python -m pytest tests/ -v
tests/test_analyses.py::test_typing_pooled_matches_R PASSED
tests/test_analyses.py::test_typing_within_between_signs PASSED
tests/test_analyses.py::test_galton_gender_model PASSED
tests/test_analyses.py::test_galton_multiple_regression PASSED
tests/test_analyses.py::test_galton_standardized_betas PASSED
tests/test_analyses.py::test_wage_unstandardized PASSED
tests/test_analyses.py::test_wage_standardized_edu_vs_exp PASSED
tests/test_analyses.py::test_wage_vif PASSED
tests/test_analyses.py::test_its_with_control_effect PASSED
======================= 9 passed =======================
Python 3.11 · pandas · numpy · scipy · statsmodels (OLS, MixedLM, VIF,
Durbin–Watson) · matplotlib · pytest. The original course solutions are in R
(lm, lme4::lmer, car::vif, lmtest::dwtest); this repo re-derives the same
results with the Python scientific stack.
- Simpson's paradox is real and dangerous: pooling clustered data can reverse
the sign of an effect; mixed-effects models (
speed_Mbetween vs.speed_Ewithin) recover the truth. - Standardization makes coefficients comparable across scales, and VIF diagnoses when multicollinearity makes a coefficient split meaningless.
- Regression is descriptive, not causal, unless the design earns causal language — which is why the four validity types and randomization matter.
- Quasi-experiments (segmented ITS, difference-in-differences, synthetic control) enable causal inference from observational time series when randomization is impossible — and autocorrelation is their signature threat (Durbin–Watson, Newey–West).
- The same inverse-variance / within-plus-between-variance structure recurs across mixed-effects models and random-effects meta-analysis — one idea, many guises.
Datasets are downloaded at runtime by scripts/download_data.py and are
not redistributed in this repository:
typingSpeed.csv,its_with_control.csv— from the official course repo bvasiles/empirical-methods.GaltonFamilies.csv— public-domain HistData dataset (Galton, 1886), via the Rdatasets mirror.wage2.csv— the Wooldridge WAGE2 econometrics teaching dataset, from the exact source (murraylax.org) the course notebook downloads from.
Based on the assignments and R solution notebooks of 17-803 Empirical Methods by Bogdan Vasilescu (Carnegie Mellon University). Course site: https://bvasiles.github.io/empirical-methods/. This repository is an independent educational reimplementation; all course materials, datasets, and specifications belong to their original authors. Original code in this repo is released under the MIT License.
