Take a Break
5:00
Inhale…
Give your mind a break — no phone, no music, just idle time or a quick walk.
Spark MLlib: Regression, Classification, Clustering, and Collaborative Filtering
This lecture is an entry point into machine learning with PySpark's MLlib library. Four techniques are covered — regression, classification, clustering, and collaborative filtering — with hands-on code snippets for the first three. The treatment is deliberately introductory: the audience has not seen machine learning before, so the first part of the session builds the vocabulary (what learning means, what supervised and unsupervised learning are), and the rest applies that vocabulary to real PySpark code running against a Spark cluster.
Along the way the session works a complete path: it defines machine learning, splits the field into supervised and unsupervised learning, separates regression from classification, derives the error metrics used to fit a straight line, then shows each idea running as a real program — linear regression on the Boston housing data, a decision tree on wine-quality data, and k-means on a tiny synthetic file. The session closes with the two recommendation approaches. Everything in the session is examinable, and the practical rules (maximum information gain, minimum gini, follow the L1 or L2 instruction given in the problem) are the ones that recur in exam questions.
8.1 What Machine Learning Is
Hook: A computer that is never told the rules, yet still plays chess better than its programmer — is that still "programming"? Machine learning is built on exactly that idea, and it is nearly seventy years old.
8.1.1 The 1959 definition and why it stayed theoretical
Machine learning is an old term — almost six decades old by now. The first author to define it was Arthur Samuel, who coined the definition in 1959: it is a field of study that gives computers the ability to learn without being explicitly programmed.
To see how different that is from ordinary programming: in a conventional program we feed instructions to the computer — rules that say exactly how to perform the task. We give it input, it applies the rules, and it generates output. That is how a computer typically works. Samuel's definition flips the emphasis: instead of writing the rules ourselves, the computer discovers them from data.
Conventional programming vs learning — the one-sentence version. In conventional programming, someone writes the rules and the computer applies them to input. In machine learning, someone supplies data and the computer derives the rules. The rules are no longer written; they are learned. Samuel's term for this — "learning without being explicitly programmed" — is the definition quoted in almost every textbook on the subject.
8.1.2 Why machine learning could not take off in 1959
The definition existed, but the field could not be leveraged at that moment, for two practical reasons:
- Machine learning needs high computing power. The data being processed is large in volume, and learning algorithms over that data are computationally heavy.
- Machine learning needs large datasets. More data is required to achieve more accuracy.
In 1959 neither abundant computing power nor abundant data existed. Neither was available in abundance, so the benefit of the concept could not be taken.
Scope: the two ingredients a learning system needs. Learning methods are only practical when both conditions hold — enough compute to run the algorithms and enough data for the patterns to show up. This is why the field waited roughly four decades after Samuel's definition: the same algorithm that was theoretical in 1959 became routine once processors were fast and data was cheap. If either ingredient is missing, a machine learning approach will underperform a hand-written rule.
8.1.3 Mitchell's task–performance–experience definition (late 90s)
Moving forward to the late 90s, Tom Mitchell defined machine learning more operationally: machine learning is a field of study of algorithms that improve their performance \(P\) at some task \(T\) with experience \(E\).
Break that down:
- \(T\) — the task you give the algorithm.
- \(P\) — the performance measure: how well it is performing, how well it is learning.
- \(E\) — the experience: the data you feed it.
It is a three-variable tuple: performance, task, and experience. Given a task and given a certain experience, you evaluate the performance. The central idea: give the algorithm more experience and its performance should improve.
Why this definition matters. Samuel's definition says what machine learning is; Mitchell's says how we can tell it is happening. A computer program is said to learn from experience \(E\) with respect to some task \(T\) and some performance measure \(P\) if its performance on \(T\), as measured by \(P\), improves with experience \(E\). The word to underline is improves — learning is not an on/off switch, it is a rising curve that you can actually measure. That is what makes the definition operational: you can plot \(P\) against the amount of \(E\) and see the learning happen.
8.1.4 The canonical example: email spam filtering
The classic example used to make this concrete is email spam filtering — classifying emails as spam or not spam.
- Task \(T\): classify each email as spam or not spam.
- Experience \(E\): historical emails that already carry certain attributes and a label saying whether each one is spam or not spam. This is what is called labeled data (labeling is discussed later under the two categories of machine learning algorithms).
- What the system does: it learns something out of those labeled emails and applies the same rules it has learned to unseen emails, classifying each as spam or not spam.
- Performance \(P\): how many emails it is able to correctly classify as spam or not spam. Give the model more emails to learn from and performance should improve.
Spotting the three letters in a real problem. Take Mitchell's definition and lay it over the spam filter: \(T\) is "classify this email as spam or not", \(E\) is "a large collection of past emails, each already marked spam or not spam", and \(P\) is "number of emails correctly classified". The three roles are not interchangeable — \(E\) is the input the system is given, \(T\) is what it must do, \(P\) is how we score it. Once a system has all three, the claim "give it more \(E\) and \(P\) goes up" is exactly what makes it a learning system rather than a fixed program.
Real-world & domain connection. The spam filter is not just a classroom example — it is the canonical first machine learning application in the industry, and it still runs on every major email service. The same T-P-E pattern generalizes everywhere: recommend a product (\(T\)), the user's past purchases (\(E\)), fraction of recommendations accepted (\(P\)); or predict the next day's traffic (\(T\)), historical sensor readings (\(E\)), mean prediction error (\(P\)). In the broader field, this definition is the entry point to the whole machine learning course: once you can name the task, the experience, and the performance measure for any problem, you have already done the first step of modelling it.
Recap + bridge. Machine learning = learning rules from data instead of writing them (Samuel, 1959), made measurable by Mitchell's task \(T\), performance \(P\), experience \(E\) triple. The moment you have labeled data, you face the fork that splits the entire field: supervised learning on one side, unsupervised on the other — the next topic.
8.2 Supervised vs Unsupervised Learning
Whenever machine learning is introduced, these two terms come up immediately, because the whole field divides along this line. The division depends on one thing: does the training data come with the desired output or not?
Hook and intuition. One yes/no question — "is the answer included with the data?" — decides which of the two big families of machine learning you are in. Think of a teacher: supervised learning is a classroom where the answer key is handed out with every exercise; unsupervised learning is a pile of mixed objects and no answer key at all, where the only job is to sort things that look alike. The two families are never about the algorithm's cleverness — they are about what the data contains.
8.2.1 Supervised learning
In supervised learning you have a dataset, called the training data, from which the model learns. The training data includes the desired output — the answer for each training instance. In the spam example, the model is told "this is a spam email" and "these are the rules of a spam email" and "these are the rules of a genuine email". Because the desired output is given to the system, this kind of data is called labeled data.
The house-price example makes the structure explicit. Suppose a real estate agency hands over the records of past house purchases in a city. The attributes available are:
- plot size
- number of bedrooms
- covered area
- whether there is granite flooring
- whether the kitchen is upgraded
- distance from the city, in kilometers
- age of the flat, in years
- price, as the final attribute
The first seven attributes are the input attributes to the system; the price is the output attribute. Because both inputs and outputs are present — these are historical sales that have already happened — the data is labeled. This kind of data, presented as input attributes plus the desired output, is called training data with desired output, and it is what supervised learning problems use. The model learns from these attributes how to predict the price; later, given a new instance with the same seven attributes, it should predict the price of that house.
Supervised learning in one sentence. The model reads a table where every row has inputs and the correct answer; it learns a rule from the answers; later it meets rows without answers and supplies its own. The label is the desired output — the price in the housing table, the spam/not-spam mark in the email example. Classification and regression (sections 8.3 and 8.4) are both supervised, which is why the same labeled-data machinery serves both.
8.2.2 Unsupervised learning
In unsupervised learning we have only the training data — only the input attributes — and no desired output; the data is unlabeled. Take the same house dataset and remove the price column: without the price of historical sales, it becomes very difficult to predict a price, because the desired output is simply not there.
But something else can be done with such data: grouping. The houses can be grouped by number of bedrooms — a buyer interested only in a 3 BHK flat should be shown only the 3 BHK flats — or by plot size, or by distance from the city. Creating groups out of the data without any desired output is exactly the shape of an unsupervised learning problem.
The same table, two different problems. With the price column present, the table answers: "predict the price of this house" — supervised, a regression problem (section 8.4). Delete the price column and the table still answers: "which houses resemble each other?" — unsupervised, a clustering problem (section 8.11). Nothing about the algorithm changed; the data changed, and that is what reclassifies the problem. This one experiment — removing one column — is the cleanest demonstration of the supervised/unsupervised boundary.
8.2.3 Student question: is a model the same as an algorithm?
Q: Is a model equal to an algorithm — kind of?
A: Kind of, we can say kind of. (The professor lets this pass at the introductory level, and returns to the distinction later: the algorithm is the procedure that fits the line; once the parameters \(m\) and \(c\) are identified, the fitted line itself is the model.)
The same question, answered properly (section 8.4.2). The student's "kind of" instinct is right: at this point in the course the two words point at the same activity, so the professor does not split hairs. The real distinction appears when the first model is built: the algorithm is the step-by-step procedure that searches for good parameters, and the model is the finished object — the fitted line with its learned \(m\) and \(c\) — that actually makes predictions. An algorithm is a recipe; a model is the dish. The same recipe can cook many dishes, and many recipes can cook the same dish.
8.2.4 Uses of unsupervised learning
Examples or use cases of unsupervised learning:
- Market segmentation — you have customer details and want to categorize them under different heads: high-income, low-income, middle-income, or high-spend vs low-spend customers. This is done for better targeting, for example to decide whom to market a new product to.
- Recommendation systems — almost every website has one today: any electronic store, any e-commerce website, and OTT platforms all build recommendations.
- Social network analysis — again an unsupervised learning task.
Recap + bridge. One question — "does the training data include the desired output?" — splits the whole field: labeled data → supervised learning; unlabeled data → unsupervised learning (grouping). The house table with price is supervised; without it, unsupervised. The Q&A above left "model vs algorithm" half-open deliberately — the next two sections answer it with a real line: regression (predict a continuous number), classification (predict a category), and then the exact procedure that fits the line.
8.3 Regression vs Classification
Regression and classification are both supervised learning problems — in both cases you have labeled data — so the difference is not in the data. The difference is in the kind of output being predicted.
Hook. You are asked to predict two things: the resale price of a house, and whether an email is spam. The data in both cases is labeled, yet the two problems feel different — one answer is a number, the other a category. That difference is the entire distinction between regression and classification.
8.3.1 Continuous vs discrete output
- Regression predicts a continuous variable — a real number that can take an infinite number of values. Predicting house price is the running example.
- Classification predicts a discrete variable — a value chosen from a finite set of categories. Handwritten digit recognition is the running example: digits 0 through 9 are only ten possible values, so any digit gets classified under one of these ten discrete, finite labels.
So the little difference is: regression → continuous output; classification → discrete output.
Continuous vs discrete, defined. A continuous output is a quantity with no gaps: the price of a house could in principle be ₹41.23 lakh or ₹41.24 lakh or anything in between — infinitely many values. A discrete output is chosen from a finite list: a digit is one of exactly ten values, a disease answer is one of yes/no. The data being labeled is the same in both families; only the nature of the answer column differs. One way to see this in practice: regression problems are scored by how close the prediction is (RMSE, section 8.4), classification problems by how many predictions are exactly right (accuracy, section 8.7).
| Dimension | Regression | Classification |
|---|---|---|
| Output type | Continuous (real number) | Discrete (category) |
| Example answers | ₹45.5 lakh, 22.4 °C, 7,500 units | spam/not spam, digit 0–9, yes/no |
| Number of possible answers | Infinitely many | Finite, known list |
| Typical scoring | RMSE / MAE — closeness | Accuracy — percentage correct |
| Running example | House price | Handwritten digit recognition |
When to pick which: if the label column contains numbers you could split infinitely, regress; if it names a fixed set of buckets, classify.
8.3.2 Classification examples
- Image recognition: certain features are extracted from training images, and each image is given a label — "this is an apple", "this is a tomato", "this is an animal". The model learns "if these are the set of features, classify as ...". In testing you give an image that is different from the training images; it extracts features, passes them to the learned model, and the model predicts which class it belongs to.
- Employability prediction: four input attributes — CGPA, communication skills, aptitude, and programming skills — with historical data from a university covering the past three to four years, including whether the job was offered to each candidate. This labeled data trains a classification model; then, given the four attributes of a new student, the model predicts whether the job will be offered.
- Disease prediction: predicting whether a patient has a particular disease — yes or no — or is likely to get it.
- Email spam detection: the spam/not-spam problem already discussed; only two categories exist here.
When classification has exactly two classes. The spam and disease problems are binary — two buckets only. The digit problem is multi-class — ten buckets. The machinery is the same in both; only the answer list is longer. This matters later: the wine-quality demo (section 8.10) is multi-class, and the buys-computer tree (section 8.8) is binary — one worked example of each is enough to see both cases.
8.3.3 Regression examples
- Property price prediction.
- Stock price prediction.
- Sales prediction: organizations such as Amazon and Flipkart predict the sales of their products, or overall sales during events like the Big Billion Days; they need such models to prepare the inventory and the workforce needed to fulfill those many orders.
Scope: both are supervised — the labels decide nothing about which family you are in. A common mistake is to classify by dataset: "house data → regression, image data → classification". Wrong. The house dataset is regression only because its label (price) is continuous; images of apples vs tomatoes are classification only because the label is a category. The same inputs can serve either family if the label changes — which is exactly what section 8.2 showed with the price column removed.
Recap + bridge. Regression and classification share labeled data; they differ only in the answer column — a real number (regression) vs a fixed list of categories (classification). The rest of the session works one supervised technique in full detail — simple linear regression — starting with the simplest possible version: one input attribute, one output, one straight line.
8.4 Simple Linear Regression
Hook. Every supervised problem asks the same question: which rule best fits the labeled data? With one input attribute and one continuous output, the candidate rule is a straight line — and the question becomes: which straight line? There are infinitely many of them.
8.4.1 The problem, simplified to one attribute
The house-price problem is simplified for study: suppose the price depends only on plot size. Price is plotted on one axis (in lakhs) against plot size on the other (in square feet), producing a two-dimensional scatter plot of training points. One attribute is independent — size can vary freely — and the attribute being predicted is dependent: given a size, the price is to be predicted.
From school days, the equation of a straight line is \(y = mx + c\), where \(m\) is the slope and \(c\) is the intercept. Relating it to this problem, and assuming the relationship between size and price is linear:
\[ \text{price} = m \cdot x + c \]
where \(x\) is the plot size. Given the training data, the objective is to come up with the line that fits these points. The assumption of linearity is important: if the relation were quadratic, the fit would not be a straight line.
Independent vs dependent, and the two numbers that define a line. The independent variable \(x\) (plot size) is the input that can take any value freely; the dependent variable \(y\) (price) is the output we must produce given \(x\). A straight line is fixed by exactly two numbers: the slope \(m\) — how many units \(y\) rises for one unit of \(x\) — and the intercept \(c\) — the value of \(y\) where the line crosses the vertical axis, i.e. at \(x = 0\). Change either number and a different line slides into view; that is why "fit a line" and "choose \(m\) and \(c\)" are the same sentence.
8.4.2 The algorithm vs the model
A line becomes the model only after its parameters are learned. There is a real difference between an algorithm and a model: once \(m\) and \(c\) have been identified, these are the model parameters — \(m\) is the slope and \(c\) is the intercept. The procedure that finds them is the algorithm; the resulting line is the model.
The student's "kind of" from 8.2.3, now resolved. The algorithm is the procedure that searches for \(m\) and \(c\) (for example, the least-squares recipe of section 8.4.8, or in Spark a fit call, section 8.6). The model is the finished line — the concrete \(m\) and \(c\) that survived the search. Two different algorithms (or two different seeds) can produce two different lines: two models. And the same algorithm trained on different data produces different models. So: algorithm = recipe, model = dish.
8.4.3 Which line is best? The error, point by point
Looking at the scatter plot, infinitely many lines can be drawn through the cloud of blue points — this line, that line, \(n\) number of lines. Which one best fits the points? That is the objective, and it is important to understand how to decide.
Focus on a single fitted line. Some points fall below the line, some fall above it. For each point, the vertical distance between the point and the line is the error between the model being selected and the original point. For a point below the line the error is negative in sign, but the magnitude of the error is still there; other points show small errors. So: we can fit a number of lines, but we choose the one that minimizes this error across different points. The definition of "error across all training data" needs a term; wherever that term is minimum, that line is chosen as the model.
Visual intuition. Draw the scatter plot with plot size (square feet) on the horizontal axis and price (lakhs) on the vertical axis. The training points form a rising cloud — bigger plots, higher prices, with scatter around the general trend. Overlay any candidate line: some blue points sit above it, some below. The vertical gap between each point and the line is the error for that point — not the diagonal distance, because prediction happens along the price axis. The line with the smallest total vertical gap — the one that threads the middle of the cloud — is the fit we want. The cloud is never threaded exactly; every point has some residual error, and that fact survives into section 8.6: 100% accuracy cannot be achieved.
8.4.4 Worked notation change: from \(m, c\) to \(\theta_0, \theta_1\)
To follow the books, the notation changes. With \(y = mx + c\):
- \(\theta_0 = c\) — the intercept
- \(\theta_1 = m\) — the slope
so the model becomes:
\[ y = \theta_0 + \theta_1 x \]
The task is to find \(\theta_0\) and \(\theta_1\). Once they are found, for any given value of \(x\) the model can predict \(y\).
Notation. The textbooks write the same line as \(y = \theta_0 + \theta_1 x\): \(\theta_0\) (theta-nought) is the intercept \(c\), and \(\theta_1\) (theta-one) is the slope \(m\). Nothing mathematical changes — only the names. The theta notation scales: when there are many inputs it generalizes to \(y = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \dots\) (section 8.5), which is why the books adopt it from the start. Keep one notation per concept: this section, and the hands-on in 8.6, use thetas throughout.
8.4.5 Worked prediction with \(y = 2 + 5x\)
Suppose the learned parameters are \(\theta_0 = 2\) and \(\theta_1 = 5\), giving:
\[ y = 2 + 5x \]
Given a plot size of 750 (square feet), the predicted price is:
\[ \hat{y} = 5 \times 750 + 2 = 3752 \]
That is the predicted value. For each training record, this predicted value is compared with the actual value we already know, and the difference is computed.
The prediction, step by step. Learned model: \(\theta_0 = 2\) (intercept), \(\theta_1 = 5\) (slope — price rises 5 units per square foot). New input: \(x = 750\) square feet.
- Multiply the slope by the input: \(5 \times 750 = 3750\).
- Add the intercept: \(3750 + 2 = 3752\).
Predicted price \(\hat{y} = 3752\) (in lakhs, say ₹37.52 lakh in this running example). Sense-check: 5 units per square foot over 750 square feet dominates the tiny intercept of 2, so a price around 3750 is the right order; the intercept only nudges the result. If the actual historical sale price of that plot was, say, 3600, then this record contributes an error of \(3600 - 3752 = -152\) — the size of the gap matters, not the sign, which is exactly why the metrics below square the gaps.
8.4.6 Root mean squared error (RMSE)
Let \(y_j\) be the actual value of the \(j\)-th training point and \(\hat{y}_j\) (read "y-j hat"; some people say "y-j cap") the predicted value. The error per point is the difference \(y_j - \hat{y}_j\). To build one number out of all training points:
\[ \text{RMSE} = \sqrt{\frac{1}{n}\sum_{j=1}^{n} \left( y_j - \hat{y}_j \right)^2} \]
where \(n\) is the number of training data points. Each difference is squared, the squares are summed over all \(n\) points, the sum is divided by \(n\), and a square root is taken at the end "to balance out" the squaring. That is why the term is root mean squared error — the mean (average over \(n\)) of squared errors, then rooted.
Reading RMSE piece by piece. Name every symbol: \(y_j\) (y-sub-j) is the actual price of the \(j\)-th training house; \(\hat{y}_j\) ("y-j hat") is what the line predicted for that house; \(n\) is how many training houses there are. Inside the sum, \((y_j - \hat{y}_j)^2\) is the squared gap for one house — squaring does two jobs: it kills negative signs (a point below the line would otherwise subtract from the total), and it punishes big gaps harder than small ones (a gap of 10 contributes \(10^2 = 100\), four times the \(5^2 = 25\) of a gap of 5). The \(1/n\) turns the total into a mean — an average gap per house — and the final square root restores the original units (price units, not squared price units), "balancing out" the squaring as the professor puts it. The result is a single number: the typical distance between the line and the data, in price units.
8.4.7 Mean absolute error (MAE)
A variant metric replaces the square with the absolute value (mod):
\[ \text{MAE} = \frac{1}{n}\sum_{j=1}^{n} \left| y_j - \hat{y}_j \right| \]
If you do not square, you do not need the square root. Both RMSE and MAE can be computed, but RMSE is largely the one used; algorithms such as gradient descent typically work with RMSE-style objectives. (Gradient descent itself is not covered here.)
The two metrics on the same three houses. Suppose three training records with actual prices \(y = [3600, 4000, 4300]\) and predicted values \(\hat{y} = [3700, 3900, 4400]\).
Errors \(y_j - \hat{y}_j\): \([-100, +100, -100]\).
MAE: \(\frac{|{-100}| + |100| + |{-100}|}{3} = \frac{300}{3} = 100\).
RMSE: \(\sqrt{\frac{100^2 + 100^2 + 100^2}{3}} = \sqrt{\frac{30000}{3}} = \sqrt{10000} = 100\).
Now repeat with one outlier — a fourth house where the model is off by 400: errors \([-100, +100, -100, +400]\).
MAE: \(\frac{100+100+100+400}{4} = \frac{700}{4} = 175\).
RMSE: \(\sqrt{\frac{10000+10000+10000+160000}{4}} = \sqrt{\frac{190000}{4}} = \sqrt{47500} \approx 218\).
Conclusion: both metrics agree when errors are even, but RMSE jumps higher when one gap is large (218 vs 175) — squaring gives big mistakes extra weight. That is exactly why RMSE is the default: a model that is usually right but occasionally wildly wrong looks bad under RMSE and tolerable under MAE. Sense-check: RMSE \(\ge\) MAE always (squaring punishes outliers), and the two meet only when every gap is identical — as the first half of this example shows.
8.4.8 The complete recipe for simple linear regression
Putting the whole section together: price is dependent on plot size; the equation \(\theta_0 + \theta_1 x\) gives predicted values; actual values are already known for each house instance; for each instance take the difference; either take the mod of the difference or the square of it; compute RMSE or MAE; and the objective is to minimize the RMSE (or the MAE) so that the line passes as close as possible through all the points — the line giving the minimum error.
Pitfalls.
- Forgetting the squaring step's purpose. Squaring is not cosmetic — it makes every gap count positively and punishes big gaps disproportionately. "Average the errors" without squaring lets a +100 and a −100 cancel to zero, hiding a badly fitted line.
- Confusing sign with size. A point below the line gives a negative error; that does not mean "no error". Magnitude is everything — the metrics are built to remove the sign.
- Treating linearity as optional. The whole fit assumes the relationship is a straight line. If the true relation is quadratic, forcing a line underfits — the professor flags this before any math: "if the relation were quadratic, the fit would not be a straight line".
- Splitting the "root mean squared" name. The order matters: mean of squares, then square root — not root of mean, not mean of roots. The 3-house example gives RMSE 100 only because the operations are done in that exact order.
Recap + bridge. Simple linear regression = assume \(y = \theta_0 + \theta_1 x\), define per-point error, aggregate it as RMSE or MAE, and pick the line with the smallest aggregate. The two metrics — and the fact that 100% accuracy is impossible — carry straight into the hands-on: a real Spark run on 506 houses with 13 input attributes, which is where the thetas multiply into \(\theta_0, \theta_1, \dots, \theta_{13}\).
8.5 Multilinear and Polynomial Regression
Simple linear regression is based on a single attribute. Two extensions are introduced, briefly, with the reassurance that in machine learning the libraries handle the complexity — it is a library call and things are done automatically.
8.5.1 Multilinear regression
In multilinear regression, \(y\) depends on multiple features at once — not just plot size, but number of bedrooms, distance from the city, marble or granite flooring, upgraded kitchen, and so on. With each feature there is an associated weight, plus an intercept:
\[ y = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \cdots + \theta_d x_d \]
where \(x_1, x_2, \dots, x_d\) are the \(d\) input features and \(\theta_1, \dots, \theta_d\) are their weights.
The intuition in machine learning terminology: \(x\) is a set of features — input features. In the simple case \(x\) was the single size of the house; it could be multiple variables: number of bedrooms, distance from the city, granite flooring, upgraded kitchen, and so on. The output is predicted from the input features.
One line, many inputs — nothing else changes. Multilinear regression is the same straight-line idea with the single \(x\) replaced by a list \(x_1, x_2, \dots, x_d\) of \(d\) features. Each feature gets its own weight \(\theta_i\) saying how strongly it moves the price, and the lone \(\theta_0\) intercept is unchanged. The reference form matches the professor's: \(Y = a + b_1 x_1 + b_2 x_2 + \cdots + b_n x_n\) with intercept \(a\) and coefficients \(b_i\) — only the letter for the weight differs. Geometrically the "line" becomes a hyperplane in \(d+1\) dimensions, but the objective is identical: pick the weights that minimize RMSE. The Boston demo (section 8.6) is genuinely multilinear — 13 features, 13 weights, one intercept — which is why it prints coefficients and intercept separately.
8.5.2 Polynomial regression
In polynomial regression, higher-degree terms are added:
\[ y = \theta_0 + \theta_1 x + \theta_2 x^2 + \theta_3 x^3 + \cdots \]
Up to the \(x^2\) term it is quadratic; further terms like \(\theta_3 x^3\) take it to higher degrees. Each of these regressions (simple, multilinear, polynomial) would take a full lecture on its own, so the session stays with the simple case — simple linear regression — and the objective of minimizing root mean squared error.
Intuition: why add \(x^2, x^3\) terms? If the scatter cloud curves (prices rising fast at small sizes, slowly at large sizes), no straight line will thread it. Polynomial regression bends the curve by adding powers of \(x\), each with its own weight. Degree 2 (quadratic) is one bend; degree 3 adds a second bend; every extra term adds flexibility. The professor's warning applies here too: each of these extensions would need a full lecture, and in practice the libraries do the work — the same LinearRegression call fits all of them. In Spark, polynomial features would be created as new input columns, and the multilinear machinery from 8.5.1 then applies unchanged.
Scope: extensions, not new skills. The session deliberately stops at simple linear regression. Multilinear and polynomial regression are named so that you recognize them when you meet them, but the examinable objective remains the one from section 8.4: minimize the RMSE. No formula beyond the two shown above is expected from this topic.
Recap + bridge. Multilinear regression: one weight per feature plus an intercept. Polynomial regression: powers of \(x\) with their own weights. Both are "a library call" in practice — which is the perfect setup for the hands-on, where 13 features and one intercept are fitted on real data by a single fit.
8.6 Hands-On: Linear Regression in PySpark
A small program, regression_1.py, is run via spark-submit against a live Spark cluster (already connected to the lab's Spark cluster). The dataset is boston.csv, a standard dataset available on the internet; it has already been downloaded onto the system.
Purpose. Everything from sections 8.4 and 8.5, running as one real program: read data, build a feature vector, split into train/test, call fit, and read off coefficients, intercept, and RMSE/MAE. The point is not the math — it is seeing the machine learning vocabulary map onto MLlib calls.
8.6.1 The boston.csv dataset
The file contains input attributes (the classic Boston housing attributes) plus a medv column — the median value, which is the price to predict. The output feature is deliberately kept separate from the input features. The data has 506 records; a statistical description shows, for each attribute, the count, the mean, the standard deviation, and the min and max. For example, crim is basically the crime rate near the area, and for medv (the output) the mean is about 22. This is the training data.
Dataset anatomy. The classic Boston housing dataset has 13 input attributes — crime rate (crim), average rooms per dwelling, age of the property, distance to employment centres, and so on — plus medv, the median house value in thousands of dollars, as the label. Two structural points matter: the label column is deliberately not one of the input columns (the output must stay separate so it is not fed back as an input), and the 13 attributes make this a genuinely multilinear regression, not the simple one-attribute case of section 8.4. The describe output — count, mean, standard deviation, min, max per column — is the standard first look at any dataset: it exposes missing values (a count below 506), scale differences between columns, and where each attribute lives.
8.6.2 Program structure, step by step
- Imports: from
pyspark, import packages related to Spark configuration, Spark context, and additionally an SQL context, because data frames are used — after RDDs came data frames and datasets, and a data frame is the most structured. The SQL context helps read the CSV file and put it into a data frame. - Read the file: create the Spark context, then the SQL context; specify the format to read and the file to read, and load it into a
housedata frame. - Inspect: print the data frame (schema — the columns come out as double, double, integer, double, and so on — and
show), anddescribe, which gives a statistical description of each attribute — count, mean, standard deviation, min, max for every input attribute as well as the output. - Vector assembler: from
pyspark.ml.feature, importVectorAssembler. It is given the input columns and asked to create a single vector out of them calledfeatures— bundling the whole set of input parameters into one vector column. Thetransformfunction is applied to the data frame; themedvcolumn is left out offeaturesbecause it is the output, the thing to predict. - Train/test split:
randomSplit([0.7, 0.3])— every machine learning algorithm follows this pattern: use some percentage of the data for training and some for testing. The split is random and the two parts are disjoint: one single record must not appear in both.splits[0](70% of the data) is the training data frame;splits[1](30%) is the testing data frame. The data used to train the model must not be used to test it; only then is testing real, because the model must be tested against unseen data (seen data is what it already learned from). - Model call: from
pyspark.ml.regression, importLinearRegression. Call the constructor with: the feature column (features, built by the vector assembler), the label column (medv),maxIter=10(10 iterations), and a regularization parameter. (Regularization relates to underfitting/overfitting, not yet discussed; these parameters help avoid overfitting — a one-liner about overfitting follows later. For now they can be skipped.) - Fit:
lrModel = lr.fit(trainingData)— callingfiton the training data produces the line. That is all: one call and the model is ready. - Coefficients and intercept:
lrModel.coefficientsandlrModel.intercept— recall \(\theta_0, \theta_1, \theta_2, \dots\); the coefficients correspond to the features (how many there are depends on the number of input features), and the intercept is the constant \(\theta_0\). - Training errors:
trainingSummary = lrModel.summary, thentrainingSummary.rootMeanSquaredErrorandtrainingSummary.meanAbsoluteError. - Predict on test data: make predictions on the test data frame; print, for each of the top five records, the prediction, the actual value, and the feature set of that record. Then compute RMSE and MAE on the test data. Finally do the same on the whole dataset —
showprints 20 rows by default (not the whole file), which is why five rows are printed first and then 20.
Inputs and outputs of each stage. Vector assembler: inputs = the 13 input columns; output = one features vector column per row (13 numbers bundled; medv excluded). Split: inputs = the full frame; outputs = two disjoint frames, splits[0] (≈70%) and splits[1] (≈30%). LinearRegression + fit: inputs = the features column name, the medv label column name, maxIter, regularization; output = a fitted model with a coefficient for each of the 13 features plus one intercept. Every stage passes one data frame to the next — that chain of shapes is the whole program.
Trace: what a fitted line looks like here. The demo model is not \(y = \theta_0 + \theta_1 x\) but the multilinear form from section 8.5:
\[ y = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \cdots + \theta_{13} x_{13} \]
with \(x_1\) = crime rate, \(x_2\) = average rooms, and so on. lrModel.coefficients returns the 13 weights \(\theta_1 \dots \theta_{13}\) and lrModel.intercept returns \(\theta_0\). When one printed weight is around 3.1 and several are exactly 0.0, read that as: that feature moves the price by about 3.1 units per unit of the attribute, and a 0.0 coefficient means that feature is not very important to the fit. fit runs the solver for up to maxIter=10 iterations and returns the finished model — the "algorithm finds the parameters, the line is the model" of section 8.4, live.
8.6.3 What the program prints
- The data frame and its schema.
- The statistical summary (describe) — 506 records per attribute.
- Three rows after the vector assembler (the call was
df.show(3)): the feature set, withmedvalongside. - Training errors: RMSE and MAE of about 4.7 and 3.27 respectively.
- Coefficients and intercept: the constant \(\theta_0\) (intercept), then \(\theta_1, \theta_2, \theta_3, \dots\) — as many thetas as input attributes, including one around 3.1 and several 0.0 values. A 0.0 coefficient means that feature is not very important. With 13 input attributes and an intercept this is truly multilinear regression, not the simple case.
- Test predictions (first five rows): record 1 — actual 24, predicted 30.19; record 2 — actual 31.01, predicted 32.2; record 3 — actual 35.4, predicted 30.84; record 4 — actual 18.9, predicted 17.10; record 5 — actual 23.1, predicted 26.12.
- Test errors: RMSE for test data 5.2, MAE for test data 3.4. There is a little difference between the RMSE on training data and on test data.
- The final
showprints 20 rows — the first five already seen, plus 15 more.
Reading the two error numbers together. The training output lists two values near 4.7 and 3.27. The order is fixed by a mathematical guarantee from section 8.4: RMSE is always at least MAE, because squaring punishes large gaps (the worked example showed 218 vs 175). So the only consistent reading is training RMSE ≈ 4.7, training MAE ≈ 3.27 — the model is off by about 4.7 price units in the RMSE sense on the data it was trained on. On the test data the numbers are RMSE 5.2 and MAE 3.4: both slightly worse, because the test records were never seen during fitting. A test error close to the training error (5.2 vs 4.7) is the healthy pattern — it says the model generalizes; a huge gap would mean overfitting (memorizing the training data, section 8.10).
8.6.4 Reading the output
There is an error with respect to each and every training record, and that will always be there — 100% accuracy cannot be achieved. This is the simple way of doing linear regression: no hyperparameter tuning, which is very deep for this course — this is not a machine learning or data mining course — so just a simple case showing how to do it and how to check the output on Spark.
Pitfalls.
- Expecting zero error. The fifth printed row (actual 18.9, predicted 17.10) is typical: no real dataset lies on a perfect line, so a nonzero error per record is guaranteed — the professor flags this explicitly.
- Mixing up training and test errors. The model is evaluated twice; only the test numbers measure real performance on unseen data. Quoting the training RMSE as "the accuracy" overstates the model.
- Reading 0.0 coefficients as bugs. A zero weight is information: the solver found that feature adds nothing to the prediction. It is not a crash.
- Forgetting
showtruncates.showprints 20 rows by default — the five printed explicitly plus fifteen more, not the whole file.
Real-world & domain connection. The Boston housing dataset (506 records, 13 attributes) is one of the most widely used public benchmarks for teaching regression — the same file appears in countless textbooks and tutorials, which is why the professor picks it for the demo. The workflow shown — assemble features, split, fit, measure RMSE — is the exact skeleton that e-commerce firms (Amazon, Flipkart in section 8.3) scale up to predict sales over events like the Big Billion Days, with the same train/test discipline but far more features and data.
Recap + bridge. The hands-on turned the theory into a ten-step program: imports → read → inspect → vector assembler → 0.7/0.3 disjoint split → LinearRegression with maxIter → fit → coefficients/intercept → training RMSE 4.7/MAE 3.27 → test RMSE 5.2/MAE 3.4. The key discipline — never test on data you trained on — reappears in the next demo, where the tree classifier is built and judged the same way.
8.7 Classification
Classification is revisited more formally. It is a supervised learning problem: training data is labeled, a classifier learns from it, and the classifier is tested on unseen data.
Hook. How does a university decide whether a lecturer will stay tenured? With a rule: "professor rank, or more than six years of service — tenured". Classification is the machinery that learns such rules from labeled records and then fires them on new people it has never seen.
8.7.1 Classification is a two-step process
- Model construction: you have training data with associated labels, and the model is represented in some form — classification rules, decision trees, or a mathematical formula (support vector machines and the like). There are many techniques; the major focus of this session is decision trees.
- Model usage: the built classifier is used on unseen data.
After building the classifier with any of these techniques, the objective is to estimate the accuracy: the rate — the percentage — of test samples correctly classified by the model.
The two phases, and how to judge the whole exercise. Construction (also called training or induction): the labeled rows are fed in and the algorithm produces a classifier — the representation can be a set of if-then rules, a tree of tests (section 8.8), or a mathematical formula such as a support-vector boundary. Usage (also called prediction or deduction): fresh records without labels pass through the classifier and come out with a predicted class. The quality number is accuracy:
\[ \text{Accuracy} = \frac{\text{number of test samples correctly classified}}{\text{total number of test samples}} \times 100\% \]
That percentage is the "performance \(P\)" of Mitchell's definition from section 8.1, applied to classification.
8.7.2 Worked example: tenure prediction
A small labeled dataset has attributes: name, rank (assistant professor), years (3). The output attribute is whether the person is tenured — no or yes. Feeding this to a classification algorithm, it learns rules, e.g.:
\[ \text{if rank} = \text{professor} \quad \text{or} \quad \text{years} > 6 \quad \text{then tenured} = \text{yes} \]
When new, unseen data arrives, the rules trigger and the class (yes or no) is output. Test data: associate professor with number of years greater than 7 — since years > 6, the rule fires and tenured is predicted yes. Training is being done on the labeled data; testing is done on the unseen data.
The tenure example, step by step. Training set: labeled records such as ("A. Kumar", assistant professor, 3 years, not tenured), ("B. Rao", professor, 9 years, tenured), and so on. The algorithm inspects which attribute values line up with tenured/not-tenured and extracts the rule shown above — the or matters: a person satisfies it if either condition holds.
Now a test record arrives: (name, associate professor, 7 years, ? — no label).
- Check condition 1: rank = professor? No (associate professor ≠ professor).
- Check condition 2: years > 6? Yes (7 > 6).
- The
ormeans one true condition is enough → rule fires.
Prediction: tenured = yes. Sense-check: seven years on the job clears the six-year threshold comfortably, and the rule captures the data's pattern that seniority, not just the top rank, earns tenure. To estimate the accuracy, this same test would run over many unseen records and the fraction predicted correctly becomes the accuracy percentage.
Real-world & domain connection. The tenure example is a classic HR-decision pattern, and the same construction-usage loop runs in production systems everywhere: banks score loan applications (accept/reject) from historical borrower records; hospitals triage patients (high-risk/low-risk) from historical outcomes; universities and firms screen candidates from past recruitment data — the employability example from section 8.3 is the same shape. Wherever a decision has a yes/no answer and a history of past decisions, a classifier can be built and its accuracy measured.
Recap + bridge. Classification = build (learn rules, trees, or formulas from labeled data) then use (fire the classifier on unseen data), judged by accuracy. The rest of the classification part of the session is one technique in detail — decision trees — which need to answer two hard questions: which attribute to test first, and when to stop. The buys-computer dataset is the vehicle.
8.8 Decision Trees and the Buys-Computer Example
The classic buys-computer dataset is the vehicle for decision trees, and decision trees are the major focus of the classification part of the session.
Hook. A shop wants to know: which of its customers will buy a computer? The data has four facts about each customer — age, income, whether a student, credit rating. A decision tree answers with a chain of yes/no tests — "young? student? then likely to buy" — that is simple enough to show a manager and powerful enough to run the whole shop.
8.8.1 The dataset
Four input attributes:
- age — three values: youth, middle-aged, senior
- income — high, medium, or low
- student — no or yes
- credit rating — fair or excellent
The output attribute is whether the person buys a computer — the class to predict. There are 14 tuples: 9 belong to yes and 5 belong to no.
8.8.2 Building the tree
The tree checks age first, with three branches:
- youth → check student: if not a student → not likely to buy; if a student → yes, likely to buy.
- middle-aged → simply yes: all four middle-aged entries have "yes" output, so a pure yes class is placed there.
- senior → check credit rating: excellent → buys a computer; fair → no. Among the five senior entries there are three yes and two no.
The tree is learned from the data, and it then predicts the class for new records. How the tree is learned — how the attributes are chosen at each level — is the important part.
Three new customers, walked down the tree. The learned tree is: age? → youth: check student; middle-aged: yes; senior: check credit rating. Now classify three unseen records.
Record 1: (youth, income medium, student yes, credit fair). Start at the root: age = youth → follow the youth branch → check student: student = yes → prediction: buys computer = yes.
Record 2: (middle-aged, income high, student no, credit excellent). Root: age = middle-aged → leaf yes — no further test needed, this is the pure 4/4 branch.
Record 3: (senior, income low, student no, credit rating fair). Root: age = senior → check credit rating: fair → prediction: buys computer = no.
Predictions: yes, yes, no. Sense-check: records 1 and 2 reach pure leaves (the yes leaf, the student-yes leaf), while record 3 lands on the senior/fair path where the training data leaned "no" (2 of the 5 senior tuples with fair credit did not buy) — the tree is consistent with the 14 labeled tuples it was built from.
Visual intuition. Draw a top-down chart. At the top, a root node labelled "age?" with three arrows leaving it: youth → (a node "student?") → no/yes; middle-aged → (a leaf labelled "yes"); senior → (a node "credit rating?") → excellent/yes, fair/no. The path a record takes is a chain of tests: the depth of the tree is the number of tests on the longest chain (this one is depth 2). A new customer enters at the root, answers each question, and exits at a leaf carrying the class. The tree is worth drawing once because every later concept — split attribute, purity, stopping — is a property of this picture.
8.8.3 Pure partitions: the goal of each split
As you move deeper down the tree, each branch should lead to a pure partition: at the next level down, the tuples belonging to a class should maximally belong to one class. The middle-aged branch is the simplest illustration: all tuples at that level belong to one class, so the yes class is placed there — a pure partition. A branch that produces tuples closer to pure partitions is more helpful and guides tree construction.
Pure vs impure, precisely. A node's tuples are pure when they all carry the same class. The middle-aged node holds 4 tuples, all "yes" — 100% pure, no further question needed. The senior node holds 5 tuples with 3 yes and 2 no — impure, so the tree keeps splitting it (on credit rating) until the leaves are pure. A split is judged by how much purity it creates: the split whose branches end in purer partitions is the better split. This single criterion is what the metrics of section 8.9 — information gain and gini — turn into numbers.
8.8.4 The two big challenges
- Which attribute to choose first? Here age was chosen — why age and not income, student, or credit rating at the first stage?
- What are the stopping conditions? It may not be possible that every split results in pure partitions; partitions may always remain impure, because 100% accuracy cannot be achieved.
Scope: why these two questions matter. Question 1 is the entire art of tree learning: any attribute could sit at the root, and different choices yield different trees with different accuracies. Question 2 keeps the tree from growing forever: if the algorithm kept splitting until every leaf was pure on the training data, it would memorize the data instead of generalizing — the underfit/overfit tension that appears again in the wine demo (section 8.10). Both questions are resolved in section 8.9 (metrics) and here (stopping conditions).
8.8.5 Stopping conditions
Any of the following can stop a branch:
- All samples for a given node belong to the same class (the middle-aged case).
- There are no remaining attributes for further partitioning — all attributes have been tested and there is no need to test the rest.
- Majority voting is employed for classifying the leaf — if tuples are still left that cannot be classified, apply majority voting: for example, at a credit-rating leaf, if 70% of the people with that rating buy and 30% do not, then anyone arriving with credit rating excellent is classified as yes.
- There are no samples left in a branch.
The four off-switches. A branch stops growing when it hits any one of: (1) perfect purity — every tuple in the node shares a class, nothing left to separate; (2) no attributes remain — every input column has already been tested along this path; (3) an impure leaf — the node cannot be made pure, so the leaf votes: the majority class among its tuples wins, e.g. 70% buy → classify as yes (this is also how the impurity of section 8.8.3 is handled in practice); (4) an empty branch — a split produced a child with no tuples. Conditions 1 and 3 are the ones that actually occur in the buys-computer tree; 2 and 4 are the safety nets that keep recursion from going forever.
8.8.6 Types of splits
The splitting criterion can take several forms:
- Multiway split on a discrete attribute: color → red / green / blue / purple / orange; income → low / medium / high.
- Binary split on a discrete attribute: color red → go to this branch; not red → go to that branch (still two branches).
- Binary split on a continuous attribute: choose a split point — less than 42,000 → this branch; greater than 42,000 → that branch.
All sorts of splits are possible; what matters is how to decide among them.
Split types at a glance. Discrete attributes can split many ways (one branch per value, or two branches that group the values); continuous attributes need a split point — a threshold — that divides the value range into two halves. The buys-computer tree uses multiway splits on age (three values → three branches) and binary splits on student and credit rating. The decision among all these candidate splits is a pure-arithmetic question — and that is the entire subject of section 8.9.
Recap + bridge. A decision tree is a chain of attribute tests ending at class leaves; each split aims at purer partitions; four stopping conditions bound the growth; splits can be multiway or binary. Everything so far leaves one question open — which attribute first? — and the next section answers it with numbers: information gain and gini.
8.9 Choosing the Split Attribute: Information Gain and Gini
The metric used to decide the splitting attribute is information gain (referred to in the flow of the session as "information game"). The same example is worked numerically: compute the information gain at the root level, then for a split on each attribute, and the attribute giving the maximum information gain is chosen for the first split. (Gini index is the companion method: maximum information gain, minimum gini.)
Hook and intuition. Which question should the tree ask first — age, income, student status, or credit rating? The intuition from section 8.8 gives the criterion: the split that leads to the most pure partitions. Information gain and gini are two different rulers for measuring that purity, and the buys-computer numbers are worked out with both rulers so you can see them agree.
8.9.1 Worked computation: information at the root
There are two classes: buys a computer (yes) or does not (no). Out of 14 tuples, 9 belong to yes and 5 to no. The information at the root is:
\[ I(9,5) = -\frac{9}{14}\log_2\frac{9}{14} - \frac{5}{14}\log_2\frac{5}{14} \]
The professor states the value of this as 0.940 — the information at this moment, when 9 tuples belong to one class and 5 to another. Mathematically, information gain is the way to find the partition that takes the tree to a more pure form: the partition whose next level has the maximum tuples belonging to one class.
Entropy — the information ruler, symbol by symbol. For a node whose tuples are split between classes with probabilities \(p_1\) (yes) and \(p_2\) (no), the entropy (how mixed the node is; the bank's "average surprise" analogy) is:
\[ I(p_1, p_2) = -p_1 \log_2 p_1 - p_2 \log_2 p_2 \]
with \(\log_2\) the base-2 logarithm ("how many times you double 1 to reach the count"). Two boundary checks pin down the scale: a perfectly pure node (\(p_1 = 1, p_2 = 0\)) gives \(I = -1\cdot 0 - 0 \cdot(-\infty) \to 0\) — no surprise at all; a perfectly mixed node (\(p_1 = p_2 = 0.5\)) gives \(I = -0.5(-1) - 0.5(-1) = 1\) — maximum surprise. The root node, with \(9/14 \approx 0.643\) and \(5/14 \approx 0.357\), sits between: \(I(9,5) = 0.940\), close to 1 because the classes are fairly mixed. Information gain = how much a split reduces this number: the bigger the drop, the more purity gained, the better the split.
8.9.2 Worked computation: splitting on age
For the age attribute there are three branches — youth, middle-aged, senior — with the following yes/no counts:
- youth: 5 tuples total — 2 yes, 3 no
- middle-aged: 4 tuples — all 4 yes, 0 no
- senior: 5 tuples — 3 yes, 2 no
The weighted information after splitting on age:
\[ I_{\text{age}} = \frac{5}{14}\,I(2,3) + \frac{4}{14}\,I(4,0) + \frac{5}{14}\,I(3,2) \]
expanding each term:
\[ I(2,3) = -\frac{2}{5}\log_2\frac{2}{5} - \frac{3}{5}\log_2\frac{3}{5} \]
\[ I(4,0) = -\frac{4}{4}\log_2\frac{4}{4} - 0 \cdot \log_2 0 = 0 \]
the middle-aged term cancels out — the \(4/4\) and zero contributions make that term zero — and
\[ I(3,2) = -\frac{3}{5}\log_2\frac{3}{5} - \frac{2}{5}\log_2\frac{2}{5} \]
The total comes to 0.694.
The age arithmetic, filled in end to end.
Branch 1, youth (5 tuples, 2 yes 3 no): \[ I(2,3) = -\frac{2}{5}\log_2\frac{2}{5} - \frac{3}{5}\log_2\frac{3}{5} \approx -0.4(-1.322) - 0.6(-0.737) \approx 0.529 + 0.442 = 0.971 \]
Branch 2, middle-aged (4 tuples, 4 yes 0 no): pure node — the first term is \(-\frac{4}{4}\log_2 1 = 0\) and the second is \(0 \cdot \log_2 0\), which convention sets to 0. \(I(4,0) = 0\) — a pure partition carries no information left to gain.
Branch 3, senior (5 tuples, 3 yes 2 no): same shape as youth, \[ I(3,2) = -\frac{3}{5}\log_2\frac{3}{5} - \frac{2}{5}\log_2\frac{2}{5} \approx 0.971 \]
Weighted sum: \[ I_{\text{age}} = \frac{5}{14}(0.971) + \frac{4}{14}(0) + \frac{5}{14}(0.971) = 0.347 + 0 + 0.347 = 0.694 \]
The split on age drops the information from 0.940 to 0.694. Sense-check: the middle-aged branch is pure (its term vanishes), the other two branches are still mixed, and the weighted average correctly lies between 0 (fully pure) and 0.971 (the two impure branches).
8.9.3 Worked computation: the gain, and the winner
The information gain for age:
\[ \text{Gain}(\text{age}) = 0.940 - 0.694 = 0.246 \]
Similar gains are calculated for income, student, and credit rating, and the values come out lower. The information gain is highest for age, so age is chosen as the splitting attribute at the first stage.
The other three candidates, for comparison. Computing each attribute the same way gives the published reference values for this dataset:
\[ \text{Gain}(\text{income}) = 0.940 - 0.911 = 0.029, \qquad \text{Gain}(\text{student}) = 0.940 - 0.789 = 0.151 \]
\[ \text{Gain}(\text{credit rating}) = 0.940 - 0.892 = 0.048 \]
Ranked: age 0.246 > student 0.151 > credit rating 0.048 > income 0.029. Age wins by a wide margin, so the root test is "age?". Sense-check against intuition: income barely separates the classes (every income group has both buyers and non-buyers — gain ≈ 0), while age at least isolates the pure middle-aged block — the biggest information drop of the four.
8.9.4 Gini index
A second metric: gini index. At the root level, with 9 yes and 5 no:
\[ \text{Gini}(\text{root}) = 1 - \left(\frac{9}{14}\right)^2 - \left(\frac{5}{14}\right)^2 \]
where the terms are the probability of the yes class and the probability of the no class. Then try it for each attribute. For income, suppose the partition is:
- \(D_1\): low + medium income — 10 tuples out of 14
- \(D_2\): high income — 4 tuples out of 14
so the weights are \(10/14\) and \(4/14\). Within \(D_1\), of the 10 tuples, 7 buy and 3 do not; within \(D_2\), of the 4, 2 buy and 2 do not. The reported gini values for the three possible income splits are:
- low–high split: 0.458
- medium–high split: 0.450
- low–medium split: 0.443
Since the low–medium split has the lowest gini index, low and medium are put in one bucket and high in another — that split gives the more pure partitions.
Gini — the impurity ruler. For a node with class probabilities \(p_1, p_2\):
\[ \text{Gini} = 1 - p_1^2 - p_2^2 \]
It is a sibling of entropy: a pure node (one class with probability 1) gives \(1 - 1^2 - 0 = 0\) — zero impurity; a 50/50 node gives \(1 - 0.25 - 0.25 = 0.5\). For a multi-branch split, take the weighted average of each branch's gini, weighting by the fraction of tuples that branch holds — exactly the \(10/14\) and \(4/14\) weights above. The direction is flipped relative to information gain: entropy drops as purity grows, gini drops as purity grows, so a split is judged by minimum gini (lowest impurity) and maximum information gain (largest entropy drop). Both rulers pick the same kind of split: the one whose branches are most single-class.
The three income splits, with every number shown. Using the buys-computer income counts (low: 4 tuples, 3 yes 1 no; medium: 6 tuples, 4 yes 2 no; high: 4 tuples, 2 yes 2 no):
Split 1 — low+medium vs high (\(D_1\): 10 tuples, 7 yes 3 no; \(D_2\): 4 tuples, 2 yes 2 no): \[ \text{Gini}(D_1) = 1 - \left(\frac{7}{10}\right)^2 - \left(\frac{3}{10}\right)^2 = 1 - 0.49 - 0.09 = 0.42, \qquad \text{Gini}(D_2) = 1 - \left(\frac{2}{4}\right)^2 - \left(\frac{2}{4}\right)^2 = 0.5 \] \[ \text{Gini}_{\text{split}} = \frac{10}{14}(0.42) + \frac{4}{14}(0.5) = 0.30 + 0.143 = 0.443 \]
Split 2 — low+high vs medium (\(D_1\): 8 tuples, 5 yes 3 no; \(D_2\): 6 tuples, 4 yes 2 no): \[ \text{Gini}(D_1) = 1 - \frac{25}{64} - \frac{9}{64} = 0.469, \qquad \text{Gini}(D_2) = 1 - \frac{16}{36} - \frac{4}{36} = 0.444 \] \[ \text{Gini}_{\text{split}} = \frac{8}{14}(0.469) + \frac{6}{14}(0.444) = 0.268 + 0.190 = 0.458 \]
Split 3 — medium+high vs low (\(D_1\): 10 tuples, 6 yes 4 no; \(D_2\): 4 tuples, 3 yes 1 no): \[ \text{Gini}(D_1) = 1 - \frac{36}{100} - \frac{16}{100} = 0.48, \qquad \text{Gini}(D_2) = 1 - \frac{9}{16} - \frac{1}{16} = 0.375 \] \[ \text{Gini}_{\text{split}} = \frac{10}{14}(0.48) + \frac{4}{14}(0.375) = 0.343 + 0.107 = 0.450 \]
Results: 0.458 (low–high), 0.450 (medium–high), 0.443 (low–medium). The low–medium split has the lowest gini, so income is bucketed as {low, medium} vs {high}. Sense-check: the {low, medium} bucket holds a strong 7-out-of-10 buy majority, which is the most single-class combination available — exactly the "more pure partitions" criterion.
Exam note: For the attribute-selection question, learn both rulers: information gain — choose the maximum; gini index — choose the minimum. Different algorithms use different metrics (different algorithms use different stories), but these two are the ones for this course.
8.9.5 The one-liner rule
This may seem complex, but there is a one-liner: the partition should lead toward more pure partitions, and the ways to calculate which attribute leads to more pure partitions are information gain and gini — information gain highest, gini lowest, and that attribute is chosen. Different algorithms use different metrics (different algorithms use different stories), but these two methods are enough for this course at this moment.
Pitfalls.
- Mixing up the two directions. Information gain: higher is better (you gain information by splitting). Gini: lower is better (less impurity). The exams test exactly this pairing — maximum gain, minimum gini.
- Forgetting the weights. Each branch's entropy/gini counts in proportion to its size — the \(\frac{5}{14}, \frac{4}{14}, \frac{5}{14}\) multipliers. A tiny pure branch must not dominate the average.
- Treating \(I(4,0) = 0\) as a mystery. A node with one class carries zero uncertainty — the first term is \(-\frac{4}{4}\log_2 1 = 0\) and the second term's \(0 \cdot \log_2 0\) is defined as 0 by convention.
- Skipping the sense-check. After computing, always compare with intuition: a pure branch (middle-aged) or a strong-majority bucket (low+medium) should pull the metric toward its "pure" end — if your arithmetic contradicts that, re-check the fractions.
Real-world & domain connection. Information gain and gini are not classroom-only: gini impurity is the default splitting criterion in scikit-learn's DecisionTreeClassifier and in Spark MLlib's tree, while information gain drives ID3 and C4.5-style learners. Every decision-tree model in production — loan approval, fraud scoring, churn prediction — picks its splits with one of these two rulers, so the 0.246-vs-0.029 comparison above is literally the arithmetic that a bank's credit-scoring tree performs at scale.
Recap + bridge. Choose the split attribute by purity: information gain = entropy before minus weighted entropy after — maximize it (age wins with 0.246 over student 0.151, credit rating 0.048, income 0.029); gini = \(1 - \sum p_i^2\), weighted across branches — minimize it (income's low–medium split, 0.443, beats 0.450 and 0.458). One-liner: partition toward more pure partitions. The next stop is the same tree machinery running live on wine data, where depth (not gain) becomes the dial.
8.10 Hands-On: Decision Tree Classifier in PySpark
Purpose. The second demo runs the exact machinery of sections 8.7–8.9 on real data: bundle chemistry features into a vector, split with a reproducible seed, fit a DecisionTreeClassifier with a depth cap, and compare predictions against the true wine quality. Its real lesson is not the code — it is watching the depth/accuracy tradeoff appear in the printed output.
8.10.1 The wine.csv dataset
The classification demo uses wine.csv. The input features are the wine's chemistry: alcohol content, volatile acidity, citric acid, residual sugar, chlorides, free sulfur (dioxide), total sulfur dioxide, density, pH value, sulphates, alcohol. The output is the quality of the wine, rated on a scale (a quality rating of 6 appears in the printed rows) — so this is a multi-class classification problem.
Dataset anatomy. The wine-quality dataset is a standard public benchmark: each row is one wine described by its measurable chemistry — acidity, sugar, sulphates, pH, density, alcohol — and a quality score on a 0–10 scale assigned by expert tasters. Because the label has several possible values (3, 5, 6, 7, 8…), the problem is multi-class, unlike the two-class buys-computer tree. Nothing in the decision-tree machinery changes: the tree still chooses the split attribute by the same purity metrics, it simply has more classes to separate.
8.10.2 Program structure, step by step
- Imports (k-means is imported too in this file but ignored here, since it belongs to the clustering problem).
- Create the Spark context, read
wine.csv, build a data frame, display two records, print the schema — the same pattern as the regression program. - Vector assembler: bundle all input features into one vector column called
features;transformthe data frame. The output — wine quality — stays separate. - Show the top three records.
- Train/test split:
randomSplit([0.7, 0.3]), this time with a seed value given. The seed makes the random pick reproducible: 70% of records go to training, 30% to testing, and rerunning the program picks up the same set of records every time (without a seed, the random split differs each run). The seed value can be read about in Python's documentation. - Decision tree classifier: from
pyspark.ml.classification, importDecisionTreeClassifier. Give it thefeaturescolumn, say the label column isquality, set the maximum depth (depth 3 is used in the demo) — "we don't want to overfit the model" — and calldt.fit(trainingData). - Predict: make predictions on the test data (the 30%): for each record print
features,quality(the actual label), andprediction(the predicted class).
The whole program is deliberately limited: imports, read the file, build the data frame, vector assembler, train/test split, call the classifier, train the model, predict on test data, and see how many instances it correctly predicts.
The two new knobs: seed and maxDepth. The seed is an integer that initializes the random splitter — with the same seed, randomSplit produces the same 70/30 partition on every run, which makes experiments reproducible (without it, every run silently reshuffles which wines are training and which are test). maxDepth caps how many consecutive tests a path may have: depth 1 is a single question, depth 3 allows three nested questions, and so on. A shallow tree can only carve the class space coarsely — that is precisely the limit the demo wants to show.
8.10.3 Output and interpretation
The output table shows the input vector, the actual quality, and the prediction:
- quality = 3, prediction = 6
- quality = 8, prediction = 7
- quality = 5, prediction = 7
There are many incorrect predictions in the first 20 rows, though some correct instances are also predicted. The likely cause is underfitting: the tree was given maximum depth 3, so perhaps going deeper would increase accuracy. This is the demo's own illustration of the depth/overfitting tradeoff: try more depth and see whether the accuracy increases.
Reading one wrong row as evidence. Take the row with actual quality 3 (a poor wine) predicted as 6 (a decent one). With maxDepth 3, a wine whose chemistry places it in an ambiguous region reaches a leaf that says "6" because that leaf's training wines were mostly 6s. Three questions are not enough to isolate the fine-grained differences between quality 3 and quality 6 wines — the tree is underfitting, drawing too coarse a picture. The experiment the professor suggests is one line of change: raise maxDepth (say to 5 or 8), refit, and watch whether the fraction of correct predictions rises. If it keeps rising with depth, the earlier tree was too shallow; if accuracy falls on the test set at large depth, the tree has started overfitting — memorizing training rows, which is why the professor caps depth in the first place ("we don't want to overfit the model").
Pitfalls.
- Reading one row's correctness as the model's accuracy. A single prediction proves nothing — the fraction of correct predictions over the whole test set is the number that matters.
- Attributing all errors to depth. Depth 3 underfits here, but the same symptom (many wrong predictions) can also come from a poor split ratio or random data; the demo's depth is the most likely culprit, not the only one.
- Dropping the seed when re-running. Without the seed, a "better" result may be pure luck of a different split — reproducibility is the whole point of the parameter.
Real-world & domain connection. Winemakers and distributors use exactly this model to grade bottles from chemistry alone, saving expert tasting time. The depth dial is the standing tradeoff of every tree-based model in industry: too shallow underfits (misses patterns), too deep overfits (memorizes noise), and practitioners pick the depth by testing on unseen data — the same loop the demo runs in miniature.
Recap + bridge. Wine demo: vectorize chemistry → seeded 0.7/0.3 split → DecisionTreeClassifier(maxDepth=3) → compare actual vs predicted quality (3→6, 8→7, 5→7). Many wrong → underfitting; try deeper. That completes the supervised side of the session — regression and classification both shown live. The next topic flips to unsupervised: clustering, where the data carries no labels at all.
8.11 Clustering
Clustering is introduced as "a little easier", and it is presented as an unsupervised learning method — no labeled data is needed. The session is extended by about 15 minutes to fit clustering in.
Hook. No answer key, no labels — just a scatter of points that visibly falls into groups. Clustering is the unsupervised technique for finding those groups, and its whole vocabulary — distance, dissimilarity, Jaccard, k-means — is built in this section.
8.11.1 What clustering is for
Given unlabeled data, clustering groups it under different heads. Examples: given customer data with certain demographics, categorize customers into different groups — this set belongs to one group, that set to another, that set to a third — to do better target marketing (launching a new product: whom should it be marketed to? find the right segment of customers). There may be no historical purchase data initially available — the customers are very new — but based on certain demographics they can still be grouped. Clustering is also used for market segmentation, spam filters, and fake news detection.
The objective in one sentence: finding groups of objects such that the objects in a group are similar to one another and different from the objects in the other groups.
Why clustering exists. Section 8.2 removed the price column and asked "what can you still do with this data?" — clustering is the answer. No labels are needed anywhere: the algorithm groups customers by demographics alone, so even brand-new customers with zero purchase history can be placed in a segment for a new-product campaign. Market segmentation, spam filtering, and fake-news detection all reduce to this same shape: no labels, just similarity.
8.11.2 The objective, in distance terms
Looking at a scatter plot of points, you intuitively see three different groups — three clusters exist. The objective is:
- intra-cluster distance minimized — the distance between two points belonging to the same cluster should be minimized;
- inter-cluster distance maximized — the distance between two points belonging to different clusters should be maximized.
Intuition — the two pulls of clustering. A good clustering pulls both ways at once: members of one group should be close to each other (small intra-cluster distance) and far from members of other groups (large inter-cluster distance). Think of friends at a party: a good cluster is a tight circle of people who know each other (small inner distances) standing at a visible gap from other circles (large outer distances). If the circles blur together, the clustering failed on the second pull; if a circle is huge and spread out, it failed on the first.
8.11.3 Dissimilarity metrics: Minkowski, Manhattan, Euclidean
When attributes are numeric, dissimilarity can be measured with the Minkowski distance, a general form:
\[ d(i,j) = \left( \sum_{k=1}^{p} \left| x_{ik} - x_{jk} \right|^{q} \right)^{1/q} \]
where the two objects \(i\) and \(j\) each have \(p\) features (the number of features is also called \(n\)), and \(q\) is a parameter.
- \(q = 1\): the Manhattan distance — the sum of absolute differences:
\[ d(i,j) = \sum_{k=1}^{p} \left| x_{ik} - x_{jk} \right| \]
Manhattan distance is called the L1 norm.
- \(q = 2\): the Euclidean distance — square the differences, sum, and take the square root:
\[ d(i,j) = \sqrt{ \sum_{k=1}^{p} \left( x_{ik} - x_{jk} \right)^{2} } \]
Euclidean distance is called the L2 norm.
Based on the dissimilarity values obtained, objects are categorized as similar or different in nature — the threshold for that decision has to be decided.
Reading the metric — symbol by symbol, and the two famous cases. \(d(i,j)\) is the dissimilarity between object \(i\) and object \(j\); \(x_{ik}\) is the \(k\)-th feature value of object \(i\), so \(x_{ik} - x_{jk}\) is the gap between the two objects on feature \(k\); the sum runs over all \(p\) features (\(k = 1, \dots, p\)); the parameter \(q\) is the "power" of the metric. Substituting \(q = 1\) gives the Manhattan distance — the reference text calls it the staircase distance: you can only walk along the grid, so the distance is the sum of the legs of the right triangle, not the hypotenuse. Substituting \(q = 2\) gives the Euclidean distance — the straight-line (as-the-crow-flies) distance, the hypotenuse itself. The labels L1 and L2 are the norms' names: L1 = sum of absolute differences, L2 = square root of sum of squared differences. In k-means problems the exam will say which to use — "if it says L1, go with L1; if it says L2, go with L2."
Two objects, both metrics, real numbers. Object \(i = (1, 2)\) and object \(j = (4, 6)\) in \(p = 2\) dimensions.
Manhattan (L1, \(q=1\)): \[ d(i,j) = |1 - 4| + |2 - 6| = 3 + 4 = 7 \]
Euclidean (L2, \(q=2\)): \[ d(i,j) = \sqrt{(1 - 4)^2 + (2 - 6)^2} = \sqrt{9 + 16} = \sqrt{25} = 5 \]
Euclidean distance = 5, Manhattan distance = 7. Sense-check: the straight line between the points is always the shortest route, so Euclidean (5) must be smaller than the staircase walk (7); the gap widens as the points spread diagonally. Minkowski with \(q=1\) reproduces the first answer, \(q=2\) the second — one formula, two rulers.
8.11.4 Binary variables: the \(a, b, c, d\) contingency table
Binary variables take two values — zero or one (or yes/no). For objects \(i\) and \(j\), count the four combinations over all attributes:
- \(a\) = number of attributes where both are 1 (value 1,1)
- \(b\) = number where \(i\) is 1 and \(j\) is 0
- \(c\) = number where \(i\) is 0 and \(j\) is 1
- \(d\) = number where both are 0 (value 0,0)
The dissimilarity — where the values differ, i.e. \(b\) and \(c\):
\[ d(i,j) = \frac{b + c}{a + b + c + d} \]
The contingency table, built in four buckets. For binary features, compare the two objects attribute by attribute and tally four counts: both 1 (\(a\)), only \(i\) has 1 (\(b\)), only \(j\) has 1 (\(c\)), both 0 (\(d\)). The total \(a + b + c + d\) equals \(p\), the number of features. Two objects are dissimilar exactly where they disagree — the \(b + c\) mismatches — so the dissimilarity is mismatches divided by total attributes. Perfect agreement gives 0; disagreement everywhere gives 1.
8.11.5 Asymmetric binary variables and the Jaccard coefficient
Some binary situations are asymmetric: one value is important but the other is not. The medical test example: if a test is positive, it matters a lot; if it is negative, that value can kind of be ignored — the person may still have a problem even when the test says negative, but a positive makes a difference. So wherever the value is zero, it is ignored — the \(d\) term (both zero) is skipped, and the total left is \(a + b + c\):
\[ d_{\text{asym}}(i,j) = \frac{b + c}{a + b + c} \]
For similarity, take one minus the dissimilarity:
\[ s_{\text{asym}}(i,j) = 1 - \frac{b + c}{a + b + c} = \frac{a}{a + b + c} \]
This similarity measure for asymmetric binary variables is termed the Jaccard coefficient.
The professor's medical-test analogy (extended). A test result of positive carries the real signal — act on it; a negative result is weak evidence ("the person may still have a problem even when the test says negative"). That asymmetry is why the both-zero bucket \(d\) is dropped: two people both testing negative is not strong evidence of similarity, so it must not count toward agreement. Where the analogy breaks: in symmetric binary settings (e.g. two documents both lacking the same irrelevant keyword) both-zero can be meaningful similarity — which is exactly why the plain \(a,b,c,d\) formula of 8.11.4 keeps the \(d\) term. The asymmetric rule is the same idea the texts formalize as the Jaccard coefficient \(= \frac{a}{a+b+c}\) — the share of attributes where either object has the important value 1 and both agree on it.
Jaccard on real counts. Two patients described by four medical tests (p = 4). Patient \(i\): (positive, positive, negative, negative); patient \(j\): (positive, negative, positive, negative).
Buckets: \(a\) (both positive) = 1 (first test); \(b\) (\(i\) positive, \(j\) not) = 1 (second); \(c\) (\(j\) positive, \(i\) not) = 1 (third); \(d\) (both negative) = 1 (fourth).
Symmetric dissimilarity: \(\frac{b+c}{a+b+c+d} = \frac{1+1}{4} = 0.5\).
Asymmetric dissimilarity: \(\frac{b+c}{a+b+c} = \frac{2}{3} \approx 0.667\).
Jaccard similarity: \(\frac{a}{a+b+c} = \frac{1}{3} \approx 0.333\), which equals \(1 - 0.667\). Sense-check: only one of the three "meaningful" (positive-involved) tests matches, so similarity is low; dropping the both-negative test makes the pair look more dissimilar than the symmetric formula did, because the shared negatives no longer count as agreement.
8.11.6 Nominal variables
A nominal variable can take more than two states — red, yellow, blue, green (the color of an object), anything. The approach is simple matching: count how many attributes are matching. If \(m\) is the number of matches out of \(p\) attributes, then \(p - m\) is the number of unmatched attributes, and:
\[ d(i,j) = \frac{p - m}{p} \]
is the dissimilarity between \(i\) and \(j\).
Simple matching on multi-state categories. When a feature is nominal (color: red/green/blue; city: Delhi/Mumbai/Bengaluru), there is no meaningful "distance" between states — red is not 1 unit from green. The workable measure is simple matching: count how many of the \(p\) attributes take the same state in both objects (\(m\) matches), then dissimilarity = non-matching share \((p - m)/p\). Two objects identical on every attribute score 0; two objects disagreeing everywhere score 1. It is the nominal cousin of the binary formula — with "same state" standing in for the binary "both 1 or both 0".
8.11.7 The notion of a cluster is ambiguous
Even after measuring dissimilarity, the notion of a cluster can be ambiguous: given the same dataset, somebody may say there are two clusters, somebody else four, and at a fine-grain level six. Clusters can be built hierarchically; you can start with a small value, get poor results, and decide to build up more clusters. All of that can be tried. One algorithm — k-means clustering — is covered, a distance-based approach.
Scope: cluster count is a choice, not a fact. A dataset does not declare "I contain exactly k clusters" — the reference treatment of the same point: the notion of a cluster is subjective, and heuristics decide the count; two clusters, four clusters, and six clusters can all be defensible readings of the same scatter, at coarse or fine grain. Hierarchical construction (start coarse, split finer) is one way to explore the options. In practice this is why cluster-quality metrics exist (silhouette and friends) — explicitly out of scope here, per the exam guidance — and why the session settles for one concrete algorithm: k-means, with k chosen by the user.
Real-world & domain connection. Clustering's name comes from the field's flagship use case — cluster analysis in market research: an insurer profiling 2,000 households found five segments (non-traditionals, direct buyers, budget-conscious, agent-loyal, hassle-free) and aimed targeted campaigns at each — the exact "target marketing" use the professor names. The same toolbox drives fake-news detection (grouping similar claims), spam filtering (grouping similar messages), and social network community detection.
Recap + bridge. Clustering = group similar objects, unlabeled; objective = minimize intra-cluster, maximize inter-cluster distance. Numeric dissimilarity: Minkowski with \(q=1\) (Manhattan/L1) or \(q=2\) (Euclidean/L2); binary: \((b+c)/(a+b+c+d)\); asymmetric binary: Jaccard \(a/(a+b+c)\); nominal: simple matching \((p-m)/p\). The number of clusters is a choice. One distance-based algorithm remains — k-means, which puts all of these rulers to work.
8.12 K-Means Clustering
Hook. You know you want \(k\) groups — but where do the groups actually sit? K-means answers with a simple loop: guess centers, assign every point to the nearest center, move the centers to the middle of their points, repeat. The loop is so simple it converges in a handful of iterations on clean data.
8.12.1 The algorithm
K-means is a partition-based clustering approach: a single point belongs to exactly one cluster, each cluster is associated with a centroid, and each point is assigned to the cluster with the closest centroid. Given a set of points:
- Choose \(k\) initial centroids — that is why it is called \(k\)-means.
- Compute the distance of every point from each centroid.
- Assign each point to the cluster whose centroid it is closest to.
- Recompute the centroids: take the average of all the points of each feature for the points in the cluster.
- Iterate — recompute distances, reassign points, recompute centroids — until the centroids converge: when points stop shuffling between clusters, the centroids are fixed, and the algorithm stops.
Inputs, outputs, and why the loop converges. Input: a set of points (each a vector of features) and \(k\), the desired number of clusters — the user chooses \(k\), the algorithm does the rest. Output: \(k\) clusters, each represented by its centroid. The centroid is a central representative — concretely, the mean of the points in the cluster, computed feature by feature (for a 3-D cluster, the centroid's first coordinate is the average of all members' first coordinates, and so on). Why stop? Each full pass (assign → recompute) can only reduce the total squared error (8.12.3), so the loop cannot oscillate forever; when an assignment pass moves no point, the centroids are stable and the loop halts. The reference treatment records the same five steps — initialize \(k\) centroids, assign each point to the nearest, average the members to move the centroid, repeat until no change — and notes that most convergence happens in the first few iterations.
8.12.2 Worked illustration: centroids moving over iterations
The illustration uses three centroids (red, blue, green plus-marks) over a scatter of data points:
- Initial: three centroids are chosen; each point is assigned by proximity — the red cluster has very few points, blue and green have more.
- After recomputing distances, some points that were in green and blue should have been in the red cluster, so points move from blue and green to red.
- Centroids are recomputed as the average of the points in each cluster; the centroids shift a little.
- The next iteration moves the centroids a little further down; the green and blue ones move further down still.
- By the sixth iteration the final clusters are settled.
This is how clusters are built with k-means: a simple distance-based approach using the L1 or L2 norm — if the exam (or some problem) says use L1, go with L1; if it says L2, go with L2.
Visual intuition. Picture the scatter: three roughly circular clouds of points, plus-marks sitting on top of them as the initial centroids (the professor's diagram shows red, blue, green). The first assignment draws boundaries mid-way between the plus-marks, so boundary points land in the wrong cloud; the first recompute drags each plus-mark toward the true middle of its assigned points; each subsequent pass re-draws the boundaries, migrating a few more points, until the plus-marks stop moving — by the sixth iteration the three clusters are settled. Each frame is the same two moves — assign by nearest centroid, then average the members — repeated until nothing changes.
Trace on a tiny 2-D dataset. Points: A(1,1), B(2,1), C(8,8), D(9,8), E(8,9); \(k = 2\); initial centroids picked as C1 = (1,1) and C2 = (8,8) (here, two of the points themselves).
Pass 1 — assign: distances (Euclidean): A is 0 from C1, C is 0 from C2. B(2,1): to C1 = 1, to C2 = \(\sqrt{36+49} \approx 9.2\) → C1. D(9,8): to C2 = 1 → C2. E(8,9): to C2 = 1 → C2. Clusters: C1 = {A, B}, C2 = {C, D, E}.
Pass 1 — recompute: new C1 = mean( (1,1), (2,1) ) = (1.5, 1.0). New C2 = mean( (8,8), (9,8), (8,9) ) = (25/3, 25/3) ≈ (8.33, 8.33).
Pass 2 — assign: A, B nearest to (1.5,1.0); C, D, E nearest to (8.33,8.33). No point changes cluster.
Pass 2 — recompute: centroids unchanged: (1.5, 1.0) and (8.33, 8.33). No movement → converged after 2 passes.
Final clusters: {A(1,1), B(2,1)} and {C(8,8), D(9,8), E(8,9)}. Sense-check: the two natural groups are exactly what the eye sees in the scatter, and the centroids sit at the center of each group — the algorithm found the obvious answer in two iterations, mirroring the professor's demo where convergence came quickly.
8.12.3 What k-means minimizes
Another way to view the clusters: k-means minimizes the sum of squared error — compute the distance of each point from its centroid, square it, and sum:
\[ \text{SSE} = \sum_{i=1}^{k} \sum_{x \in C_i} \| x - \mu_i \|^2 \]
where \(C_i\) is the \(i\)-th cluster, \(x\) is a point in it, and \(\mu_i\) is its centroid.
Reading the SSE, symbol by symbol. \(k\) is the number of clusters; \(C_i\) (C-sub-i) is the set of points in cluster \(i\); \(x\) ranges over those points; \(\mu_i\) (mu-sub-i) is the centroid of cluster \(i\); \(\| x - \mu_i \|\) is the distance (norm) from point \(x\) to its centroid — using the L1 or L2 norm, whichever the problem specifies. The double sum squares every point-to-centroid distance and adds them all up. K-means minimizes this one number: the outer sum over clusters, the inner over members, total squared distance from every point to its own centroid. The centroids of 8.12.1 are exactly the \(\mu_i\) that minimize SSE for the current assignment — the "mean" in the name. The reference treatment states the same criterion: the centroids are the ones for which the sum of squared distances is least for all points of each cluster.
8.12.4 Limitations of k-means
Three limitations are illustrated with diagrams:
- Clusters of different sizes: the original data has three clusters of different sizes, but depending on the chosen initial centroids, k-means may end up with wrong groupings — not good quality clusters.
- Clusters of different densities: the data shows three clusters where some are more dense than others; with k-means, certain centroid choices can merge two of them into one — again not good quality. For density differences there is a density-based clustering algorithm: DBSCAN.
- Non-globular shapes: the original clusters have elongated, non-globular shapes; k-means may cut them into the wrong pieces. K-means cannot be used in this case.
Other algorithms exist to find these kinds of clusters, covered in more depth in the machine learning course, with some things also covered in the data mining course.
Pitfalls: when k-means quietly fails.
- Unequal cluster sizes. A large cluster can swallow a small neighbor when the initial centroids fall unluckily — the diagram shows the small group chopped and merged. The final grouping depends on the random start, so different runs can give different clusters (k-means is non-deterministic).
- Unequal densities. A dense cluster and a sparse cluster are both "groups", but k-means splits by distance, not by density — a dense blob can get cut in half while a sparse region gets merged. The remedy has a name: DBSCAN, a density-based algorithm, mentioned here and deferred to the machine learning course.
- Non-globular shapes. K-means draws straight boundaries between centroids, so a crescent-shaped or elongated cluster gets sliced into pieces that look wrong. The reference treatment states the restriction directly: the method is well suited only when the clusters are globular (round blobs). If the shapes are rings, crescents, or chains, k-means cannot be used.
- Blindly trusting \(k\). The number of clusters is the user's guess — the ambiguity of section 8.11.7 is baked into the algorithm's first parameter.
Real-world & domain connection. K-means is the workhorse unsupervised algorithm in industry — customer segmentation for targeted marketing (the professor's exact motivation), image compression (each pixel assigned to one of \(k\) color centroids), fraud and anomaly detection, and healthcare sub-population characterization (diabetic vs non-diabetic group structure from patient attributes). Its strength is speed — the reference analysis gives time cost \(O(n k I d)\) with \(n\) points, \(k\) clusters, \(I\) iterations, \(d\) attributes — which is why it survives at Big Data scale even though it inherits all three shape limitations.
Recap + bridge. K-means: pick \(k\) centroids, assign each point to the nearest, recompute centroids as feature averages, repeat until nothing moves; it minimizes the SSE \(\sum_i \sum_{x \in C_i} \|x - \mu_i\|^2\). Works for globular clusters; fails on unequal sizes, unequal densities (use DBSCAN), and non-globular shapes. The exam rule from the professor: use whatever distance the problem names — L1 or L2. The next section runs this whole loop in PySpark on a six-point file.
8.13 Hands-On: K-Means in PySpark
8.13.1 The program
The clustering program, kmeans_clustering_1.py, is very simple because the input file is very simple:
- Import the Spark context; import k-means (from the MLlib library, e.g.
KMeans). - Define a function that splits the input file — each line is split on spaces (a
parseVector-style helper used withmap; recall themaptransformation on RDDs). - Set
k = 2— build two clusters. - The whole dataset is the training data (there is no train/test split in clustering).
- At the end, print the cluster centers and the compute cost.
- Stop the Spark context.
Similar examples ship with the Spark ML libraries; this one was picked up to show the context.
Inputs, outputs, and the one difference from the earlier demos. Input: the six-point file (8.13.2) and \(k = 2\). Output: the two final cluster centers and the total cost. The structural difference from regression and classification is deliberate: no train/test split — clustering is unsupervised, there is no labeled answer to test against, so the whole dataset is the training data. The parseVector helper splits each line on spaces into a vector — exactly the map transformation seen on RDDs in the earlier Spark sessions.
8.13.2 The data file
The input file is kmeans_data.txt (the file listing first shows kmeans.txt absent — the actual file is kmeans_data.txt). It contains only five or six samples, three-dimensional points near the origin — \(0.0, 0.0, 0.0\); \(0.0, 0.1, 0.1\); \(0.1, 0.1, 0.1\); and similar — with the data well separated into two natural groups (points near the origin and a point near \(9.1, 9.1, 9.1\)). The goal is to cluster these samples into two clusters: the program picks initial centroids and comes up with final centroids.
The file, fully reconstructed. The standard MLlib sample file shipped with Spark is six 3-D points, three huddled near the origin and three near \((9, 9, 9)\):
0.0 0.0 0.0
0.1 0.1 0.1
0.2 0.2 0.2
9.0 9.0 9.0
9.1 9.1 9.1
9.2 9.2 9.2
That is the "five or six samples near \(0.0, 0.0, 0.0\) and a point near \(9.1, 9.1, 9.1\)" the recording captures — six points in total, two clean groups on the diagonal. The two clusters are so well separated that even a poor initial centroid choice gets corrected within a couple of passes.
8.13.3 Output
Running spark-submit kmeans_clustering_1.py:
- Total cost: 0.12 — the computed cost of the final clustering.
- Two centroids: \(0.1, 0.1, 0.1\) — the first centroid — and \(9.1, 9.1, 9.1\) — the second centroid.
- K-means converged in two iterations — within just two iterations the algorithm figured it out.
Why the cost is exactly 0.12 — the trace. With the six points above and \(k = 2\), the final assignment splits the file at its natural gap:
Cluster 1 = \(\{ (0.0,0.0,0.0), (0.1,0.1,0.1), (0.2,0.2,0.2) \}\), centroid \(\mu_1 = (0.1, 0.1, 0.1)\). Cluster 2 = \(\{ (9.0,9.0,9.0), (9.1,9.1,9.1), (9.2,9.2,9.2) \}\), centroid \(\mu_2 = (9.1, 9.1, 9.1)\).
Cost (SSE, per section 8.12.3) with the L2 norm:
\[ \text{SSE}_1 = (0.1^2\cdot 3) + 0 + (0.1^2 \cdot 3) = 0.06, \qquad \text{SSE}_2 = (0.1^2\cdot 3) + 0 + (0.1^2 \cdot 3) = 0.06 \]
\[ \text{Total cost} = 0.06 + 0.06 = 0.12 \]
Total cost = 0.12. Sense-check: every point sits exactly 0.1 units (along each coordinate) from its centroid except the centroids themselves, so the cost is six points × 0.03 = 0.18 minus the zero contributions of the two centroid points — 0.12. Two iterations suffice because the first assignment already splits the file at the gap, and the second pass only confirms it — mirroring the two-pass convergence traced in section 8.12.2.
Pitfalls.
- Mixing up
kmeans.txtandkmeans_data.txt. The directory listing shows nokmeans.txt— the demo readskmeans_data.txt; the wrong filename fails thespark-submit. - Expecting a train/test split. Clustering has none by design — no labels, nothing to test against; the whole dataset trains the model.
- Misreading "cost". The printed cost is the SSE of the final clustering — the sum of squared distances from the printed centers, not an error rate. Zero-ish cost here simply reflects that the points sit nearly on top of their centroids.
- Assuming one answer. Initial centroids are chosen randomly, so another run can converge to a different (but still sensible) pairing — reproducibility would need the
seedtrick from section 8.10.
No in-depth discussion of cluster quality metrics (like the silhouette coefficient) is attempted — explaining clustering properly needs three to four lectures — so the session covers simple k-means: what it does, and how to write a small sample and run it on PySpark. The same was done for regression and for classification; three hands-on demos are enough at this moment. (A recommendation-system code snippet may be shared separately, easy to run on your own.)
Real-world & domain connection. This six-line toy is the archetype of every production k-means job: the same KMeans class in MLlib segments millions of customers by spending behavior, retrieves similar images by feature similarity, and flags anomalous credit-card transactions — the exact use cases the reference text lists for k-means. The cost number printed here is the same SSE that, at scale, guides choosing \(k\) (smaller is tighter, but over-splits).
Recap + bridge. The k-means demo: read six 3-D points, k = 2, no train/test split, print centers and cost — centroids \((0.1, 0.1, 0.1)\) and \((9.1, 9.1, 9.1)\), total cost 0.12, converged in two iterations. All three hands-on demos are done — regression, classification, clustering. The session closes with the fourth technique, recommendation systems, in a brief conceptual pass.
8.14 Recommendation Systems
A brief, roughly five-minute close on recommendation systems — what the two approaches to recommending items are.
Hook. Every shopping site you visit is telling you what to buy next — and it never guessed; it computed. Recommendation systems are the fourth technique of the session, and the entire subject reduces to one choice: what do you base the guess on — the item's description, or what other people like you did?
8.14.1 The recommendation problem
Almost every website that sells anything has a recommendation system: any e-commerce website recommends products to you; movie websites recommend movies; reading platforms recommend books. The core idea: predict the preference of a user based on past behavior. There is a set of items \(Y\) and a set of users \(X\), and the system tries to learn a function from past interactions that predicts the likeliness of \(x\) (a user) to \(y\) (an item). On an OTT platform like Netflix, the items are movies or shows; users are end users, each with attributes like age and likes and dislikes.
The problem in one sentence. Input: a set of users \(X\), a set of items \(Y\), and a history of past interactions (who watched/bought/rated what). Output: for each user \(x\), a score of how likely they are to like each item \(y\) — typically surfaced as the top-\(N\) items with the highest scores. Every recommender — Netflix movies, Amazon products, bookstore suggestions — is a specific recipe for computing that score from the interaction history.
8.14.2 Content-based filtering
Content-based filtering uses only the attributes of the items and does not study the attributes of the users coming in. For items (movies, songs) to be usable this way, items must have attributes: for a movie — its genre, the actor, the director. If a person has been liking thriller movies, recommend more thrillers; if they have previously watched a movie of a certain actor, recommend another movie by the same actor. In the course of the session the professor describes this with an audience-behavior example as well: if someone has heard songs A, B, C and a large number of the audience who listened to A, B, C have also heard X and "we next" (the next track), that next song appears in the playlists of a large number of that audience — and that is how it gets recommended. The distinguishing claim is that content-based studies the attributes of the items they have but not the attributes of the users.
Content-based, pinned down. The signal is entirely in the items: each movie carries attributes (genre, actor, director), each song carries attributes (artist, style), and the system matches those attributes against what the user liked before. Liked thrillers → recommend more thrillers; liked an actor → recommend that actor's other films. The users' own attributes are irrelevant — the professor's phrase is exact: it studies the attributes of the items, not the attributes of the users. A note on the audience-behavior example: as told, it leans on co-listening patterns — "people who heard A, B, C also heard X" — which is behavior-based reasoning, the hallmark of collaborative filtering rather than pure content matching. The professor's framing mixes the two approaches slightly; the clean content-based version would say "X is recommended because X's attributes (artist, genre) match the attributes of A, B, C that you liked". Keep both pictures: the examinable distinction is content-based = item attributes only.
8.14.3 Collaborative filtering
Collaborative filtering utilizes the user interaction behavior in addition to the item attributes — the specific user interactions that have happened with the system matter. With songs, the system understands who are the similar users and what else those users listen to, so that the next song recommendation can be generated; item attributes are less important here. New users are matched to categories: if a new user fits into a particular category (as the system recorded the attributes of existing users), whatever the users in that category have watched gets recommended — not on a one-person basis, of course; there should be sufficient data, a certain number of users in the category who have watched that content.
The everyday analogy: you want to watch a movie and you ask your friend circle — specifically the people of a similar nature of taste, not each and every friend. Out of a friend list of 25, you know that five of you share very common taste in movies; you ask those five, and their recommendation tells you whether to go. Most collaborative filtering systems use a similarity index with respect to the active user — a set of similar user preferences is aggregated. What matters is the relationship of the users to the items, rather than only among the items (which is content-based). The similarity in items is determined by the similarity of the preferences of those items by the users who have rated both items. This is an unsupervised technique; techniques like nearest neighbor are used.
The professor's friend-circle analogy (the canonical picture). You are deciding whether to watch a movie. Of your 25 friends, five reliably share your taste. You ask those five — not all 25 — and their verdict decides. Mapping: you = the active user; the five = the nearest neighbors in taste space; their combined opinion = the aggregated similarity index; the movie verdict = the recommendation. Where the analogy breaks: the system does not ask people — it infers "same taste" from overlapping ratings, and it needs enough users who rated both items to trust the similarity. The reference treatment frames it the same way: collaborative filtering (CF) relies on the behavior of users, not on item features, and generates recommendations by computing similarities between users or items in the user-item matrix. A genuine CF insight: CF can recommend an item whose attributes are nothing like what you watched — because people like you liked it; content-based can never do that.
Why "collaborative"? The name is the message: a community of users collaborates — each person's interactions contribute to everyone else's recommendations. The system models the user-item relationship (who interacted with what), finds similar users (nearest neighbors) by their overlapping preferences, and aggregates those neighbors' behavior to score items the active user has not touched. The reference text notes CF is built around user behavior while content-based is built around item attributes — and that item features cannot capture changing user interests, which is exactly why behavior wins in practice. This is an unsupervised technique: no labels are involved, just the interaction matrix.
8.14.4 User-based vs item-based approaches
Two diagrams illustrate the two collaborative approaches:
- User-based approach: if a particular user has bought two DVDs/CDs of a digital content and another user has bought three, and the two users are similar, then the third one can be recommended to the first user.
- Item-based approach: two items are similar because the same user has given similar ratings to both; so if another user buys one of these items, since the two items are similar (two users gave similar ratings), that item is recommended back to this person.
Sources are mentioned for reading more about these approaches.
| Dimension | User-based collaborative filtering | Item-based collaborative filtering |
|---|---|---|
| What is compared | Users vs users (similarity between people) | Items vs items (similarity between products) |
| Similarity from | Overlap in ratings across items | Ratings given to both items by the same users |
| Flow | Find similar users → recommend what they bought | Find similar items → recommend items bought together |
| Example | User bought 2 DVDs, similar user bought 3 → recommend the 3rd | Two items rated alike by the same users → co-recommend |
| Famous early adopter | Research systems | Amazon (the reference text credits Amazon with developing it) |
When to pick which: with many users and few items per user, item-based is more stable (item similarities change slowly); with a dense user-item matrix, user-based works well. Both are memory-based collaborative filtering — the reference text's two branches of CF are exactly user-based and item-based.
The two approaches on one small rating table. Three movies — M1 (action), M2 (thriller), M3 (comedy) — and ratings (1–5) from two users plus the active user:
| User | M1 (action) | M2 (thriller) | M3 (comedy) |
|---|---|---|---|
| U1 | 5 | 4 | – |
| U2 | 4 | 5 | 3 |
| You (active) | 4 | 4 | ? |
Content-based: you rated the action and thriller highly, so the system matches the item attributes — genre, actor, director — and offers M2-like thrillers; M3 (comedy) is not in the running because no comedy matches what you have liked. M2's attributes carry the recommendation.
User-based collaborative: compare your ratings with other users'. U1's ratings (5, 4) lie close to yours (4, 4) — you and U1 are similar users (a similarity index from the overlapping M1/M2 columns). U1 has not rated M3 either, so look one step further: U2 rated M3 a 3, and U2 overlaps with both of you. With more data, the system aggregates the nearest-neighbour ratings for M3 and recommends it if the aggregate clears the bar.
Item-based collaborative: M1 and M2 are similar because U1 and U2 rated both almost alike (U1: 5/4, U2: 4/5) — item similarity comes from users who rated both. So when you engage with M1, the system recommends the similar item M2 to you.
Takeaway: content-based answers from the item's description (M2 is a thriller); both collaborative branches answer from other people's behavior — user-based via similar users, item-based via similar items. Sense-check: the same table supports all three stories because each approach reads a different slice of it — attributes, user rows, or item columns.
8.14.5 Matrix factorization, and how much depth is intended
The matrix factorization approach is not covered ("max factorization" in the flow of the session is the matrix factorization method). It is something you can read about for detail. The simple things about recommendation systems have been covered; covering all these four techniques in detail would need 12–13 sessions, but that is not the objective here — the basics are the objective.
Scope: what is examinable and what is not. The two approaches — content-based and collaborative filtering — and the two collaborative branches — user-based and item-based — are the examinable core. Matrix factorization, the method that powers many real recommenders (factor the user-item matrix into user and item factors), is explicitly not covered: read about it if curious, but it is out of scope, as the exam guidance confirms.
8.14.6 Student question and closing notes
Q: Could you please rename the recorded sessions by topic, like how the first two classes were renamed? It would be really helpful.
A: They were not renamed by the professor — probably a student did it. To relate each recording to its content, go to the slide deck, which lists dates for every slide: match the recording's date with the slide-deck date and you will be able to see what content is covered.
For finding a session's topic, the answer is to match the recording's date with the dates on the slide deck. Exam note: everything in this session — regression, classification, clustering, and collaborative filtering — is part of the end-semester exam; consolidated guidance on what to study is gathered at the end. The next session covers a little bit of spark streaming.
Real-world & domain connection. Recommenders are the most visible machine learning product in the world: Netflix's home screen, Amazon's "customers also bought", Spotify's weekly playlist, YouTube's next video. The friend-circle logic scales to billions of interactions — Netflix's items are movies and shows, users carry attributes like age and preferences, and the top-N list is the interface everyone sees. Item-based similarity is why Amazon shows you the chocolate and gift box next to the greeting card in your cart — the same co-purchase inference the professor's audience example describes.
Recap + bridge. Recommendation = predict user preference from past behavior. Content-based: item attributes only (genre, actor, director). Collaborative filtering: user interaction behavior — user-based (similar users) or item-based (similar items), unsupervised, nearest-neighbor flavored. Matrix factorization: out of scope. This closes the fourth technique — and the session's next section gathers the consolidated exam guidance.
Exam Guidance Summary
- Exam note: The end-semester exam covers regression, classification, clustering, and collaborative filtering — everything discussed in this session. Pay careful attention to all of these topics.
- Exam note: Questions may be asked from code snippets and conceptual things out of these topics; the professor will not go too deep, and whatever is in the slides is enough — but the topics should be explored a little more in detail.
- Exam note: For distance choices in k-means-style problems, if the exam says use the L1 norm, go with L1; if it says L2, go with L2.
- Exam note: Two methods suffice for the attribute-selection question in classification: information gain (choose the maximum) and gini index (choose the minimum). Different algorithms use different metrics, but these two are the ones to learn for this course.
- Study advice: The three code files used in the session (regression, decision tree classifier, k-means) will be uploaded; a working recommendation-system snippet may also be uploaded if it works.
- Study advice: Recordings are organized by date in the slide deck; to find which recording covers which topic, match the recording's date with the dates mentioned on the slide deck.
- Course scope: Hyperparameter tuning, gradient descent, cluster-quality metrics (silhouette coefficient), matrix factorization, and other clustering algorithms (DBSCAN and the like) are explicitly out of scope for this course — they belong to machine learning or data mining courses.
How to prepare for this session's exam questions. Four working rules cover the numerical questions: (1) compute information gain at the root and per attribute — maximum wins (buys-computer: age, 0.246); (2) compute gini per candidate split — minimum wins (income low–medium, 0.443); (3) use exactly the distance metric the problem names — L1 (Manhattan) or L2 (Euclidean); (4) know the k-means loop and the SSE it minimizes. The conceptual questions come straight from the vocabulary: Samuel vs Mitchell definitions, labeled vs unlabeled, regression vs classification, content-based vs collaborative filtering.
Key Industry Applications
- Real-world: Spam filtering is the canonical first machine learning application: classify emails as spam or not spam using labeled historical emails.
- Real-world: Machine learning has touched almost every area — image recognition, speech recognition, medical diagnosis, traffic prediction, stock price trading, self-driving cars, product recommendations, and fraud detection.
- Real-world: Amazon and Flipkart predict product sales, and overall sales during events like the Big Billion Days, to prepare inventory and the workforce needed to fulfill those orders.
- Real-world: OTT platforms such as Netflix run recommendation systems whose items are movies and shows, recommending based on a user's attributes and past behavior.
- Real-world: E-commerce websites and book/movie platforms all carry recommendation systems; most use either content-based or collaborative filtering.
- Real-world: Market segmentation for target marketing — grouping new customers by demographics to decide whom to market a new product to — is an unsupervised learning use case.
- Real-world: Social network analysis is an unsupervised learning task.
- Real-world: The medical-test asymmetry example — positive results matter, negatives can be ignored — is why asymmetric binary dissimilarity drops the both-zero term.
- Real-world: The Boston housing dataset (boston.csv, 506 records) and the wine-quality dataset (wine.csv) are standard public benchmark datasets used to teach regression and classification.
BDS Lecture 8 notes
Sections Breakdown
What machine learning is: Samuel 1959 and Mitchell definitions, and why 1959 was too early.
Supervised vs unsupervised learning - the division is the presence of the desired output in the data.
Regression vs classification - continuous vs discrete output, both supervised.
Simple linear regression: model form, error metrics (RMSE, MAE), and worked predictions.
Multilinear and polynomial regression extensions.
Hands-on: linear regression on the Boston housing data with PySpark MLlib.
Classification as a two-step process with worked tenure prediction.
Decision trees and the buys-computer example.
Choosing the split attribute: information gain and the Gini index, fully worked.
Hands-on: decision tree classifier on wine-quality data with PySpark.
Clustering: dissimilarity metrics (Minkowski, Manhattan, Euclidean, Jaccard) and binary variables.
K-means clustering: algorithm, SSE objective, and limitations.
Hands-on: k-means on a tiny synthetic file with PySpark.
Recommendation systems: content-based and collaborative filtering.
Professor exam strategy: what is examinable, L1/L2 instruction rule, and out-of-scope topics.
Real-world machine learning applications and standard benchmark datasets.
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
What Machine Learning Is
Must-know: Samuel 1959: learning without being explicitly programmed. Mitchell (late 90s): improve performance P at task T with experience E; P on T as measured by P improves with E.
\[\text{program learns if } P \text{ at } T \text{ improves with more } E\]
⚠️ Top pitfall: Mixing up the roles of T, P, E — E is the labeled data fed in, T is the job, P is the score.
Self-check: In spam filtering, what is the experience E and the performance P?
Connects to: 8.2 Supervised vs Unsupervised Learning
Supervised vs Unsupervised Learning
Must-know: Supervised: labeled training data with desired output. Unsupervised: only input attributes, no desired output — used for grouping/segmentation.
⚠️ Top pitfall: Thinking the difference is the algorithm — it is the data (presence/absence of the output column).
Self-check: Remove the price column from the house dataset — which learning family does the problem move into?
Connects to: 8.1 What Machine Learning Is, 8.3 Regression vs Classification, 8.4 Simple Linear Regression, 8.11 Clustering
Regression vs Classification
Must-know: Regression → continuous output; classification → discrete output. Both supervised. Examples: house price (regression), spam/digit/employability/disease (classification).
⚠️ Top pitfall: Judging by dataset rather than by the label type — the label column decides the family.
Self-check: Is disease prediction (yes/no) regression or classification? Why?
Connects to: 8.2 Supervised vs Unsupervised Learning, 8.4 Simple Linear Regression
Simple Linear Regression
Must-know: y = theta_0 + theta_1 x; theta_0 = intercept c, theta_1 = slope m. RMSE = sqrt((1/n) sum (y_j - y_hat_j)^2), MAE = (1/n) sum |y_j - y_hat_j|. Choose the line that minimizes the metric. RMSE >= MAE always.
\[\text{RMSE} = \sqrt{\frac{1}{n}\sum_{j=1}^{n} \left( y_j - \hat{y}_j \right)^2},\qquad \text{MAE} = \frac{1}{n}\sum_{j=1}^{n} \left| y_j - \hat{y}_j \right|\]
⚠️ Top pitfall: Negative errors do not cancel positives; squaring exists precisely to remove sign and to punish large gaps.
Self-check: With y = 2 + 5x and x = 750, what is the predicted price and what is the error if the actual was 3600?
Connects to: 8.5 Multilinear and Polynomial Regression, 8.6 Hands-On: Linear Regression in PySpark
Multilinear and Polynomial Regression
Must-know: Multilinear: y = theta_0 + theta_1 x_1 + ... + theta_d x_d (weight per feature plus intercept). Polynomial: y = theta_0 + theta_1 x + theta_2 x^2 + theta_3 x^3 + ...
\[y = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \cdots + \theta_d x_d\]
⚠️ Top pitfall: Thinking the professor's multilinear form differs from the textbook form — same formula, different weight letter (b_i vs theta_i).
Self-check: How many coefficients does multilinear regression have for d input features?
Connects to: 8.4 Simple Linear Regression, 8.6 Hands-On: Linear Regression in PySpark
Hands-On: Linear Regression in PySpark
Must-know: Pipeline: imports, read CSV into data frame, VectorAssembler -> features, randomSplit([0.7,0.3]) disjoint, lr.fit(trainingData), coefficients/intercept, training RMSE 4.7 / MAE 3.27, test RMSE 5.2 / MAE 3.4. RMSE >= MAE so the order is RMSE 4.7, MAE 3.27.
⚠️ Top pitfall: Quoting training error as accuracy; forgetting the test set must be unseen data.
Self-check: Why must training and test splits be disjoint? What does a 0.0 coefficient mean?
Connects to: 8.4 Simple Linear Regression, 8.5 Multilinear and Polynomial Regression, 8.10 Hands-On: Decision Tree Classifier in PySpark
Classification
Must-know: Classification is two steps: construction (learn rules/tree/formula from labeled data) and usage (classify unseen data). Accuracy = % of test samples correctly classified.
\[\text{Accuracy} = \frac{\text{correctly classified test samples}}{\text{all test samples}} \times 100\%\]
⚠️ Top pitfall: Judging the classifier on training data instead of unseen test data.
Self-check: In the tenure rule, what class is predicted for an associate professor with 7 years?
Connects to: 8.3 Regression vs Classification, 8.8 Decision Trees and the Buys-Computer Example
Decision Trees and the Buys-Computer Example
Must-know: Buys-computer: 14 tuples, 9 yes 5 no. Root = age (youth -> student?; middle-aged -> yes, pure; senior -> credit rating). Pure partition = all tuples one class. Stopping: pure node, no attributes left, majority voting at impure leaf, no samples left.
⚠️ Top pitfall: Expecting every split to be pure — 100% accuracy is impossible, majority voting handles impure leaves.
Self-check: Why does the middle-aged branch stop immediately in the buys-computer tree?
Connects to: 8.7 Classification, 8.9 Choosing the Split Attribute: Information Gain and Gini
Choosing the Split Attribute: Information Gain and Gini
Must-know: I(p1,p2) = -p1 log2 p1 - p2 log2 p2; gain = I(parent) - weighted I(children), maximize. Gini = 1 - sum p_i^2, weighted across branches, minimize. Root 0.940; age 0.694; gain 0.246 -> age. Income gini: 0.458, 0.450, 0.443 -> low+medium bucket.
\[\text{Gain}(\text{attr}) = I(\text{parent}) - \sum_{\text{branches}} \frac{|D_j|}{|D|} I(D_j), \qquad \text{Gini} = 1 - \sum_i p_i^2\]
⚠️ Top pitfall: Reversing the directions: information gain maximum, gini minimum.
Self-check: Which attribute wins the root split in buys-computer and what is its gain?
Connects to: 8.8 Decision Trees and the Buys-Computer Example, 8.10 Hands-On: Decision Tree Classifier in PySpark
Hands-On: Decision Tree Classifier in PySpark
Must-know: Multi-class problem (quality 0-10). Pipeline: vector assembler, randomSplit([0.7,0.3], seed), DecisionTreeClassifier(features, quality, maxDepth=3), fit, predict. Depth too small -> underfit; too large -> overfit.
⚠️ Top pitfall: Judging the model by a single prediction row instead of the whole test set.
Self-check: Why does the seed make the train/test split reproducible? What does a wrong prediction at depth 3 suggest?
Connects to: 8.8 Decision Trees and the Buys-Computer Example, 8.9 Choosing the Split Attribute: Information Gain and Gini, 8.6 Hands-On: Linear Regression in PySpark
Clustering
Must-know: Minkowski d(i,j) = (sum_{k=1}^p |x_ik - x_jk|^q)^(1/q); q=1 Manhattan (L1), q=2 Euclidean (L2). Binary: (b+c)/(a+b+c+d). Asymmetric: (b+c)/(a+b+c), Jaccard = a/(a+b+c). Nominal: (p-m)/p. Objective: intra minimized, inter maximized.
\[d(i,j) = \left( \sum_{k=1}^{p} \left| x_{ik} - x_{jk} \right|^{q} \right)^{1/q}\]
⚠️ Top pitfall: Forgetting the weights/directions: L1 = absolute sum, L2 = sqrt of squared sum; exam problems specify which to use.
Self-check: Compute Manhattan and Euclidean distances between (1,2) and (4,6).
Connects to: 8.2 Supervised vs Unsupervised Learning, 8.12 K-Means Clustering
K-Means Clustering
Must-know: K-means steps: k initial centroids, assign nearest, recompute as average per feature, iterate till stable. SSE = sum_{i=1}^k sum_{x in C_i} ||x - mu_i||^2, minimized. Exam: use L1 if problem says L1, L2 if L2. Fails on unequal size/density (DBSCAN) and non-globular shapes.
\[\text{SSE} = \sum_{i=1}^{k} \sum_{x \in C_i} \| x - \mu_i \|^2\]
⚠️ Top pitfall: Using k-means on non-globular clusters or assuming deterministic results — the initial centroids matter.
Self-check: Why does k-means stop when points stop shuffling between clusters?
Connects to: 8.11 Clustering, 8.13 Hands-On: K-Means in PySpark
Hands-On: K-Means in PySpark
Must-know: kmeans_data.txt: six 3-D points (0.0,0.0,0.0; 0.1,0.1,0.1; 0.2,0.2,0.2; 9.0,9.0,9.0; 9.1,9.1,9.1; 9.2,9.2,9.2). k=2, no train/test split. Output: cost 0.12, centroids 0.1,0.1,0.1 and 9.1,9.1,9.1, 2 iterations.
\[\text{cost} = 0.06 + 0.06 = 0.12\]
⚠️ Top pitfall: Confusing kmeans.txt with kmeans_data.txt; expecting a train/test split in clustering.
Self-check: Why is there no train/test split in the k-means program?
Connects to: 8.12 K-Means Clustering, 8.11 Clustering
Recommendation Systems
Must-know: Content-based = item attributes only (genre/actor/director). Collaborative filtering = user behavior: user-based (find similar users, recommend what they bought) vs item-based (items similar because same users rated alike; Amazon). Similarity index wrt active user; nearest neighbor; unsupervised.
⚠️ Top pitfall: Conflating the audience co-listening example with content-based — co-listening is behavioral (collaborative); content-based uses item attributes.
Self-check: In the friend-circle analogy, what are the 5 friends in collaborative-filtering terms?
Connects to: 8.2 Supervised vs Unsupervised Learning, 8.3 Regression vs Classification
Exam Guidance Summary
Must-know: All four techniques examinable; information gain max / gini min for attribute selection; use L1 or L2 as the problem specifies; code-snippet questions possible.
⚠️ Top pitfall: Studying out-of-scope topics (gradient descent, silhouette, DBSCAN, matrix factorization, hyperparameter tuning).
Self-check: Which two attribute-selection metrics are examinable and in which directions?
Connects to: 8.9 Choosing the Split Attribute: Information Gain and Gini, 8.12 K-Means Clustering
Key Industry Applications
Must-know: Spam filtering is the canonical ML application; recommenders run on Netflix/Amazon/e-commerce; sales prediction drives inventory planning (Big Billion Days).
Self-check: Which datasets are the standard benchmarks used in the regression and classification demos?
Connects to: 8.1 What Machine Learning Is, 8.3 Regression vs Classification, 8.14 Recommendation Systems