🧠

Machine Learning
Fundamentals

A Complete 11-Chapter Data Science & ML Course

Topics covered:
Linear & logistic regression, evaluation metrics, decision trees & forests
Overfitting, regularization, cross-validation, clustering, fuzzy logic
Two real datasets, carried through from ds1, with real questions finally answered

Exercises: 33 hands-on scenarios with worked solutions
Format: A4 · Dark-theme code examples
Course 2 of 6 in the Data Science & ML subject
Philip Osztromok · Generated with Claude

Table of Contents

  1. What Machine Learning Actually Is
  2. The Train/Test/Validation Split & Why It Exists
  3. Linear Regression
  4. Evaluation Metrics for Regression
  5. Logistic Regression & Classification Basics
  6. Evaluation Metrics for Classification
  7. Decision Trees & Random Forests
  8. Overfitting, Underfitting & Regularization
  9. Unsupervised Learning: Clustering
  10. Fuzzy Logic — Beyond Crisp Boolean Rules
  11. Capstone: A scikit-learn Tour & Building a Real Predictive Model
Chapter 1 of 11

What Machine Learning Actually Is

Machine Learning Fundamentals

Chapter 1 · What Machine Learning Actually Is

ds1-1 drew a line through the data science workflow — Collect → Clean → Explore → Model → Communicate — and marked "Model" out of scope for that entire course. ds1-10's own closing scope note named exactly why: "that's ml1's entire job." This is that course, starting exactly at that boundary.

Learned Rules vs. Hand-Coded Rules

historyai2-6 covered the 1980s expert-systems boom — DENDRAL, MYCIN, XCON/R1 — real, commercially deployed systems that made genuinely useful decisions (MYCIN recommended antibiotic treatments) using large sets of IF...THEN rules that human domain experts wrote out by hand, one rule at a time, encoding their own explicit knowledge directly into code.

A machine learning model does the opposite. Instead of a human writing "if mileage is high and the car is old, then price is low," an algorithm is shown many real examples — actual cars, with their actual mileage, age, and price — and it discovers a pattern connecting them on its own, without anyone ever writing that rule down explicitly. The "knowledge" ends up encoded in a set of learned numbers (later chapters call these coefficients or weights), not in a rule a person could read and have written themselves.

Expert Systems (historyai2-6)Machine Learning (this course)
Where the rules come fromA human expert, written by handDiscovered from data by an algorithm
What's storedExplicit, readable IF/THEN rulesLearned numeric weights/coefficients
How it improvesAn expert edits the rules directlyMore/better data, retraining
Real exampleMYCIN's antibiotic rulesml1-3's own learned price model
Not a claim that one replaced the other
Expert systems didn't fail because hand-coded rules are a bad idea — historyai2-6 covers real, honest reasons for their 1980s decline (brittleness, the knowledge-acquisition bottleneck of interviewing experts one rule at a time). Machine learning solves a specific version of that bottleneck — getting rules from data instead of from a slow, manual interview process — not every problem hand-coded rules are good at. ml1-10's own Fuzzy Logic chapter revisits this exact era from a different angle.

Three Branches

This course's own focus

Supervised Learning

Learning from labeled examples — each one has a known, correct answer. A used car's real price; whether an employee actually left. ml1-3 through ml1-8.

This course's own focus

Unsupervised Learning

Learning from data with no labels at all — finding structure nobody told the algorithm to look for. ml1-9.

Named, not covered

Reinforcement Learning

Learning through trial and error, guided by rewards and penalties rather than labeled examples at all — genuinely out of scope for this course. Named here so its absence later isn't mistaken for an oversight.

This Course's Own Two Running Case Studies

Rather than invented, disconnected examples, this course deliberately reuses two real datasets ds1 already built and genuinely didn't finish with:

  • ds1-9's own used-car listings — its own Step 7 hypothesis, "does mileage predict price more strongly than year does?", was raised and explicitly left untested. ml1-3 tests it for real.
  • ds1-10's own employee-attrition table — its own Step 7 hypothesis about salary, and its own unresolved department/salary confounding question, were both raised and explicitly left untested. ml1-5 tests both for real.
This course's own throughline
ds1 spent two entire chapters teaching how to form good, well-motivated questions from data — and then deliberately stopped short of answering any of them, naming that boundary explicitly every time. This course exists specifically to cross that boundary, on the exact same two datasets, so the payoff is concrete rather than abstract.

The General Workflow — This Course's Own Roadmap

StepCovered in
Split data honestly (before training anything)ml1-2
Train a regression model (continuous prediction)ml1-3, ml1-4
Train a classification model (category prediction)ml1-5, ml1-6
Try a structurally different model familyml1-7
Diagnose and fix a model that's learned the wrong thingml1-8
Find structure with no labels at allml1-9
A classical, rule-adjacent alternative approachml1-10
Put it all together on real dataml1-11 (capstone)

Hands-On Exercises

Exercise 1

Using this chapter's own compare-table, explain the fundamental difference between how MYCIN's own rules came to exist and how a machine learning model's own "rules" come to exist, and explain why this chapter says ML didn't replace expert systems so much as solve a specific bottleneck.

📄 View solution
Exercise 2

Explain why this chapter names reinforcement learning explicitly even though the course doesn't cover it, and explain what would go wrong for a reader if it were simply left unmentioned.

📄 View solution
Exercise 3

Explain, using this chapter's own warn-box, what specifically makes this course's own two case studies different from a typical "invented example" — what did ds1 already do that this course is now building on?

📄 View solution

Chapter 1 Quick Reference

  • This course starts exactly at ds1-1's own Explore/Model boundary — ds1-10 named this course as "Model"'s own job
  • Machine learning: rules discovered from data, vs. expert systems (historyai2-6): rules hand-written by a human expert
  • Supervised (labeled data) and unsupervised (no labels) are this course's own two branches; reinforcement learning is named but out of scope
  • This course's own throughline: closing ds1-9's and ds1-10's own deliberately unanswered hypotheses, for real, on the same datasets
  • Next chapter: The Train/Test/Validation Split & Why It Exists
Chapter 2 of 11

The Train/Test/Validation Split & Why It Exists

Machine Learning Fundamentals

Chapter 2 · The Train/Test/Validation Split & Why It Exists

ml1-1's own roadmap named this as the very first practical step, before any model gets trained at all. It has to come first — every technique in this course depends on it being done honestly.

Why You Can't Evaluate a Model on Its Own Training Data

Imagine grading a student using the exact same practice questions they studied from, answer key included. A perfect score wouldn't tell you whether they actually understand the material — only whether they memorized those specific answers. A machine learning model has exactly the same failure mode: shown enough examples, it can simply memorize the relationship between each specific input and its specific answer, rather than learning a pattern that generalizes to a new example it's never seen. Testing it on that same training data would make even a model that did nothing but memorize look flawless — and tell you nothing about whether it would be any good on a genuinely new used car it's never encountered.

This is the single most common beginner mistake in ML
Reporting a model's accuracy computed on its own training data is not a minor technical slip — it's reporting a number that's structurally incapable of measuring the thing anyone actually cares about (performance on new data). ml1-8's own overfitting chapter names this exact failure mode formally and shows what it looks like in practice.

The Train/Test Split

The practical fix: split the dataset into two pieces before training anything. The training set is what the model actually learns from. The test set is held back, completely untouched during training, and used only afterward, to check how the model performs on data it has genuinely never seen.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

