cswork / libraryOpen practice workspace

Articles

Collaborative Filtering Interview Questions: Explicit Ratings, Implicit Feedback, and ALS

Practice collaborative filtering interviews with explicit ratings, implicit confidence, worked ALS updates, and evaluation checks for missing predictions.

A collaborative filtering interview often starts with a sparse user–item table. The decisive question comes before choosing ALS: does an empty cell mean an unknown rating, or a weak-confidence absence of interaction? Those interpretations produce different objectives and different factor updates.

A strong answer states the observation rule, derives one small update, and evaluates recommendations on a clearly defined population. It does not turn missing ratings into zero-star reviews or treat repeated clicks as repeated declarations of preference.

This guide uses official Spark documentation and the original implicit-feedback research for algorithm contracts. The numerical updates, evaluation ledger, and preparation recommendations are original exercises.

Separate ratings, preferences, and confidence

Official fact: Spark ALS supports explicit feedback and an implicit-feedback variant through implicitPrefs. Its documentation distinguishes observed ratings from behavioral signals whose strength contributes confidence in preference. Spark collaborative filtering guide.

For an original explicit example, a user rated item A five stars and item C one star. Item B has no rating. The training mask includes A and C; B is unknown. A zero in an array is not enough to tell whether B was observed, so preserve a separate mask or sparse observation list.

For an original implicit example, the same user generated three events on A, zero on B, and one on C. We define positive interaction as preference one, absence as preference zero, and confidence as 1 + alpha * event_count. This is a simplified nonnegative-event exercise based on the implicit-feedback formulation; it excludes explicit dislikes and signed feedback. Hu, Koren, and Volinsky's implicit-feedback paper.

Under that definition, A and C have the same preference target despite different event counts. A receives more confidence. B contributes a weaker zero-preference term; that modeling term is not evidence that the user saw B and disliked it.

Ask what creates an event, how duplicates are identified, and whether views and purchases are comparable. Replayed events can inflate confidence without adding information. Define aggregation windows and deduplication before searching for an optimal alpha.

Explain neighborhood methods before factorization

A user-based approach finds similar users and uses their histories to suggest items. An item-based approach finds items with similar interaction patterns and scores them from the user's history. Matrix factorization instead learns compact user and item vectors and scores a pair through their dot product.

For interview reasoning, compare what must be stored and refreshed. A neighborhood design needs a similarity definition and enough overlap; a factor model needs a training objective, factor updates, and a serving path. “Matrix factorization scales” is incomplete without discussing catalog size, factor dimension, training cadence, and candidate retrieval.

A sparse observation matrix should not automatically become a dense zero-filled matrix for a conventional SVD. In our explicit task, zero-filling introduces invented targets. State which objective you are solving rather than using “SVD” and “ALS” as interchangeable algorithm names.

Latent coordinates also have no inherent business meaning. If a factor coordinate is negative, that does not by itself mean negative sentiment. The score and objective determine its interpretation; naming a coordinate “comedy preference” requires additional evidence.

Derive one explicit ALS update

Our original two-factor exercise fixes three item vectors:

A = [1, 0]
B = [0, 1]
C = [1, 1]
Observed ratings: A = 5, C = 1; B is missing
Regularization lambda = 1

For this teaching objective, minimize squared error over observed items plus lambda * ||x||², where x is the user's factor vector. Holding the item vectors fixed turns the user update into a regularized least-squares problem.

Stack only the observed item vectors into Y_obs. The normal equation is:

(Y_obs.T @ Y_obs + lambda * I) @ x = Y_obs.T @ ratings

In our example, the matrix on the left is [[3,1],[1,2]] and the right-hand vector is [6,1]. Solving gives x = [2.2, -0.6]. The fitted scores for A and C are 2.2 and 1.6; they need not equal the original ratings because regularization and shared factors constrain the solution.

Now deliberately insert B as an observed zero rating. The left matrix becomes [[3,1],[1,3]], and the solution changes to [2.125,-0.375]. This is an observable counterexample to the claim that missing and zero are equivalent.

The example uses an unscaled regularization coefficient to keep the arithmetic transparent. Official fact: Spark scales its regularization by the number of ratings associated with the user or item in its ALS-WR formulation. Our solve is not a reproduction of Spark's complete implementation. Spark regularization documentation.

Show why implicit ALS includes unobserved items

For the implicit version, keep the same item factors but use event counts [3,0,1], alpha = 2, and lambda = 1. Preferences are [1,0,1], while confidences are [7,1,3].

The weighted least-squares update uses all three item vectors:

(Y.T @ C @ Y + lambda * I) @ x = Y.T @ C @ preference

Here C is a diagonal confidence matrix. The general weighted objective and alternating update are described in the original paper and oneDAL's algorithm reference. Implicit-feedback paper, oneDAL implicit ALS.

