Docs · Machine learning

als: alternating least squares.

Alternating least squares matrix factorisation for explicit ratings, the equivalent of Spark MLlib's ALS. Each iteration is two paged passes over the ratings: a user step with the item factors resident and an item step with the user factors resident.

Module
ml_als
Header
clio_ml/als.h
Rows
user, item, rating, pad
Limits
ids below 2^24, rank at most 16

What it does

A pass accumulates each entity's normal equations in fixed row order; the host solves (sum v v^T + lambda * n * I) x = sum r v by Cholesky in double precision. The result is bit-reproducible across paging, block counts and cluster nodes.

Rows

Fixed 4-column records: [user, item, rating, pad]. The pad column is ignored and keeps rows page-aligned. Ids are floats holding integers below 2^24. clio_ml.COLUMNS["als"] is None: the Python wrapper passes no column count.

Python

python
import numpy as np, clio_ml as cm
rng = np.random.default_rng(1)
n = 4096
u, i = rng.integers(0, 32, n), rng.integers(0, 32, n)
ratings = np.column_stack([u, i, rng.random(n), np.zeros(n)]).astype(np.float32)

r = cm.fit_als(ratings, num_users=32, num_items=32, rank=4, iters=3)
m = r.model
U = np.asarray(m.user_factors).reshape(m.U, m.k)
I = np.asarray(m.item_factors).reshape(m.I, m.k)
print(U[0] @ I[0])                       # predicted rating for user 0, item 0
print(cm.native.AlsPredict(m, 0, 0))     # the same from C++
  • fit_als(X, **options). num_users and num_items must be set.
  • Options (AlsOptions): num_users (0), num_items (0), rank (4, at most 16), iters (10), lambda (1e-3), seed (1), threads (256).
  • Result AlsResult: model and stats (summed over passes). model (AlsModel): U, I, k, user_factors (U*k), item_factors (I*k).
  • No predict entry; use clio_ml.native.AlsPredict(model, user, item) or a dot product.

C++

cpp
struct AlsOptions {
  u32 num_users = 0, num_items = 0;
  u32 rank = 4;        // <= 16
  u32 iters = 10;
  float lambda = 1e-3f;
  u32 seed = 1;
  u32 threads = 256;
  ClusterExchange cluster;
};
struct AlsModel {
  u32 U = 0, I = 0, k = 0;
  std::vector<float> user_factors;  // U*k
  std::vector<float> item_factors;  // I*k
  std::vector<float> Flatten() const;
};
struct AlsResult { AlsModel model; VecStats stats; };
AlsResult FitAls(Dataset &ds, const AlsOptions &opt);
AlsResult FitAlsPlain(const float *data, u64 n_ratings, u64 elems_per_page,
                      u32 nblocks, const AlsOptions &opt);
AlsResult FitAlsReference(/* same arguments */);
float AlsPredict(const AlsModel &m, u32 user, u32 item);

The ChiMod is module ml_als.

Related: factorization machine, PCA.