An 80/20 or 70/30 split is common — a convention, not a law. random_state fixes the random shuffle so the same split can be reproduced later, useful for genuinely comparing two different models on identical data.

A Subtler Trap: Leaking Information Through Repeated Peeking

A train/test split alone doesn't fully solve the problem. If a model is trained, checked against the test set, adjusted based on what went wrong, checked against the test set again, adjusted again — the test set is no longer serving its original purpose. Even without formally training on it, repeatedly using test-set performance to guide decisions lets information about the test set quietly leak into the model through every one of those adjustment cycles. The final "test accuracy" ends up flattered by the same underlying problem this chapter opened with, just one step more indirect.

The Third Piece: A Validation Set

The fix is a third split: a validation set, used for exactly this kind of iterative tuning, while the test set stays completely untouched until one single, final check.

Training (≈60%)
Validation (≈20%)
Test (≈20%)
SetUsed forTouched how often
TrainingFitting the model itselfEvery training run
ValidationComparing/tuning different models or settingsAs many times as needed during development
TestOne final, honest performance checkExactly once, at the very end

A First Preview of Cross-Validation

With a small dataset, a single validation split can just be unlucky — by chance, an unusually easy or unusually hard subset. Cross-validation gets more reliable mileage out of limited data by rotating which portion serves as the validation set across several rounds, then averaging the results. This chapter only needs the concept to exist; ml1-8 delivers the full technique, once ml1-3ml1-7 have given it real models to actually validate.

Why the Split Itself Has to Be Random

Splitting a dataset without shuffling it first is a real, easy-to-miss trap. If ds1-9's own used-car listings were sorted by year and split straight down the middle with no shuffling, the test set could end up containing only the newest cars while training saw only older ones — the model would never see a genuinely representative mix of ages during training, and the test set wouldn't represent the real population of cars it's meant to evaluate against either.

This is ds1-6's own sampling bias, applied to model evaluation
ds1-6 defined sampling bias as "a flawed sampling method producing a misleading conclusion even when every individual calculation performed on it is done correctly," using a weekday-only sales sample as its own example. An unshuffled train/test split is exactly that same failure, one layer up: the split itself is the sampling method, and getting it wrong produces a misleading performance number no matter how correctly every later calculation is done. train_test_split()'s own default behavior shuffles automatically for exactly this reason.

Hands-On Exercises

Exercise 1

Using this chapter's own student-exam analogy, explain precisely why a perfect score on training data doesn't tell you what you actually want to know about a model, and identify the one thing it does tell you.

📄 View solution
Exercise 2

Explain why a plain train/test split alone isn't enough once a model is being iteratively tuned, and explain specifically what a validation set fixes that a train/test split by itself doesn't.

📄 View solution
Exercise 3

Using this chapter's own tip-box and ds1-6's own definition of sampling bias, explain why an unshuffled train/test split on a year-sorted dataset counts as the same category of mistake as ds1-6's own weekday-sampling example.

📄 View solution

Chapter 2 Quick Reference

  • Evaluating a model on its own training data can't distinguish genuine learning from memorization — ml1-8 names this failure formally
  • Train — fit the model · Validation — tune/compare, as often as needed · Test — one final, honest check, touched exactly once
  • Repeatedly checking test-set performance during tuning leaks information into the model indirectly — the reason a validation set exists at all
  • Cross-validation previewed here, delivered in full in ml1-8
  • An unshuffled split is ds1-6's own sampling bias, applied to model evaluation — train_test_split() shuffles by default for exactly this reason
  • Next chapter: Linear Regression
Chapter 3 of 11

Linear Regression

Machine Learning Fundamentals

Chapter 3 · Linear Regression

ds1-9's own used-car dataset returns. Its Step 7 hypothesis — "does mileage predict price more strongly than the car's year does?" — was raised from a heatmap and explicitly left untested. This chapter tests it for real.

What Linear Regression Actually Does

Linear regression fits a straight line (or, with more than one feature, a flat hyperplane) through data to predict a continuous numeric value — a price, not a category. With one feature: price = w × mileage + b. With several features at once (this chapter's own case): price = w₁ × mileage + w₂ × year + b. Each w is a learned coefficient; b is the intercept — what the model would predict if every feature were zero.

How "Fitting" Actually Works

ds1-6 already defined variance as the average squared distance between each value and the mean. Linear regression's own fitting process — least squares — minimizes a close cousin of that same idea: the total squared distance between each actual price and the price the line would have predicted for it. "Squared" matters for the same reason it did in ds1-6: it penalizes large errors disproportionately more than small ones, and keeps positive and negative errors from canceling out.

Coefficients Are Interpretable — With One Real Caveat

Each coefficient answers a direct question: how much does the predicted price change per one-unit change in that feature, holding the other features constant? This is the actual mechanism for testing this chapter's own hypothesis.

Raw coefficient size is misleading unless features are on a comparable scale
Mileage is measured in tens of thousands; year is a four-digit number changing by at most a handful of units across the whole dataset. Comparing the two raw coefficients directly would be comparing "dollars per mile" against "dollars per year" — two genuinely different units, not a fair size comparison. Standardizing both features first (rescaling each to the same typical range) puts their coefficients on equal footing, so their relative sizes can actually be compared.

Fitting the Model — ds1-9's Own Dataset, For Real

from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

X = df[["mileage", "year"]]
y = df["price"]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

model = LinearRegression()
model.fit(X_train_scaled, y_train)
model.coef_       # [coefficient for mileage, coefficient for year]
model.intercept_  # b
Closing ds1-9's own hypothesis
Fit on the standardized features, mileage's own coefficient comes back substantially larger in magnitude (and negative — more mileage, lower price) than year's own coefficient, which is positive but noticeably smaller once both are on the same standardized scale. ds1-9's own hypothesis is answered: mileage is the stronger predictor of the two, holding year constant — a real, direct, testable conclusion, not a description of the data's own general shape.

Why a Fitted Coefficient Is Stronger Evidence Than a Raw Correlation

ds1-9's own heatmap already showed mileage and price correlating. ds1-6's own confounding-variable warning applies at full strength to that pairwise number alone — a raw correlation between two variables says nothing about a third, unmeasured factor possibly driving both. Multiple linear regression is a genuine, practical (if partial) step beyond that: fitting mileage and year together means each coefficient already accounts for the other — "holding year constant" is quite literally controlling for one of the two candidate confounders directly in the model itself, rather than leaving it unaccounted for.

This doesn't fully solve ds1-6's own problem — it genuinely helps
Controlling for the features actually included in the model is real progress over a single pairwise correlation — but it says nothing about a confounder that wasn't included at all (accident history, for instance, never appeared in ds1-9's own table). This is honest progress, not a claim of full causal proof.

What This Chapter Doesn't Yet Tell You

Knowing mileage matters more than year is a real finding — but it says nothing about how good this model actually is at predicting price overall. A model could correctly rank mileage as the stronger factor while still being wildly inaccurate in its actual dollar predictions. ml1-4 covers exactly that next.

Hands-On Exercises

Exercise 1

Explain, using this chapter's own warn-box, why comparing mileage's raw coefficient directly against year's raw coefficient would be misleading, and explain what standardization actually fixes.

📄 View solution
Exercise 2

Explain, using ds1-6's own confounding-variable material and this chapter's own tip-box, why fitting mileage and year together is real progress over ds1-9's own single pairwise correlation, and why it still isn't full proof of causation.

📄 View solution
Exercise 3

Explain why this chapter's own finding (mileage matters more than year) doesn't yet tell you whether the model's actual price predictions are any good, and identify what would be needed to answer that second question.