Our original arithmetic yields left matrix [[11,3],[3,5]], right vector [10,3], and x = [41/46, 3/46], approximately [0.8913,0.0652]. These are preference-oriented scores, not predictions of five-star ratings or calibrated click probabilities.

B's zero-preference contribution remains in the left matrix even though its right-hand contribution is zero. Removing B changes the problem. At a large catalog scale, avoid constructing a dense confidence matrix: the baseline Y.T @ Y plus sparse corrections for stronger-confidence observations expresses the same update.

Increasing alpha changes relative penalties, not just training speed. An interviewer can test your reasoning by asking whether a tenfold event-count increase changes preference, confidence, or both under the stated rule. Answer from the definition before discussing tuning.

Execute the small solve and check its residual

The following original NumPy fixture was executed locally. It verifies the two updates and the normal-equation residual; it does not run Spark training or claim recommender quality.

import numpy as np

Y = np.array([[1., 0.], [0., 1.], [1., 1.]])
lam = 1.0
obs = np.array([0, 2])
ratings = np.array([5., 1.])
Yo = Y[obs]
Ae = Yo.T @ Yo + lam * np.eye(2)
be = Yo.T @ ratings
xe = np.linalg.solve(Ae, be)
np.testing.assert_allclose(xe, [2.2, -0.6])

counts = np.array([3., 0., 1.])
pref = (counts > 0).astype(float)
confidence = 1 + 2 * counts
Ai = Y.T @ (confidence[:, None] * Y) + lam * np.eye(2)
bi = Y.T @ (confidence * pref)
xi = np.linalg.solve(Ai, bi)
np.testing.assert_allclose(xi, [41/46, 3/46])
np.testing.assert_allclose(Ai @ xi, bi)

Use a linear solve rather than explicitly forming a matrix inverse. Check dimensions: with rank two, both left matrices are 2 × 2, both right vectors have length two, and the updated user vector also has length two.

Positive regularization helps make these particular unconstrained solves well-defined even when item vectors are redundant. It does not make every jointly optimized factorization globally optimal. ALS alternates user updates with fixed items and item updates with fixed users; initialization and stopping criteria remain part of the full training procedure.

Useful follow-up tests include duplicate item factors, a user with one observed rating, and zero events across the implicit catalog. Under our implicit objective with positive regularization, an all-zero preference vector produces a zero user vector. That is a consequence of this exercise, not a complete new-user serving policy.

Inspect Spark parameters as contracts

Official facts: Spark's ALS API exposes rank, maxIter, regParam, implicitPrefs, alpha, and optional nonnegative constraints. User and item identifiers must fit the supported integer range. PySpark ALS reference.

Our preparation recommendation is to narrate each parameter's role. Rank sets vector dimension; iteration count sets an optimization budget; regularization changes the objective. Confidence scaling matters only for the implicit formulation being used. A nonnegative constraint changes the optimization problem, so do not apply the unconstrained normal-equation solution unchanged and claim it solves that variant.

Keep a stable mapping from external identifiers to model identifiers. An inconsistent mapping can make a plausible score belong to the wrong item. Save the mapping version with factors and test retrieval against known user–item pairs.

Before comparing configurations, fix the input snapshot and event aggregation rule. A model with a different history window is not simply a rank-tuning experiment. Record data eligibility and factor availability alongside the hyperparameters.

Evaluate the population, not only the surviving predictions

Official fact: Spark can emit NaN when a user or item factor is unavailable; coldStartStrategy='drop' removes those rows before metric computation. Spark cold-start strategy.

Consider this original diagnostic ledger:

ConfigurationEligible evaluation rowsScored rowsRMSE on scored rows
A1,0008500.90
B1,0007500.85

You cannot infer that B improved overall quality from these numbers. It scored fewer rows, possibly excluding harder cases. Compare a fixed shared population where appropriate and report coverage separately. Specify how unavailable factors are handled in the full product evaluation.

For ranking, define the eligible candidate set, held-out positives, cutoff K, and aggregation across users. Removing already-seen items or enforcing access restrictions changes the ranking problem. A low rating RMSE does not directly establish a better top-K list.

Our recommendation is to use time-aware splits when predicting future behavior, with no future events in factor training or candidate features. Include a simple popularity baseline on the same eligible catalog and users. Sampled negatives must follow the same protocol across models; changing sampling can change the apparent ranking score.

New-user fallback decisions deserve their own design discussion. Use the separate Cold-Start Recommendation interview guide for that scope; here the key issue is reporting unavailable-factor coverage honestly.

Finish with the objective and one counterexample

Define missingness, solve one user update, then show how zero-filling or silently dropping evaluation rows changes the answer.

That gives the interviewer something concrete to inspect: an observation mask, a normal equation, a checked numerical result, and an evaluation population. It is a stronger preparation target than memorizing one library configuration.

Sources and Further Reading

Research checked October 4, 2026. NumPy solves are original arithmetic controls; Spark version defaults and constraints should be checked against the runtime used in your interview.