Before you start · The three weeks · Course map · The capstone · What it uses · Series front page
Three weeks from a fitted line to a three-model comparison on data you have never seen, with every model tested on rows it did not learn from and every finding drawn as a chart.
On day one you take Course 1's line of OAS on rating score and treat it as a model: fitted on training rows, judged on rows it never saw, with its error in bp. Three weeks later you fit and read regressions and classifiers, choose a threshold for the recall a desk asks for, prune a decision tree, validate a model on dated data with no lookahead, group bonds and issuers with clustering, and summarise the Treasury curve's history with PCA. Then a public file of Polish company statements arrives, and you compare three models on it, choose one with reasons, and write what it shows and where it fails.
That is the course: models fitted, tested, and read honestly, on data that is described, never forecast.
Every model in this course describes a dataset. Nothing in it is a forecast, a rating, or a lending rule. A fitted spread is the model's spread for a bond with those characteristics, never a fair value; a probability on the card file is a number about that file, never a credit decision about a person; a Treasury model describes the file's own past and is never fitted for a date after its last row.
Each notebook is one problem worked from start to finish: a problem statement, the data, the charts, a model, its score on rows it never saw, and what it shows. There is no helper module to build in this course. The few functions a week reuses are defined on the page, where you can read every line.
Four habits run through all of it.
| Habit | What it means |
|---|---|
| Test rows stay closed | The split comes first. Scaling, encoding, imputation, thresholds, and settings are fitted on training rows only, and the test rows are opened once, for the reported numbers. |
| Predict, then run | Three to five times a notebook stops and asks you to write down a number or sketch a chart before the cell that answers it. The answer is never on the page before the question. |
| The same answer on every run | One seed, SEED = 42, and one thread for the maths libraries, so a rerun prints the same numbers. |
| Describe, never forecast | Every model's output has a plain name and a list of names it is never given. Case studies end with where the model fails, not with a recommendation. |
You need Courses 1 to 3, or the same ground: pandas and matplotlib, writing a function, and Course 3's dated data with its no-lookahead rule. This is the fourth course in Python for Fixed Income.
Status: 14 of 14 notebooks are ready, and so is the capstone.
This course is educational content created in a personal capacity. Nothing here is investment advice or a recommendation to buy or sell any security. All portfolio data is synthetic.
Setup is on the series front page. Course 4 runs in the same .venv as Courses 1 to 3.
| Step | What to do |
|---|---|
| Install the course's packages | With the course's .venv active, run the install line below. It adds scikit-learn, statsmodels, scipy, ipywidgets, and plotly. |
| No API key | This course needs no key and no account. Every dataset is in the repo. |
| Or use Colab | Open any notebook in the course map and click the Open in Colab badge. Colab's library versions can differ from the pins, so a printed number may differ in its last digits. |
Set-Location "$HOME\projects\python-fixed-income"
.venv\Scripts\Activate.ps1
python -m pip install -r course04_machine_learning\requirements.txtEach notebook reads its data from the repo's data folder, or from GitHub in Colab, and writes no file.
Each day's folder holds three files with the same name: the notebook, a short overview PDF to read first, and a solutions notebook. How a day works explains the pattern. Every notebook in this course follows one ladder: a problem statement (the business context, the objectives, and the data dictionary), then numbered sections from Setting Up to Insights and Conclusion, then what you can now do and the exercises, with the AI check last: an answer written in the style of an AI assistant that runs and has one bug to find. Every model is shown, not only printed: ten or more charts and pictures on a teaching day, a confusion matrix drawn to scale, ROC and precision-recall curves with the chosen threshold marked, residual plots, and comparisons as charts. Most days have a slider or a dropdown to move, with a still picture under it for where a widget cannot run.
| Week | Theme | By the end you can |
|---|---|---|
| 1 | Regression on the spread cross-section | Split, fit, and score a spread regression in bp; read coefficients, p-values, and VIFs; check the assumptions behind them; work in log spreads; and use ridge and lasso inside a pipeline that fits every step on training rows |
| 2 | Classification on the card file | Fit a logistic regression and read odds ratios, build a confusion matrix, say why 78 percent accuracy can catch no defaults, choose a threshold on validation rows, prune and read a decision tree, and open the test rows once in a case study |
| 3 | Dated data, unsupervised learning, and the capstone | Validate on dated rows with walk-forward splits and no lookahead, scale and cluster bonds and issuers and profile the groups in their own units, describe the curve with PCA, and compare three models on a file you have not seen |
| Day | Notebook | You learn | Status |
|---|---|---|---|
| 1 | The ML Workflow and Simple Regression | A full regression workflow on 821 bonds: data overview, exploratory charts, three simple regressions of OAS (rating score, duration, coupon) with their equations and fitted lines, R-squared, MAE, RMSE, MAPE, and adjusted R-squared on training and test bonds, a model that memorises, and residuals | Ready |
| 2 | Multiple Regression and Dummy Variables | Two features and a fitted plane, then a rating as 17 dummy steps from a named reference level: a staircase against Day 1's straight line, one bond's spread built as a waterfall, the dummy trap, sector held against rating, adjusted R-squared, and residuals before and after | Ready |
| 3 | Coefficients, P-Values, and Multicollinearity | An error bar on every coefficient: standard errors, t, p-values and 95 percent intervals in statsmodels, a forest plot of the rating steps, what 1,000 noise columns do to a 0.05 test, the joint F-test on sector, two near-copies of a bond's length and the VIF that catches them, and error bars checked by resampling the bonds | Ready |
| 4 | Regression Assumptions and Log Spreads | The assumptions under a regression's error bars, tested on Day 3's model: linearity with a lowess line, constant variance with Breusch-Pagan, normality with a Q-Q plot, why a spread model fans in bp, a power picked with a slider, the log model scored back in bp, each rating step read as a percent, HC3 error bars checked against refits, and the distressed bonds that bend the checks | Ready |
| 5 | Case Study: Ridge, Lasso, and the Spread Cross-Section | A case study on 30 columns: one pipeline that encodes and scales, least squares against ridge and lasso, coefficient paths as the penalty rises, alpha chosen by five folds of the training bonds, which columns lasso keeps, the rating steps beside the generator's own recipe, whole issuers held back, and where the model fails | Ready |
| Day | Notebook | You learn | Status |
|---|---|---|---|
| 1 | Logistic Regression and Odds | Why a straight line fails on a 0/1 outcome, probability, odds and log odds, the S curve fitted by eye and then by maximum likelihood, odds ratios read with their units, one account scored step by step, statsmodels and scikit-learn side by side, and a 19-column pipeline scored on validation accounts | Ready |
| 2 | Confusion Matrix, Precision, and Recall | A model that flags nobody and why accuracy flatters it, the confusion matrix with its four cells drawn to scale, precision, recall and F1 as 100 accounts, one function that scores any model, and what moving the threshold trades, cell by cell | Ready |
| 3 | ROC Curves and Choosing a Threshold | The ROC curve joined by hand and then drawn at every threshold, AUC as a share of pairs, the precision-recall curve, a threshold chosen by a rule written down first, Youden's J, why the rows that choose cannot report, and one calibration chart | Ready |
| 4 | Decision Trees | A tree as a run of questions, Gini impurity by hand and the split a tree picks, an unlimited tree that memorises, decision-boundary maps at three depths, class weights, pre-pruning by a cross-validated grid search and post-pruning along the alpha path, and what feature importance does and does not say | Ready |
| 5 | Case Study: Credit Card Default | A case study on 30,000 card accounts: heavy tails tamed by a quantile transform inside a pipeline, two logistic models and a tree compared by cross-validation, the tree pruned, thresholds for a recall of 0.70 read off cumulative gains curves, the test rows opened once, the person columns handled in the open, and where the model fails | Ready |
| Day | Notebook | You learn | Status |
|---|---|---|---|
| 1 | Dated Data and Walk-Forward Validation | Why shuffled folds flatter a model on dated rows, walk-forward folds with TimeSeriesSplit, a tree and a line scored fold by fold, new levels and a relationship that drifts, ridge and lasso on near-copy tenors, a feature built from later dates caught by a cut test, and misses that run |
Ready |
| 2 | Scaling and K-Means | Distance and why units decide it, K-means on the file's units and then scaled, the loop stepped through round by round, one start against ten, the elbow against the silhouette, k chosen as a stated judgement, and clusters described in bp, years and notches, never ranked | Ready |
| 3 | Hierarchical Clustering and Cluster Profiling | One row per issuer, bottom-up merges and the dendrogram, where to cut and how wide each band is, four linkages compared, cophenetic correlation, cluster profiles in the file's own units, and K-means set beside the tree | Ready |
| 4 | PCA and t-SNE | PCA on two tenors and then on the whole Treasury curve, the loadings read as level, slope and curvature, curves rebuilt from a few components, the curve's path since 2015, PCA on daily changes, PCA kept inside a pipeline so later dates stay out of every fold, scaling on mixed units, and t-SNE as a picture of neighbours | Ready |
| 5 | Course 4 Capstone | A real file of 5,910 company statements checked, described, prepared without a leak, looked at without its label, and modelled three ways; one model chosen by a criterion fixed first, the test rows opened once, and a written description of what the model shows and where it fails. A worked version sits beside it | Ready |
Day 5 of week 3 is yours, and it is more than one sitting: plan on two or three. A colleague who covers emerging market corporates hands you a public file of Polish companies' financial ratios, each statement flagged by whether the company went bankrupt within a year, and asks which of three standard models best separates them, how well on companies it never saw, and where it fails. Twenty-two questions take you from the raw file to a written description. Nothing is planted in the file: its real missing values, duplicate rows, extreme ratios, and rare outcome are the work.
You describe the file's gaps, copies, and extremes, and look at it without its label using PCA and K-means. You fit a logistic regression and two pruned trees inside pipelines, choose every setting and a threshold for a recall of 70 percent on folds of the training rows, and name one model by a criterion fixed before any model is fitted. Then you open the test rows once, and write what the chosen model leans on, where it is wrong, and what the data cannot support.
| File | What it is |
|---|---|
course4_capstone.ipynb |
The brief, the questions, and a check line for every answer that can be checked. A check compares a fingerprint of your answer with a stored one, so it says correct or not yet and no answer is on the page |
course4_capstone_overview.pdf |
The brief as slides: the problem, the file, and what each part of the work asks |
course4_capstone_solutions.ipynb |
The worked version, with every decision stated. Open it after you finish |
The description you write is about a historical, anonymised dataset. It is not a credit view on any company, and nothing you build is a rating, a credit decision, or a probability of default for any company going forward.
| Tool | Used for | First appears |
|---|---|---|
| scikit-learn | Splits, pipelines, linear and logistic models, trees, cross-validation, clustering, PCA, and t-SNE | Week 1, Day 1 |
| pandas, matplotlib, and seaborn | Tables and charts of every dataset | Week 1, Day 1 |
| ipywidgets | The sliders and dropdowns | Week 1, Day 1 |
| statsmodels | Coefficient tables, p-values, VIFs, residual tests, and the logistic fit read for odds ratios | Week 1, Day 3 |
| scipy | Distributions, normality tests, and hierarchical clustering | Week 1, Day 3 |
| plotly | One chart in three dimensions that you can turn | Week 3, Day 2 |
Exact versions are pinned in requirements.txt.
| Data | Kind | Used in |
|---|---|---|
| The benchmark: 821 bonds of 150 issuers, with the rating scale | Synthetic: invented for this series, spreads generated by tools/make_holdings.py |
Week 1, and days 12 to 14 |
| Default of Credit Card Clients: 30,000 accounts in Taiwan in 2005 | Real, public: Yeh, I. (2009). Default of Credit Card Clients [Dataset]. UCI Machine Learning Repository. https://doi.org/10.24432/C55S3H. Licensed under CC BY 4.0 | Week 2 |
| U.S. Treasury daily par yield curve rates, 2015 to 2026 | Real, public domain | Days 11 and 14 |
| Polish Companies Bankruptcy, 5th year: 5,910 financial statements | Real, public: Tomczak, S. (2016). Polish Companies Bankruptcy [Dataset]. UCI Machine Learning Repository. https://doi.org/10.24432/C5F600. Licensed under CC BY 4.0 | The capstone |
The card accounts describe people, so the four columns about them (sex, education, marriage, age) are never model features, and one section of day 10 describes the chosen model's flags for the two labels of one of those columns, with counts and margins, and recommends nothing. Consumer credit in Taiwan in 2005 differs from US credit, and the Polish companies are one country and period; every notebook that uses them says so. Sources, terms, and changes for every file are in the data page.
Course 5 is Advanced Machine Learning: three weeks of bagging, random forests, AdaBoost, gradient boosting, XGBoost, LightGBM, stacking, honest tuning, feature engineering on financial ratios, rare events, and SHAP values, on Course 4's datasets with its test rows kept closed, and a four-model capstone on a new public file of company ratios. Each of its notebooks writes the helper files it starts from, so you carry nothing over from this course.
Created by Jeff Lenamon