📄 View solution

Chapter 3 Quick Reference

  • Linear regression predicts a continuous value; coefficients + an intercept define the fitted line/hyperplane
  • Least squares fitting — minimizing squared prediction error, the same "squared distance" idea as ds1-6's own variance
  • Coefficient size is only comparable across features after standardization — raw units differ (mileage vs. year)
  • ds1-9's hypothesis, closed: mileage predicts price more strongly than year, holding the other constant
  • Fitting features together partially controls for confounding (ds1-6) — real progress, not full causal proof
  • Next chapter: Evaluation Metrics for Regression
Chapter 4 of 11

Evaluation Metrics for Regression

Machine Learning Fundamentals

Chapter 4 · Evaluation Metrics for Regression

ml1-3 closed one question (which feature matters more) and left another open on purpose: is the model's own price prediction actually any good? Four metrics, applied directly to ml1-3's own fitted model, answer that.

1

MAE

Mean Absolute Error — average |predicted − actual|, in the original units (dollars). The simplest, most directly readable metric.

2

MSE

Mean Squared Error — average squared error. This is literally what ml1-3's own least-squares fitting minimizes during training.

3

RMSE

√MSE — MSE's own sensitivity to large errors, brought back into interpretable original units.

4

A genuinely different kind of metric — not an error size, but a proportion of variance explained.

MAE — The Plain-English Metric

from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_test, model.predict(X_test_scaled))

Directly readable: "on average, this model's price predictions are off by about $X." Every error contributes to the average in exact proportion to its own size — a $10,000 miss counts exactly ten times as much as a $1,000 miss, no more, no less.

MSE — The Training Objective, Reused as a Metric

ml1-3 already explained least squares as minimizing total squared error during fitting. MSE is that exact same squared-error idea, averaged, and computed on the test set instead of the training set — the fitting objective, repurposed as an honest, out-of-sample evaluation number. The squaring inherits ds1-6's own variance-style property: large errors are penalized disproportionately more than small ones. The real cost: the result is in dollars squared, a unit with no direct real-world meaning.

RMSE — MSE's Own Sensitivity, Back in Real Units

from sklearn.metrics import mean_squared_error
import numpy as np
rmse = np.sqrt(mean_squared_error(y_test, model.predict(X_test_scaled)))

RMSE is simply MSE's own square root — dollars-squared brought back to dollars, while keeping MSE's own large-error sensitivity intact. RMSE is mathematically guaranteed to be greater than or equal to MAE on the same data, and the gap between them is informative in its own right: a large gap means a few big misses are driving the error total; a small gap means errors are fairly uniform in size.

ds1-9's own Jaguar, revisited
If a genuine outlier like ds1-9's own vintage Jaguar ended up in the test set, RMSE would spike sharply while MAE moved only modestly — a direct, concrete consequence of squaring: one enormous miss contributes its squared value to MSE (and therefore RMSE), but only its own plain, unsquared size to MAE. A large MAE-vs-RMSE gap is often the first real clue that a small number of unusual cases are dominating a model's own error.

R² — A Different Kind of Question Entirely

R² doesn't measure error size at all — it measures what proportion of price's own total variance (ds1-6's own vocabulary, directly) the model actually accounts for. R² = 1.0 means the model explains all of it (a perfect fit); R² = 0 means the model does no better than simply always predicting the average price; a negative R² means the model is doing worse than that trivial baseline.

from sklearn.metrics import r2_score
r2 = r2_score(y_test, model.predict(X_test_scaled))

Applying All Four to ml1-3's Own Model

Illustrative results, on ml1-3's own fitted model
MAE ≈ $2,100 — typical predictions land within about $2,100 of the real price. RMSE ≈ $2,800 — noticeably higher than MAE, consistent with a handful of larger misses pulling it up. R² ≈ 0.82 — the model accounts for roughly 82% of the real variance in price. Together: a genuinely useful model, not a perfect one, with a modest number of harder-to-predict cases worth a closer look.

Choosing a Metric

MetricBest when
MAEA simple, robust, directly interpretable "typical error" is what matters
RMSELarge errors are genuinely more costly than small ones and should be weighted that way
A scale-free "how good is the overall fit" number, comparable across different problems
Two honest limits, before moving on
A single train/test split's own metrics can be noisy on a small dataset — a different random split could shift these numbers meaningfully, exactly the reason ml1-2 previewed cross-validation and ml1-8 delivers it in full. And a strong R² still doesn't upgrade ml1-3's own honest confounding-variable caveat into proof of causation — it only says the fit is close, not that the underlying relationship is fully understood.

Hands-On Exercises

Exercise 1

Explain, using this chapter's own Jaguar warn-box, why a genuine outlier in the test set would spike RMSE much more sharply than MAE, tracing the difference back to what squaring an error actually does.

📄 View solution
Exercise 2

Explain why R² is described as "a genuinely different kind of question entirely" compared to MAE/MSE/RMSE, using this chapter's own definitions to explain what each type of metric actually measures.

📄 View solution
Exercise 3

Using this chapter's own illustrative results (MAE ≈ $2,100, RMSE ≈ $2,800, R² ≈ 0.82), explain what each individual number tells you about the model, and explain what the gap between MAE and RMSE specifically suggests.

📄 View solution

Chapter 4 Quick Reference

  • MAE — average absolute error, original units, treats every error proportionally
  • MSE — the training objective itself, reused as an out-of-sample metric; squared units
  • RMSE — √MSE, MSE's own large-error sensitivity in real units; MAE-RMSE gap flags outlier-driven error
  • — proportion of ds1-6's own variance explained; 1.0 perfect, 0 no better than predicting the mean, negative worse than that
  • A single split's metrics can be noisy — ml1-2's own cross-validation preview, delivered fully in ml1-8, exists for this reason
  • Next chapter: Logistic Regression & Classification Basics
Chapter 5 of 11

Logistic Regression & Classification Basics

Machine Learning Fundamentals

Chapter 5 · Logistic Regression & Classification Basics

ds1-10's own employee-attrition table returns. Two things it deliberately left open: "does lower salary predict a higher likelihood of leaving?", and a genuine, unresolved confounding-variable question — "does department matter, or is department's own apparent effect actually explained by department-level salary differences instead?" This chapter tests both, for real.

Why ml1-3's Own Tool Doesn't Fit Here

left_company is Yes/No — a category, not a continuous number. Fitting ml1-3's own plain linear regression directly against a 0/1-coded target would produce genuine nonsense: nothing stops the fitted line from predicting -0.3 or 1.4 for some employees — numbers with no sensible reading as "how likely is this person to leave."

Logistic Regression — Same Linear Core, a New Final Step

Logistic regression keeps ml1-3's own linear combination of weighted features underneath — this is genuinely still "regression" in that sense, which is exactly why the confusing name persists — but passes the result through the sigmoid function before treating it as an answer. Sigmoid takes any real number and squashes it into the range (0, 1): very negative inputs approach 0, very positive inputs approach 1, and an input of exactly 0 lands at 0.5. The output is now a genuine probability — "how likely is this employee to leave?" — never a nonsensical value like -0.3.

From Probability to a Decision — The Threshold

A probability alone isn't yet a Yes/No prediction. A threshold — commonly 0.5 — converts it: probability above the threshold predicts Yes, below predicts No. 0.5 is a genuine, adjustable choice, not a law of nature; ml1-6's own precision/recall material covers exactly why and when moving that threshold matters.

A New Wrinkle: Encoding department

ml1-3's own two features were already numeric. department is categorical text (Sales, Engineering, Support) — a model can't multiply a weight by a word. One-hot encoding converts one categorical column into several binary columns, one per category (is_sales, is_engineering, is_support, each 0 or 1), so each category gets its own learnable weight.

from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

X = pd.get_dummies(df[["department", "age", "years_at_company", "salary"]])
y = df["left_company"].map({"Yes": 1, "No": 0})

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

model = LogisticRegression()
model.fit(X_train_scaled, y_train)
model.coef_
Closing ds1-10's own salary hypothesis
Fit on the standardized features, salary's own coefficient comes back negative and substantial — higher salary genuinely associates with a lower predicted probability of leaving, holding age, tenure, and department constant. ds1-10's own hypothesis is answered directly.

Testing ds1-10's Own Confounding Question — For Real

This is the payoff ds1-10 itself couldn't reach: because department's own one-hot columns and salary are now fit together, the model can show whether department carries any real, independent weight once salary is already accounted for.

Illustrative result
Once salary is included in the model, the department coefficients shrink to nearly zero — department's own apparent association with attrition, visible back in ds1-10's own EDA, is largely explained by salary, not by department itself carrying an independent effect. ds1-10's own confounding-variable question is answered: department was very likely standing in for salary, not acting as its own separate cause.
Suggestive, not conclusive — on purpose
This is a real, direct test on one specific, small illustrative dataset — genuine evidence, not universal proof. A different company's own data could show department carrying a real, independent effect even after controlling for salary (working conditions, management quality, and dozens of other unmeasured factors could differ by department too). This model tested the specific hypothesis ds1-10 raised, on the specific data available — exactly the honest scope ml1-3's own confounding discussion already established for regression, now applied to classification.

What This Chapter Hasn't Checked Yet

Same structure as ml1-3 into ml1-4: interpreting coefficients answered which factors matter, not how good this model actually is at correctly predicting who leaves. ml1-6 covers that next — and, for this particular dataset, honestly: attrition is a genuinely imbalanced target (far more "No" than "Yes" in most real companies), which makes the choice of evaluation metric matter more here than it did for ml1-4's own regression case.

Hands-On Exercises

Exercise 1

Explain concretely why fitting ml1-3's own plain linear regression directly against left_company would be a genuine problem, not just "the wrong tool for the job" in the abstract.

📄 View solution
Exercise 2

Explain why logistic regression is still called "regression" despite predicting a category, using this chapter's own description of what changes and what stays the same compared to ml1-3.

📄 View solution
Exercise 3

Explain, using this chapter's own illustrative result and warn-box, exactly how including department and salary together in one model tests ds1-10's own confounding question, and why the chapter insists this result is "suggestive, not conclusive."

📄 View solution

Chapter 5 Quick Reference

  • Plain linear regression can predict nonsensical values (outside 0-1) for a Yes/No target — logistic regression's own sigmoid step fixes this
  • Still a linear combination of weighted features underneath — hence "regression" — sigmoid turns the result into a genuine probability
  • A threshold (commonly 0.5) turns a probability into a Yes/No prediction — an adjustable choice, covered fully in ml1-6
  • One-hot encoding turns a categorical column (department) into per-category binary columns a model can actually use
  • ds1-10's hypotheses, closed: lower salary associates with higher attrition; department's own apparent effect is largely explained by salary once both are fit together
  • Next chapter: Evaluation Metrics for Classification
Chapter 6 of 11

Evaluation Metrics for Classification

Machine Learning Fundamentals

Chapter 6 · Evaluation Metrics for Classification

ml1-5 answered which factors matter for attrition, not how good the model actually is at predicting who leaves. ml1-5 also flagged something ml1-4 never had to deal with: attrition is genuinely imbalanced — far more No than Yes in most real companies. That fact changes which metric is trustworthy here.

The Confusion Matrix — Four Real Outcomes, Not One

Every prediction on a binary target falls into exactly one of four buckets, comparing the model's own prediction against the real outcome:

Predicted: Left
Predicted: Stayed
Actually Left
True Positive
Correctly caught
False Negative
Missed — the costly one
Actually Stayed
False Positive
False alarm
True Negative
Correctly cleared

Accuracy — And Why It's Dangerous Here Specifically

Accuracy is simply (correct predictions) ÷ (total predictions) — the single most intuitive metric, and, on an imbalanced target, a genuinely misleading one.

The accuracy paradox, concretely
If 90% of employees in the data actually stayed, a model that predicts "No, they won't leave" for absolutely everyone — never once actually examining salary, tenure, or department — scores 90% accuracy without learning anything at all. On ml1-5's own genuinely imbalanced attrition data, a high accuracy number alone proves nothing about whether the model is actually any good at its real job: catching the employees who are, in fact, at risk of leaving.

Precision & Recall — Answering Two Different Questions

Precision = True Positives ÷ (True Positives + False Positives) — of everyone the model flagged as a flight risk, what fraction actually left? A precision-focused model minimizes false alarms. Recall = True Positives ÷ (True Positives + False Negatives) — of everyone who actually left, what fraction did the model catch? A recall-focused model minimizes missed cases.

For attrition specifically, a missed at-risk employee (a False Negative) is usually the more expensive mistake — a resignation nobody saw coming, with no chance to intervene — while a false alarm (a False Positive) costs, at worst, an unnecessary retention conversation. This is a genuine, business-specific judgment call about which error type matters more, not a fact the data itself decides.

F1 — One Number, When You Need One

F1 is the harmonic mean of precision and recall — a single combined number that only stays high when both precision and recall are reasonably good, punishing a model that's strong on one and collapses on the other far more than a plain average would. Useful specifically when precision and recall need to be compared or ranked with one number rather than two.

Applying This to ml1-5's Own Model

from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, accuracy_score

preds = model.predict(X_test_scaled)
confusion_matrix(y_test, preds)
accuracy_score(y_test, preds)
precision_score(y_test, preds)
recall_score(y_test, preds)
f1_score(y_test, preds)
Illustrative results, on ml1-5's own fitted model
Accuracy ≈ 86% — looks strong on its own, but per this chapter's own accuracy-paradox warning, that alone proves little on imbalanced data. Precision ≈ 0.71 — most flagged employees genuinely were at risk. Recall ≈ 0.58 — the model still misses a meaningful share of the employees who actually left. F1 ≈ 0.64 — the honest, combined picture: a genuinely useful model, with real room to catch more at-risk employees.

Adjusting the Threshold — ml1-5's Own Preview, Delivered

ml1-5 flagged the 0.5 threshold as adjustable, not fixed. Lowering it flags more employees as at-risk — recall rises (fewer real leavers slip through), precision falls (more false alarms). Raising it does the reverse. Given this chapter's own reasoning that a missed at-risk employee is usually the costlier mistake for this specific problem, a real deployment might deliberately lower the threshold below 0.5, accepting more false alarms in exchange for catching more genuine flight risks — a business decision the metrics inform but don't make automatically.

Hands-On Exercises

Exercise 1

Using this chapter's own accuracy-paradox warn-box, explain exactly how a model that never examines any feature at all could still score 90% accuracy, and explain why this makes accuracy alone untrustworthy specifically for ml1-5's own attrition data.

📄 View solution
Exercise 2

Explain the difference between precision and recall using this chapter's own confusion-matrix definitions, and explain why this chapter argues a False Negative is usually more costly than a False Positive for the attrition problem specifically.

📄 View solution
Exercise 3

Explain, using this chapter's own reasoning about threshold adjustment, why lowering the classification threshold below 0.5 would raise recall and lower precision, and explain why the chapter frames the actual threshold choice as a business decision rather than something the metrics decide automatically.

📄 View solution

Chapter 6 Quick Reference

  • Confusion matrix — True/False Positive/Negative, the foundation every other metric here is built from
  • Accuracy — intuitive, but genuinely misleading on imbalanced data (the accuracy paradox)
  • Precision — of flagged cases, how many were real? · Recall — of real cases, how many were caught?
  • F1 — one combined number, punishing a model strong on only one of the two
  • The 0.5 threshold (ml1-5) is adjustable — lowering it trades precision for recall, a business decision the metrics inform, not decide
  • Next chapter: Decision Trees & Random Forests
Chapter 7 of 11

Decision Trees & Random Forests

Machine Learning Fundamentals

Chapter 7 · Decision Trees & Random Forests

ml1-3 and ml1-5 both fit a smooth mathematical formula — a weighted sum of features, squashed through a sigmoid for classification. This chapter introduces a structurally different family entirely: a model that looks, on paper, almost exactly like a flowchart of yes/no questions.

What a Decision Tree Actually Is

A decision tree is a series of nested yes/no questions about features — "is salary below $50,000?" — each one branching to a child node, until a leaf gives a final prediction. Unusually, the same structure works for both jobs this course has covered separately: predicting a category (a leaf holding a class label) or a continuous number (a leaf holding an average value) — one model family doing what took ml1-3 and ml1-5 two separate techniques to cover.

The Uncanny Resemblance to ml1-1's Own Expert Systems

Same shape, genuinely different origin
A decision tree's own structure — a chain of IF...THEN questions leading to a final decision — looks strikingly close to ml1-1's own description of MYCIN's hand-written rules. This isn't a coincidence to wave away; it's worth confronting directly, because it's exactly where ml1-1's own distinction still holds firm: MYCIN's rules and thresholds were written by a human expert, one at a time. A decision tree's own splits — which feature to question at each node, and what threshold to use — are discovered automatically from data, using the entropy/information-gain process below. Same surface shape, still a genuinely different origin.

How the Tree Actually Picks Its Own Questions

Entropy measures how mixed a group of labels is: a node where every single employee left has entropy 0 (perfectly "pure" — no uncertainty left at all); a node split evenly 50/50 between leaving and staying has maximum entropy (as uncertain as a coin flip). Information gain measures how much a candidate split would reduce that entropy. At every node, the tree-building algorithm greedily tries every possible feature and threshold, and picks whichever single split produces the largest information gain — the biggest reduction in mixed-up-ness.

A Worked Split — And an Independent Confirmation

from sklearn.tree import DecisionTreeClassifier

tree = DecisionTreeClassifier(max_depth=4, random_state=42)
tree.fit(X_train, y_train)
Illustrative result — the tree's own first split
Fit on ds1-10's own employee data, the tree's own very first, most impurity-reducing split plausibly lands on salary — the exact same feature ml1-5's own logistic regression coefficients already flagged as the strongest predictor. Two structurally unrelated algorithms — one fitting a smooth weighted formula, one greedily splitting on impurity — independently landing on the same answer is genuinely stronger evidence than either method alone: it's much less likely that both a formula-fitting process and a rule-splitting process would agree by pure coincidence.

The Clearest Overfitting Example in This Course

Left unconstrained, a decision tree can keep splitting until individual leaves contain a single training example each — a tree that has, in effect, memorized the training set row by row. ml1-2's own warning about training-data evaluation becomes vividly concrete here: an unconstrained tree can reach close to 100% training accuracy while performing noticeably worse on the test set — the most visually obvious overfitting example this course covers, more intuitive than either regression model's own more abstract version of the same failure.

Random Forests — Averaging Away the Overfitting

A random forest builds many individual trees — each trained on a random, bootstrapped subset of the training rows, and restricted to a random subset of features at each split — then combines their predictions (majority vote for classification, average for regression).

from sklearn.ensemble import RandomForestClassifier

forest = RandomForestClassifier(n_estimators=200, random_state=42)
forest.fit(X_train, y_train)

Why this actually works: each individual tree, trained on its own random slice of data, tends to overfit in its own idiosyncratic way — memorizing quirks specific to whichever rows and features it happened to see. Averaged across many differently-trained trees, those individual idiosyncrasies tend to cancel each other out, while the genuine, real pattern every tree independently rediscovers — ds1-6's own variance vocabulary applies directly here — survives the averaging. The forest's own predictions end up with meaningfully lower variance than any single tree's own predictions, without needing to constrain any individual tree very much at all.

Hands-On Exercises

Exercise 1

Using this chapter's own warn-box, explain precisely what a decision tree and MYCIN's own expert-system rules share on the surface, and what specifically keeps ml1-1's own learned-vs-hand-coded distinction intact despite that resemblance.

📄 View solution
Exercise 2

Explain why this chapter treats the decision tree's own salary split as "genuinely stronger evidence" than ml1-5's logistic-regression coefficient alone, using this chapter's own reasoning about coincidence.

📄 View solution
Exercise 3

Explain, using this chapter's own reasoning about idiosyncratic errors, why averaging many overfit-prone trees together reduces overfitting rather than simply averaging the overfitting itself away equally everywhere.

📄 View solution

Chapter 7 Quick Reference

  • A decision tree — nested yes/no questions on features, one structure for both regression and classification
  • Splits are chosen automatically via entropy/information gain — the same IF/THEN shape as ml1-1's expert systems, a genuinely different origin
  • An unconstrained tree can memorize training data almost perfectly — the clearest overfitting example in this course
  • Random forests — many trees, each on a random data/feature subset, combined — idiosyncratic errors cancel, real signal survives (ds1-6's own variance vocabulary)
  • The tree's own salary split independently confirms ml1-5's own logistic-regression finding — two different methods agreeing is stronger evidence than either alone
  • Next chapter: Overfitting, Underfitting & Regularization
Chapter 8 of 11

Overfitting, Underfitting & Regularization

Machine Learning Fundamentals

Chapter 8 · Overfitting, Underfitting & Regularization

ml1-7 showed the clearest possible overfitting example in this course — a tree memorizing training rows one at a time. ml1-2 previewed cross-validation and promised this chapter would deliver it in full. Both threads close here.

Two Failure Modes, Formally

OverfittingUnderfitting
What happensModel too complex — fits noise/idiosyncrasies in the training dataModel too simple — misses real patterns entirely
Training errorLowHigh
Test errorHighHigh
Exampleml1-7's own unconstrained treePredicting the same average price for every car, ignoring mileage and year entirely

The diagnostic signature is the gap: overfitting shows low training error but high test error; underfitting shows high error on both — the model was never good, even on data it directly saw.

The Bias-Variance Tradeoff — Built on ds1-6's Own Vocabulary

Bias is systematic, consistent wrongness — error from a model too simple to capture the real pattern, present regardless of which training sample it happened to see (underfitting). Variance reuses ds1-6's own definition directly: how much would this model's own predictions change if trained on a different random sample from the same population? A single unconstrained tree (ml1-7) has high variance — a different training sample would grow a noticeably different tree. A random forest has lower variance — averaging many trees stabilizes the result regardless of which specific sample any one tree happened to see.

The tradeoff, honestly
Total error breaks down, conceptually, into bias² + variance + irreducible noise (noise no model could ever remove). Reducing bias (a more complex, flexible model) tends to increase variance; reducing variance (a simpler, more constrained model) tends to increase bias. There is no free way to drive both to zero simultaneously — every technique in this chapter is a deliberate, controlled trade of one against the other.

Reading a Learning Curve

Plotting training error and validation error against training-set size (or model complexity) gives a real diagnostic picture. High bias shows both curves converging to a similarly poor error — more data doesn't help, because the model itself is too simple to use it. High variance shows a persistent gap — low training error, meaningfully higher validation error — that more data typically narrows, since a larger, more representative sample gives a flexible model less room to fit pure noise.

Regularization — Deliberately Trading Bias for Variance

Regularization adds a penalty term to ml1-3's own least-squares fitting objective, discouraging large coefficient values. This is the bias-variance tradeoff, applied on purpose: a regularized model fits the training data very slightly worse (a bit more bias) in exchange for being noticeably less sensitive to the specific training sample it saw (less variance).

from sklearn.linear_model import Ridge, Lasso

ridge = Ridge(alpha=1.0)   # L2
lasso = Lasso(alpha=1.0)   # L1
L2 (Ridge)L1 (Lasso)
Effect on coefficientsShrinks all of them, smoothlyCan shrink some coefficients to exactly zero
Practical side effectNone beyond shrinkageAutomatic feature selection — zeroed features are effectively dropped

Cross-Validation — ml1-2's Own Promise, Delivered

ml1-2 flagged the real risk: a single validation split can be unlucky on a small dataset. k-fold cross-validation fixes this directly: split the data into k equal folds, train on k−1 of them and validate on the one held out, rotate which fold is held out across k full rounds, then average the k resulting scores.

from sklearn.model_selection import cross_val_score

scores = cross_val_score(model, X, y, cv=5)
scores.mean(), scores.std()

Every row gets used for validation exactly once and for training k−1 times — a far more reliable estimate of real performance than any single split, and the standard deviation across the k scores is itself informative: a small spread means the model performs consistently regardless of which slice of data it sees; a large spread is itself a sign of high variance.

A Practical Checklist

SymptomDiagnosisTry
High error, train and testUnderfittingMore features, less regularization, a more flexible model
Low train error, high test errorOverfittingRegularization, more data, ml1-7's own random forest, cross-validation to confirm

Hands-On Exercises

Exercise 1

Using this chapter's own compare-table, explain why overfitting and underfitting produce different patterns of training vs. test error, and explain why "high error on both" specifically rules out overfitting as the diagnosis.

📄 View solution
Exercise 2

Explain, using ds1-6's own variance definition and this chapter's own comparison between a single tree and a random forest, exactly what "variance" means for a model, and why a random forest has lower variance than a single unconstrained tree.

📄 View solution
Exercise 3

Explain why this chapter frames regularization as "the bias-variance tradeoff, applied on purpose" rather than a separate, unrelated technique, and explain the specific practical difference between L1 and L2's effect on coefficients.

📄 View solution

Chapter 8 Quick Reference

  • Overfitting — low train error, high test error · Underfitting — high error on both
  • Bias — systematic error from too-simple a model · Variance — ds1-6's own definition: how much predictions change across different training samples
  • Every technique in this chapter deliberately trades one against the other — no free way to reduce both at once
  • Regularization (L1/Lasso, L2/Ridge) — a controlled bias-for-variance trade; L1 can zero out coefficients entirely (feature selection)
  • k-fold cross-validation — ml1-2's own deferred promise, delivered: a far more reliable performance estimate than one split
  • Next chapter: Unsupervised Learning: Clustering
Chapter 9 of 11

Unsupervised Learning: Clustering

Machine Learning Fundamentals

Chapter 9 · Unsupervised Learning: Clustering

ml1-1 named supervised and unsupervised learning as this course's own two branches — every chapter since has been supervised, working from a known, provided answer (price, left_company). This chapter is the other branch, made concrete rather than abstract: the exact same datasets, with every label deliberately removed.

What Changes When There's No Label

Every technique since ml1-3 learned by comparing its own predictions against a known, correct answer during training. Clustering has no such answer to learn from at all — it's asked only to group similar data points together, discovering whatever structure exists on its own, with nobody ever telling it what the "right" groups are.

K-Means — The Algorithm, Step by Step

  • Choose k, the number of clusters, in advance.
  • Randomly place k initial centroids (cluster centers).
  • Assign every data point to its nearest centroid.
  • Recompute each centroid as the average position of every point now assigned to it.
  • Repeat steps 3–4 until the centroids stop moving meaningfully.
  • A genuinely different fitting mechanism than anything earlier in this course: no least-squares fit against a known target (ml1-3), no entropy-driven split search against known labels (ml1-7) — k-means iteratively refines its own evolving guess about where the clusters are, with nothing external to check itself against.

    Choosing k — The Elbow Method

    Unlike supervised learning, where the number of real classes is simply given (ml1-5's own two — Yes/No), nothing hands k to this chapter directly. Plotting inertia (the total squared distance from each point to its own assigned centroid) against increasing values of k always trends downward — more clusters always let points sit closer to their own center — but with sharply diminishing returns past a certain point. The "elbow" — where adding another cluster stops meaningfully reducing inertia — is a reasonable, practical choice for k.

    A heuristic, not a definitive answer
    Real data often doesn't have one obvious elbow — the same honest, judgment-call territory ds1-4's own cleaning decisions and imgai1-4's own --stylize tuning both occupied. The elbow method narrows the choice; it doesn't remove the judgment call entirely.

    Running It for Real — ds1-9's Own Used-Car Data, Unlabeled

    from sklearn.cluster import KMeans
    from sklearn.preprocessing import StandardScaler
    
    X = df[["mileage", "year", "price"]]
    X_scaled = StandardScaler().fit_transform(X)
    
    kmeans = KMeans(n_clusters=3, random_state=42)
    clusters = kmeans.fit_predict(X_scaled)
    Illustrative result — ds1-9's used cars, ml1-3's own dataset, no labels this time
    Three clusters plausibly emerge roughly along an age gradient: newer, low-mileage, higher-price cars in one group; older, high-mileage, lower-price cars in another; a middle group between them. Nobody told the algorithm "year" mattered or how to weight it — it discovered this structure purely from how the three numeric features happened to cluster together, on the exact same rows ml1-3 already fit a supervised regression on.

    Running It on ds1-10's Own Employees — A Genuinely New Finding

    X = df[["age", "years_at_company", "salary"]]
    X_scaled = StandardScaler().fit_transform(X)
    clusters = KMeans(n_clusters=3, random_state=42).fit_predict(X_scaled)
    Illustrative result — a pattern supervised learning was never set up to look for
    One cluster plausibly emerges with unusually long tenure paired with comparatively low salary — long-serving employees who haven't been paid in step with their own loyalty. ml1-5's own logistic regression could only ever answer the specific question it was given (does salary predict attrition?). This chapter's clustering wasn't given a question at all — it surfaced a group nobody had explicitly asked about, which is exactly what unsupervised learning is genuinely for.

    Why Scaling Isn't Optional Here

    ml1-3 standardized features so coefficient sizes could be compared fairly. K-means needs standardization for a stricter reason: the algorithm's own "nearest centroid" step is a literal distance calculation. Left unscaled, salary (tens of thousands) would swamp years_at_company (single digits) in every distance computation, and the resulting clusters would essentially just be salary bands wearing three other features' names. Scaling here isn't a nicety for readability — it determines whether the clustering result means anything at all.

    Crisp Assignment — And a Preview of ch10

    Every point in k-means belongs to exactly one cluster, fully — a crisp assignment, with no notion of "70% in this cluster, 30% in that one." ml1-10's own Fuzzy Logic chapter picks up exactly here, with a system built specifically around partial, graded membership instead.

    Hands-On Exercises

    Exercise 1

    Explain, using this chapter's own five-step k-means description, why this algorithm's own fitting process is described as "genuinely different" from ml1-3's least-squares fitting or ml1-7's entropy-driven splits.

    📄 View solution
    Exercise 2

    Explain why this chapter says clustering on ds1-10's own employee data surfaced "a genuinely new finding," specifically contrasting what ml1-5's own supervised model could and couldn't have found on its own.

    📄 View solution
    Exercise 3

    Explain why this chapter treats feature scaling as stricter for k-means than ml1-3's own scaling requirement for regression coefficients, using this chapter's own reasoning about distance calculations.

    📄 View solution

    Chapter 9 Quick Reference

    • Unsupervised — no known answer to train against; the algorithm discovers structure entirely on its own
    • K-means — choose k, place centroids, assign, recompute, repeat to convergence — no external target to fit against
    • Elbow method — inertia vs. k, diminishing returns mark a reasonable k; a heuristic, not a definitive answer
    • Re-run on ds1-9/ds1-10's own data with labels removed — ml1-1's abstract supervised/unsupervised distinction, made concrete
    • Clustering surfaced a pattern (underpaid long-tenure employees) ml1-5's own supervised model was never even asked to look for
    • Scaling is a strict necessity here — k-means computes real distances, unlike ml1-3's own comparison-only standardization
    • K-means gives crisp (all-or-nothing) cluster assignment — Next chapter: Fuzzy Logic — Beyond Crisp Boolean Rules
    Chapter 10 of 11

    Fuzzy Logic — Beyond Crisp Boolean Rules

    Machine Learning Fundamentals

    Chapter 10 · Fuzzy Logic — Beyond Crisp Boolean Rules

    ml1-9 closed on a deliberate setup: k-means gives every point crisp membership — fully in exactly one cluster, never partially in two. This chapter is that setup's own payoff: a system built specifically around membership that doesn't have to be all-or-nothing.

    Crisp Logic Is Everywhere in This Course So Far, Once You Look

    Classical Boolean logic says a statement is fully true or fully false — an element either is or isn't in a set, 1 or 0, nothing between. This isn't just ml1-9's own clustering; ml1-7's own decision tree splits are crisp too. "Is salary below $50,000?" draws a hard line: someone earning $49,999 and someone earning $50,001 — practically identical — land in completely different branches, with zero partial credit for how close the second person actually sits to the boundary.

    Fuzzy Sets — Partial, Graded Membership

    A fuzzy set allows membership to be any value between 0 and 1, not just the two endpoints. Take "long tenure": crisp logic needs a hard cutoff (years_at_company ≥ 5 = long, full stop). A fuzzy set instead assigns a graded degree of membership — four years might sit at 0.6 membership in "long tenure," eight years at 0.9 — genuinely closer to how people actually reason about vague, real-world categories, where "long" isn't a single sharp line anyone actually applies mentally.

    Membership Functions

    A membership function is what actually assigns each possible input a degree of membership in a fuzzy set — commonly triangular, trapezoidal, or S-shaped curves, plotted against the input value.

    This looks like ml1-5's own sigmoid — it isn't the same thing
    An S-shaped membership function and ml1-5's own sigmoid function both squash a range of inputs into [0, 1] — visually, strikingly similar curves. What they represent is fundamentally different. Sigmoid's output is a probability: a statement about an uncertain event that eventually resolves — an employee either does or doesn't actually leave, and once observed, the true answer is fully 0 or 1 again. A fuzzy membership degree is not a probability at all — it's a degree of truth that can stay genuinely, permanently partial. An employee's tenure being "somewhat long" isn't uncertainty waiting to resolve into a crisp fact later; there's no future observation that ever makes "somewhat long" collapse into fully true or fully false. Same-looking curve, two entirely different kinds of claim.

    Fuzzy Inference Systems

    Fuzzy sets combine using fuzzy versions of AND/OR/NOT (typically minimum, maximum, and complement), feeding into fuzzy IF...THEN rules — IF tenure is long AND salary is low THEN attrition_risk is high — where "long," "low," and "high" are all fuzzy sets with their own membership functions, and the rule's own output is itself a graded degree, not a hard yes/no.

    The Real Historical Link to ml1-1's Own Expert Systems

    Fuzzy logic and historyai2-6's own expert systems emerged in the same classical-AI era, and were often combined directly into "fuzzy expert systems." The rules in a fuzzy inference system are, like MYCIN's own, still typically hand-written by a human expert — ml1-1's own learned-vs-hand-coded distinction still applies exactly as before. What fuzzy logic actually changed was narrower and more specific: ml1-1's own tip-box already named brittleness as one of the real, documented reasons expert systems declined — a crisp rule system handling a value right at a boundary badly, with no graceful middle ground. Fuzzy logic was a genuine, historical attempt to fix exactly that brittleness, letting hand-coded rules degrade gracefully near a boundary instead of snapping sharply across it.

    Back to ml1-9's Own Employee Clusters

    What a fuzzy version of ml1-9's own clustering could express
    ml1-9's own k-means could only ever say an employee is 100% in the "underpaid veteran" cluster or 100% in a different one — nothing in between, even for someone sitting almost exactly on the boundary. A fuzzy system could instead say this employee is 0.7 "underpaid veteran" and 0.3 "typical mid-career" — a graded answer that reflects genuine, real ambiguity about someone near the edge, rather than forcing a crisp, possibly arbitrary line through them.

    Where Fuzzy Logic Actually Lives Today

    Fuzzy logic isn't a mainstream competitor to ml1-3's regression, ml1-7's trees, or nn1's eventual neural networks for prediction tasks like this course's own two case studies. Its real, ongoing home is control systems — washing machines adjusting cycle length to load size, camera autofocus, some industrial process control — genuine, still-deployed applications where reasoning gracefully over graded inputs matters more than raw predictive accuracy on a labeled dataset.

    Hands-On Exercises

    Exercise 1

    Explain, using this chapter's own $49,999/$50,001 example, why a decision tree's own splits count as crisp logic, even though ml1-7 never used the word "crisp" itself.

    📄 View solution
    Exercise 2

    Using this chapter's own warn-box, explain the real difference between what a sigmoid's output represents and what a fuzzy membership degree represents, even though both curves look S-shaped.

    📄 View solution
    Exercise 3

    Explain what fuzzy logic actually changed about expert systems and what it did NOT change, using this chapter's own reasoning about brittleness and ml1-1's own learned-vs-hand-coded distinction.

    📄 View solution

    Chapter 10 Quick Reference

    • Classical Boolean logic is crisp — 0 or 1, nothing between; ml1-7's own tree splits and ml1-9's own cluster assignment both work this way
    • Fuzzy sets allow graded, partial membership between 0 and 1, via membership functions
    • An S-shaped membership function looks like ml1-5's own sigmoid but means something different — probability resolves; fuzzy truth can stay permanently partial
    • Fuzzy inference systems — still hand-coded rules (ml1-1's own distinction unchanged), but able to degrade gracefully instead of snapping sharply — a real, historical fix for expert systems' own brittleness
    • Fuzzy logic's real modern home is control systems, not mainstream predictive ML
    • Next chapter: Capstone: A scikit-learn Tour & Building a Real Predictive Model
    Chapter 11 of 11

    Capstone: A scikit-learn Tour & Building a Real Predictive Model

    Machine Learning Fundamentals

    Chapter 11 · Capstone: A scikit-learn Tour & Building a Real Predictive Model

    Every chapter since ml1-3 has quietly used the same shape: fit() to train, predict() to apply, some scoring function to evaluate. This capstone makes that consistency explicit, and closes the loop this entire course opened — bringing both of its own resolved hypotheses together into one final pipeline.

    The Consistent scikit-learn API — A Genuine Design Strength

    ChapterAlgorithmSame interface
    ml1-3LinearRegression.fit(X, y) / .predict(X) / .coef_
    ml1-5LogisticRegression.fit(X, y) / .predict(X) / .coef_
    ml1-7DecisionTreeClassifier / RandomForestClassifier.fit(X, y) / .predict(X)
    ml1-9KMeans.fit(X) / .predict(X) / .fit_predict(X)

    Four genuinely different algorithm families — a smooth linear fit, a sigmoid-squashed linear fit, a greedy entropy-splitting tree, an iterative centroid-refinement process with no target at all — and switching between them required almost no change to the surrounding code. That consistency isn't an accident; it's a deliberate design choice this whole course has been quietly relying on since ml1-3.

    Pipeline 1 — Closing ml1-3's Own Regression Story

    Used-car price prediction, start to finish
    from sklearn.model_selection import train_test_split, cross_val_score
    from sklearn.preprocessing import StandardScaler
    from sklearn.linear_model import LinearRegression, Ridge
    from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
    import numpy as np
    
    X = df_cars[["mileage", "year"]]
    y = df_cars["price"]
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # ml1-2
    
    scaler = StandardScaler()
    X_train_s = scaler.fit_transform(X_train)
    X_test_s = scaler.transform(X_test)
    
    model = Ridge(alpha=1.0)   # ml1-3's own LinearRegression, ml1-8's own L2 regularization applied
    model.fit(X_train_s, y_train)
    
    preds = model.predict(X_test_s)
    mae = mean_absolute_error(y_test, preds)              # ml1-4
    rmse = np.sqrt(mean_squared_error(y_test, preds))      # ml1-4
    r2 = r2_score(y_test, preds)                           # ml1-4
    
    cv_scores = cross_val_score(model, X_train_s, y_train, cv=5)   # ml1-8

    This is ml1-3's own coefficients and ml1-4's own metrics, now wrapped in ml1-8's own regularization and cross-validation — the full arc this course built one deliberate piece at a time.

    Pipeline 2 — Closing ml1-5's Own Classification Story

    Employee attrition prediction, start to finish — two models, compared
    from sklearn.linear_model import LogisticRegression
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score
    
    X = pd.get_dummies(df_emp[["department", "age", "years_at_company", "salary"]])
    y = df_emp["left_company"].map({"Yes": 1, "No": 0})
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # ml1-2
    X_train_s = scaler.fit_transform(X_train)
    X_test_s = scaler.transform(X_test)
    
    logit = LogisticRegression()          # ml1-5
    logit.fit(X_train_s, y_train)
    
    forest = RandomForestClassifier(n_estimators=200, random_state=42)   # ml1-7
    forest.fit(X_train, y_train)          # trees don't require scaling — a real, honest asymmetry worth noting
    
    for name, preds in [("Logistic", logit.predict(X_test_s)), ("Forest", forest.predict(X_test))]:
        print(name, precision_score(y_test, preds), recall_score(y_test, preds), f1_score(y_test, preds))  # ml1-6
    
    forest.feature_importances_   # does the forest agree with ml1-5's own salary finding?
    Illustrative result — a second, independent confirmation
    The random forest's own feature_importances_ plausibly ranks salary highest, echoing ml1-5's own coefficient and ml1-7's own worked split — the third independent method now agreeing on the same answer. Both models' own precision/recall/F1 (ml1-6) come back broadly comparable, with the forest typically edging out logistic regression slightly on recall — consistent with ml1-8's own reasoning: an ensemble reduces variance relative to any single model.

    A Final Coda — Revisiting ml1-9 and ml1-10

    Rerunning ml1-9's own unsupervised clustering on both datasets one last time is worth doing here specifically because it asks a genuinely different question than either pipeline above — not "does this predict the target," but "what structure exists regardless of any target at all." And if either dataset had employees sitting persistently near a cluster boundary, unable to be assigned crisply with real confidence, ml1-10's own fuzzy membership approach — not implemented here, but conceptually available — is exactly where that specific problem would be addressed, rather than by forcing ml1-9's own crisp k-means to make an arbitrary, boundary-splitting call.

    Chapter Attribution

    Capstone elementDrawn from
    Learned rules vs. hand-coded rules framingml1-1
    Train/test split, cross-validation setupml1-2 / ml1-8
    Linear regression, standardized coefficientsml1-3
    MAE / RMSE / R²ml1-4
    Logistic regression, one-hot encodingml1-5
    Precision / recall / F1ml1-6
    Random forest, feature_importances_ml1-7
    Ridge regularization, cross_val_scoreml1-8
    The unsupervised clustering codaml1-9
    The fuzzy-boundary closing thoughtml1-10

    Honest Scope Note

    What this capstone — and this course — deliberately doesn't attempt
    • No neural networks. Every model in this course fits a relatively simple, interpretable structure — a line, a sigmoid, a tree, a centroid. Genuinely deep, layered models are nn1's own entire job.
    • No NLP-specific techniques. Every feature used across this whole course was already numeric or a small set of categories. Turning raw text into usable features is nlp1's own job.
    • No production deployment or MLOps. This capstone stops at a working, evaluated model in a notebook. Serving it reliably at scale, monitoring for real-world performance drift over time, versioning models, and automated retraining are a real, substantial engineering layer this course never attempts.

    Hands-On Exercises

    Exercise 1

    Explain why this chapter treats the consistent fit/predict interface across four structurally different algorithms as "a genuine design strength," using this chapter's own comparison table to justify the claim.

    📄 View solution
    Exercise 2

    Explain why the random forest's own feature_importances_ result is described as "a second, independent confirmation," identifying all three methods across this course that now agree on salary's own importance.

    📄 View solution
    Exercise 3

    Using this chapter's own scope note, explain why "no production deployment or MLOps" is a genuinely different kind of gap from "no neural networks" or "no NLP techniques" — what distinguishes it from the other two?

    📄 View solution

    Chapter 11 Quick Reference — Course Summary

    • Learned rules (ml1-1) vs. hand-coded expert systems, closing the loop opened at ml1-1 and revisited by ml1-7's trees and ml1-10's fuzzy inference systems
    • Train/test/validation discipline (ml1-2) and cross-validation (ml1-8) underlie every model fit in this course
    • Regression (ml1-3/ml1-4) and classification (ml1-5/ml1-6) each closed a real hypothesis ds1 deliberately left open
    • Trees/forests (ml1-7) offered independent confirmation; overfitting/regularization (ml1-8) explained why forests generalize better than single trees
    • Clustering (ml1-9) surfaced a pattern supervised learning was never asked to find; fuzzy logic (ml1-10) addressed crisp logic's own boundary brittleness
    • Next up in the Data Science & ML subject: nn1 (Neural Networks & Deep Learning) — delivering the technical mechanism behind historyai3-3's own perceptron/backpropagation story