Skip to content

Classical AI, ML & RL

Six pure-NumPy modules that broaden OptimumAI from the deep-learning/LLM stack to the whole field. Every concept is an explainable Trace — run it with explain=True in Python, from the CLI, or as a course lesson.


Machine learning — optimumai.ml

Linear & logistic regression, k-means, KNN, decision trees, Gaussian naive Bayes, PCA, and a complete metrics module.

Class / function CLI What it teaches
LinearRegression optimumai ml linreg OLS normal equation: θ = (XᵀX)⁻¹Xᵀy
LogisticRegression optimumai ml logreg ŷ = σ(Xθ), cross-entropy, gradient descent
KMeans optimumai ml kmeans Lloyd's algorithm: assign → recompute → repeat
KNN optimumai ml knn Majority vote among k nearest Euclidean neighbors
DecisionTree optimumai ml tree Greedy information-gain splits (Gini/entropy)
GaussianNB optimumai ml nb Bayes' rule with per-feature Gaussian likelihood
PCA optimumai ml pca Eigendecomposition of the covariance matrix
metrics optimumai ml metrics accuracy, precision_recall_f1, confusion_matrix, mse, r2_score, roc_auc
from optimumai.ml import LinearRegression, LogisticRegression, KMeans, KNN
from optimumai.ml import DecisionTree, GaussianNB, PCA
from optimumai.ml.metrics import accuracy, precision_recall_f1, roc_auc

# Linear regression
model = LinearRegression()
model.fit([[1], [2], [3], [4]], [2, 4, 6, 8])
model.predict([[5]])                          # ≈ [10]

# K-means
km = KMeans(k=2)
km.fit([[0, 0], [0, 1], [9, 9], [9, 8]])
km.predict([[1, 1]])                          # -> cluster 0
optimumai ml linreg "[[1],[2],[3],[4]]" "[2,4,6,8]"
optimumai ml logreg
optimumai ml kmeans "[[0,0],[0,1],[9,9],[9,8]]" --k 2
optimumai ml knn
optimumai ml tree
optimumai ml nb
optimumai ml pca
optimumai ml metrics

optimumai.ml

Classical machine learning — the algorithms that predate (and still outlive) deep nets.

Every estimator here follows the same shape as the rest of OptimumAI: a <name>_trace(...) function builds a full step-by-step :class:~optimumai.core.trace.Trace with real numbers, and a thin class (LinearRegression, KMeans, ...) wraps it in the familiar fit/predict interface.

DecisionTree

A shallow classification tree grown by greedy impurity-reduction splits.

Example

model = DecisionTree(max_depth=1).fit([[0], [1], [10], [11]], [0, 0, 1, 1]) model.predict([[0.5], [10.5]]) array([0, 1])

fit(X, y)

Grow the tree greedily, splitting on maximum information gain.

predict(X)

Route each row of X through the fitted tree to a leaf prediction.

explain(X, y, level=ExplainLevel.INTERMEDIATE)

Fit, print the root-split search trace, and return training predictions.

KMeans

Lloyd's-algorithm k-means clustering.

Example

model = KMeans(k=2).fit([[0], [1], [10], [11]]) model.predict([[0.5], [10.5]]) array([0, 1])

fit(X)

Run Lloyd's algorithm to convergence (or :attr:max_iters).

predict(X)

Assign new points to the nearest fitted centroid.

explain(X, level=ExplainLevel.INTERMEDIATE)

Fit, print the full assign/update trace, and return cluster labels.

KNN

k-nearest-neighbors classifier: store the data, vote at prediction time.

Example

model = KNN(k=1).fit([[0], [1], [10], [11]], [0, 0, 1, 1]) model.predict([[0.5], [10.5]]) array([0, 1])

fit(X, y)

Store the training data (k-NN has no learned parameters).

predict(X)

Classify each row of X by majority vote of its k nearest neighbors.

explain(x_query, level=ExplainLevel.INTERMEDIATE)

Print the full distance/vote trace for one query point and return its label.

LinearRegression

Ordinary least squares via the normal equation.

Example

model = LinearRegression().fit([[1], [2], [3]], [2, 4, 6]) model.predict([[4]]) array([8.])

fit(X, y)

Fit θ by the normal equation and store it on the model.

predict(X)

Predict ŷ = Xθ for new samples (must call :meth:fit first).

explain(X, y, level=ExplainLevel.INTERMEDIATE)

Fit, print the full trace, and return the training predictions.

LogisticRegression

Binary logistic regression trained by batch gradient descent.

Example

model = LogisticRegression(lr=0.5, steps=200).fit([[0], [1], [2], [3]], [0, 0, 1, 1]) model.predict([[0.1], [2.9]]) array([0, 1])

fit(X, y)

Run :attr:steps gradient-descent updates and store the final weights.

predict_proba(X)

Return P(y=1|x) for new samples (must call :meth:fit first).

predict(X)

Return the hard 0/1 label (threshold at 0.5).

explain(X, y, level=ExplainLevel.INTERMEDIATE)

Fit, print the full trace (with :attr:steps gradient updates shown), return labels.

GaussianNB

Gaussian Naive Bayes classifier.

Example

model = GaussianNB().fit([[0], [1], [10], [11]], [0, 0, 1, 1]) model.predict([[0.5], [10.5]]) array([0, 1])

fit(X, y)

Estimate class priors and per-feature Gaussian parameters.

predict(X)

Classify each row of X by argmax log-posterior.

explain(x_query, level=ExplainLevel.INTERMEDIATE)

Print the full prior/likelihood/posterior trace for one query point.

PCA

Principal Component Analysis via covariance eigendecomposition.

Example

model = PCA(n_components=1).fit([[0, 0], [1, 1], [2, 2], [3, 3]]) model.transform([[4, 4]]).shape (1, 1)

fit(X)

Compute the mean and top principal components from X.

transform(X)

Project new data onto the fitted principal components.

fit_transform(X)

Fit on X and return the projected training data in one call.

explain(X, level=ExplainLevel.INTERMEDIATE)

Fit, print the full center/covariance/eigen trace, and return the projection.

decision_tree_trace(X, y, max_depth=2, criterion='gini')

Build a trace of the best-split search at the root, then grow a shallow tree.

Parameters:

Name Type Description Default
X

Features, shape (n, d) (or (n,)).

required
y

Integer class labels, shape (n,).

required
max_depth int

Maximum depth of the fitted tree.

2
criterion str

"gini" or "entropy".

'gini'

entropy_impurity(y)

Shannon entropy −Σ pᵢ log₂(pᵢ) of the labels in y.

gini_impurity(y)

Gini impurity 1 − Σ pᵢ² of the labels in y.

kmeans_trace(X, k=2, max_iters=10, init=None)

Build the full Lloyd's-algorithm trace, clustering X into k groups.

Parameters:

Name Type Description Default
X

Data points, shape (n, d) (or (n,) for 1-D data).

required
k int

Number of clusters.

2
max_iters int

Safety cap on assign/update rounds.

10
init ndarray | None

Optional starting centroids, shape (k, d). Defaults to the first k points, which keeps the demo deterministic.

None

knn_trace(X_train, y_train, x_query, k=3)

Build the full distance/vote trace classifying one query point.

Parameters:

Name Type Description Default
X_train

Training features, shape (n, d) (or (n,)).

required
y_train

Training labels, shape (n,).

required
x_query

A single query point, shape (d,) (or a scalar for 1-D).

required
k int

Number of neighbors to vote.

3

linear_regression_trace(X, y)

Build the full normal-equation trace fitting ŷ = Xθ to (X, y).

logistic_regression_trace(X, y, lr=0.5, steps=3, theta0=None)

Build a trace of a few gradient-descent steps fitting logistic regression.

Parameters:

Name Type Description Default
X

Feature matrix, shape (n, d) (or (n,) for one feature).

required
y

Binary labels in {0, 1}, shape (n,).

required
lr float

Learning rate for each gradient step.

0.5
steps int

Number of gradient-descent steps to trace (kept small — a real fit would run until the loss plateaus).

3
theta0 ndarray | None

Optional starting weights (zeros by default).

None

accuracy(y_true, y_pred)

Fraction of predictions that exactly match the true labels.

accuracy_trace(y_true, y_pred)

Build the trace of accuracy = fraction of exactly-correct predictions.

confusion_matrix(y_true, y_pred, labels=None)

Confusion matrix (rows = true label, columns = predicted label).

confusion_matrix_trace(y_true, y_pred, labels=None)

Build the trace of the confusion matrix (rows = true, columns = predicted).

mse(y_true, y_pred)

Mean squared error between y_true and y_pred.

mse_trace(y_true, y_pred)

Build the trace of mean squared error.

precision_recall_f1(y_true, y_pred, positive_label=1)

Return {"precision": ..., "recall": ..., "f1": ...} for positive_label.

precision_recall_f1_trace(y_true, y_pred, positive_label=1)

Build the trace of binary precision, recall, and F1 for positive_label.

r2_score(y_true, y_pred)

R² (coefficient of determination) between y_true and y_pred.

r2_score_trace(y_true, y_pred)

Build the trace of the R² (coefficient of determination) score.

roc_auc(y_true, y_scores)

ROC-AUC for binary labels y_true given continuous y_scores.

roc_auc_trace(y_true, y_scores)

Build the trace of ROC-AUC via the Mann-Whitney rank-sum formula.

y_true must be binary (0/1); y_scores are the model's continuous scores or probabilities for the positive class.

naive_bayes_trace(X_train, y_train, x_query)

Build the full prior/likelihood/posterior trace classifying one query point.

Parameters:

Name Type Description Default
X_train

Training features, shape (n, d) (or (n,)).

required
y_train

Training labels, shape (n,).

required
x_query

A single query point, shape (d,) (or a scalar for 1-D).

required

pca_trace(X, n_components=1)

Build the full center/covariance/eigendecomposition/project trace.

Parameters:

Name Type Description Default
X

Data, shape (n, d).

required
n_components int

How many top principal components to keep (k <= d).

1

Classical AI search — optimumai.search

BFS, DFS, uniform-cost (Dijkstra), greedy best-first, A*, minimax, and alpha-beta pruning over reusable Graph / GridWorld problems.

Function CLI What it teaches
bfs optimumai algo bfs Fewest-edge path (uninformed, queue)
dfs optimumai algo bfs Depth-first (uninformed, stack)
ucs (Dijkstra) optimumai algo bfs Cheapest-cost path (uniform cost)
astar optimumai algo astar f = g + h, optimal when h is admissible
minimax optimumai algo minimax Game tree search with opponent
alpha_beta optimumai algo minimax Minimax with pruning — same result, less work
from optimumai.search import bfs, ucs, astar
from optimumai.search.problem import Graph, GridWorld

g = Graph()
g.add_edge("A", "B", 1); g.add_edge("B", "C", 1)
g.add_edge("C", "D", 1); g.add_edge("B", "D", 5)

bfs(g, "A", "D")    # fewest edges: ['A', 'B', 'D']
ucs(g, "A", "D")    # cheapest cost: ['A', 'B', 'C', 'D'] (cost 3)

BFS vs. UCS

BFS finds the path with the fewest edges; UCS (Dijkstra) finds the path with the lowest total cost — they can disagree on weighted graphs.

optimumai algo bfs
optimumai algo astar
optimumai algo minimax

optimumai.search

Classical AI search — how agents find paths and choose moves.

Two families, four algorithms:

  • Path-finding (:mod:optimumai.search.uninformed, :mod:optimumai.search.informed) — :func:bfs, :func:dfs, :func:uniform_cost_search, :func:greedy_best_first, and :func:astar all search a :class:~optimumai.search.problem.Graph or :class:~optimumai.search.problem.GridWorld for a route from a start state to a goal state.
  • Adversarial search (:mod:optimumai.search.adversarial) — :func:minimax and :func:alpha_beta choose a move in a two-player game tree, with alpha-beta pruning finding the identical value while visiting fewer nodes.

Every function has a *_trace counterpart (e.g. :func:astar_trace) that returns a full :class:~optimumai.core.trace.Trace of the search: frontier contents, expansion order, and (for informed/adversarial search) the g/h/f values or the alpha-beta window at every step.

GameNode dataclass

A node in a small, explicit game tree.

A leaf has value set and no children; an internal node has children and no value. player records whose turn it is to move at this node ("max" or "min"), used only for the trace narration — the recursion itself alternates automatically.

Attributes:

Name Type Description
name str

Short label for tracing, e.g. "A" or "root".

value float | None

The static evaluation, only set on leaves.

children list[GameNode]

Child nodes reachable by one move, only set on internal nodes.

player Literal['max', 'min']

Whose turn it is to move at this node.

is_leaf property

True if this node has no children (a terminal position).

Graph dataclass

An explicit directed, weighted graph used as a search problem.

The adjacency structure is a plain dict[state, dict[neighbor, cost]] — no external graph library needed. Edges are directed: add both a -> b and b -> a for an undirected edge (see :meth:add_edge).

Attributes:

Name Type Description
adjacency dict[State, dict[State, float]]

{state: {neighbor: edge_cost, ...}, ...}.

heuristics dict[State, float]

Optional straight-line-style estimates {state: h(state)} for use with greedy best-first / A. Defaults to 0 everywhere (which makes A degrade gracefully to uniform-cost search).

Example

g = Graph() g.add_edge("A", "B", 1) g.add_edge("B", "C", 2) g.neighbors("A") {'B': 1} g.cost("B", "C") 2

add_edge(a, b, cost=1.0, bidirectional=True)

Add an edge a -> b with the given cost (and the reverse, by default).

neighbors(state)

Return {neighbor: edge_cost} reachable in one step from state.

cost(a, b)

Return the edge cost of the direct move a -> b.

heuristic(state, goal)

Return an estimate of the remaining cost from state to goal.

Falls back to 0 for states with no registered heuristic, which is always admissible (never overestimates) but uninformative.

states()

All states that appear as either an edge source or destination.

GridWorld dataclass

A 2-D grid path-finding problem: 4-connected moves, optional walls.

Coordinates are (row, col) with row increasing downward, matching how the grid is usually printed. Movement is restricted to the 4 orthogonal neighbors (no diagonals), each costing 1 by default, so BFS already finds shortest hop-count paths here — the more interesting question is how much less work A* does than BFS/UCS once a heuristic is added.

Attributes:

Name Type Description
width int

Number of columns.

height int

Number of rows.

walls set[Coord]

Set of blocked (row, col) cells that cannot be entered.

Example

gw = GridWorld(width=3, height=3, walls={(1, 1)}) sorted(gw.neighbors((0, 1))) [(0, 0), (0, 2), (1, 1)]

in_bounds(state)

True if state lies within the grid's rectangle.

is_free(state)

True if state is in bounds and not a wall.

neighbors(state)

Return {neighbor: 1.0} for the in-bounds, non-wall 4-neighbors.

Note the returned dict includes cells even when they happen to be walls filtered out — walls are excluded entirely, never returned.

cost(a, b)

Cost of moving from a to an adjacent free cell b (always 1).

heuristic(state, goal, kind='manhattan')

Estimate the remaining cost from state to goal.

manhattan (|dr| + |dc|) is admissible here because every move costs exactly 1 and can only change row or column by 1 — the true remaining cost can never be less than the Manhattan distance. euclidean is also admissible (straight-line distance is never longer than a path constrained to a grid) but less tight, so it prunes less and A* typically expands more nodes with it than with Manhattan on a 4-connected grid.

render(path=None)

Render the grid as text: # walls, * path, . free cells.

alpha_beta(node, maximizing=True, alpha=float('-inf'), beta=float('inf'))

Return the minimax value of node's game tree, computed with pruning.

alpha_beta_trace(node, maximizing=True, alpha=float('-inf'), beta=float('inf'))

Build the full trace of minimax with alpha-beta pruning.

Returns the identical root value :func:minimax_trace would (see the module docstring for why), while typically visiting far fewer nodes — the trace records every prune with the (alpha, beta) window active at the time.

minimax(node, maximizing=True)

Return the minimax value of the root of node's game tree.

minimax_trace(node, maximizing=True)

Build the full trace of plain minimax evaluation over a game tree.

astar(problem, start, goal)

Return the optimal path from start to goal via A* (admissible h assumed).

astar_trace(problem, start, goal)

Build the full trace of A* search (order by f(n) = g(n) + h(n)).

Optimal whenever problem.heuristic is admissible (never overestimates the true remaining cost) — see the module docstring for the proof sketch.

greedy_best_first(problem, start, goal)

Return a path from start to goal via greedy best-first search.

greedy_best_first_trace(problem, start, goal)

Build the full trace of greedy best-first search (order by h(n) alone).

bfs(problem, start, goal)

Return the fewest-edges path from start to goal (BFS).

bfs_trace(problem, start, goal)

Build the full trace of breadth-first search from start to goal.

dfs(problem, start, goal)

Return a path from start to goal found via DFS (not necessarily optimal).

dfs_trace(problem, start, goal)

Build the full trace of depth-first search from start to goal.

Return the minimum-cost path from start to goal (UCS / Dijkstra).

uniform_cost_search_trace(problem, start, goal)

Build the full trace of uniform-cost search (Dijkstra to a single goal).


Reinforcement learning — optimumai.rl

MDPs with value & policy iteration (the Bellman equation), tabular Q-learning / SARSA, REINFORCE, and the PPO clipped surrogate objective.

Component CLI What it teaches
value_iteration optimumai rl mdp Bellman backup to exact V*
policy_iteration optimumai rl mdp Alternating policy eval + improvement
q_learning optimumai rl q-learning Off-policy TD control
sarsa optimumai rl q-learning On-policy TD control
reinforce optimumai rl reinforce Policy gradient: REINFORCE on a bandit
ppo_clip optimumai rl ppo Clipped surrogate objective
from optimumai.rl import value_iteration, q_learning, ppo_clip
from optimumai.rl.mdp import MDP

mdp = MDP.demo()           # a small gridworld
V, pi = value_iteration(mdp, gamma=0.9, explain=True)
optimumai rl mdp
optimumai rl q-learning
optimumai rl reinforce
optimumai rl ppo

optimumai.rl

Reinforcement learning — how an agent learns to act from reward alone.

Four building blocks, each handed off to the next:

  • :mod:optimumai.rl.mdp — the formal object (states, actions, transitions, rewards, discount) and the Bellman equation that "solves" it exactly when the environment model is known (value iteration, policy iteration).
  • :mod:optimumai.rl.q_learning — model-free temporal-difference learning (Q-learning, SARSA) when the model is not known, only lived experience.
  • :mod:optimumai.rl.policy_gradient — REINFORCE, which parameterizes the policy directly and differentiates through sampled actions via the score-function trick.
  • :mod:optimumai.rl.ppo — PPO's clipped surrogate objective, the stabilized policy-gradient update that powers the reinforcement-learning stage of RLHF (contrasted with the closed-form DPO loss in :mod:optimumai.frontier.rlhf).

MDP dataclass

A finite, discounted Markov Decision Process.

Attributes:

Name Type Description
states list[str]

State labels, e.g. ["s0", "s1", "s2"].

actions list[str]

Action labels, e.g. ["left", "right"].

transition ndarray

P[s_idx][a_idx] is a probability vector over next-state indices — transition[s][a][s'] = P(s'|s, a). Must sum to 1 per (s, a).

reward ndarray

R[s_idx][a_idx][s'_idx] = immediate reward for that transition.

gamma float

Discount factor, 0 <= gamma < 1.

terminal frozenset[int]

Optional set of state indices with no outgoing value (their value is fixed at 0 and they are excluded from the max/backup).

expected_backup(values, s, a)

The Bellman backup Σₛ' P(s'|s,a)[R(s,a,s') + γV(s')] for one (s, a).

BanditEnv dataclass

A stateless k-armed bandit: pick an arm, get a fixed reward.

Deterministic rewards keep the lesson focused on how REINFORCE shifts probability mass toward the best action, without the extra variance a stochastic reward would add on top of the policy's own sampling noise.

PPOSample dataclass

One (state, action) observation replayed from a rollout batch.

Attributes:

Name Type Description
old_logprob float

logπ_θ_old(a|s) — log-prob under the policy that generated this action (frozen for the whole batch).

new_logprob float

logπ_θ(a|s) — log-prob under the policy currently being optimized (changes across optimizer steps/epochs).

advantage float

Aₜ, how much better this action was than the state's baseline (e.g. from a critic / GAE — not recomputed here).

GridWorld dataclass

A tiny, fully deterministic grid: step off the edge and you don't move.

The agent starts at start and the episode ends on reaching goal (reward +goal_reward) or a cell in traps (reward trap_reward, also terminal). Every other step costs step_reward (encourages short paths). Deterministic transitions isolate the TD-learning behavior being taught here from the extra variance a stochastic MDP would add.

step(pos, action)

Apply action at pos; return (next_pos, reward, done).

policy_iteration(mdp, theta=1e-06, max_iterations=1000, explain=False, level=ExplainLevel.ENGINEER)

Return V^π* for mdp. explain=True prints the full trace.

policy_iteration_trace(mdp, theta=1e-06, max_iterations=1000)

Build the full trace of policy iteration converging to π* on mdp.

Alternates policy evaluation — solve the linear system V^π = R + γPV^π exactly for the current (possibly suboptimal) policy — with policy improvement — make the policy greedy w.r.t. that V^π — until the policy stops changing. Guaranteed to converge in a finite number of iterations for a finite MDP.

value_iteration(mdp, theta=1e-06, max_iterations=1000, explain=False, level=ExplainLevel.ENGINEER)

Return V* for mdp. explain=True prints the full trace.

value_iteration_trace(mdp, theta=1e-06, max_iterations=1000)

Build the full trace of value iteration converging to V* on mdp.

Repeatedly applies the Bellman optimality backup to every state, tracking the largest change Δ each sweep, and stops once Δ < theta. The greedy policy w.r.t. the converged values is then extracted.

reinforce(env=None, episodes=200, alpha=0.1, gamma=0.99, seed=0, explain=False, level=ExplainLevel.ENGINEER)

Return the learned action-probability vector. explain=True prints the trace.

reinforce_trace(env=None, episodes=200, alpha=0.1, gamma=0.99, seed=0)

Build the full trace of REINFORCE learning a softmax policy on env.

Each "episode" here is a single-step trajectory (state, action, reward) — enough to show the sample → return → score-function-gradient → update loop without the bookkeeping of multi-step return-to-go, which :func:optimumai.rl.ppo.ppo_trace picks up with real advantages instead.

ppo_clip(batch=None, epsilon=0.2, explain=False, level=ExplainLevel.ENGINEER)

Return the PPO clipped loss for batch. explain=True prints the trace.

ppo_clip_trace(batch=None, epsilon=0.2)

Build the full trace of the PPO clipped surrogate objective on batch.

Walks every sample through the ratio, the unclipped and clipped terms, whether/why clipping engaged, and the final batch-averaged loss (L = -mean(L^CLIP) since optimizers minimize).

q_learning_trace(world=None, episodes=500, alpha=0.5, gamma=0.9, epsilon=0.1, seed=0)

Build the full trace of tabular Q-learning on world (default: a 3x3 grid).

sarsa(world=None, episodes=500, alpha=0.5, gamma=0.9, epsilon=0.1, seed=0, explain=False, level=ExplainLevel.ENGINEER)

Return the learned Q-table. explain=True prints the full trace.

sarsa_trace(world=None, episodes=500, alpha=0.5, gamma=0.9, epsilon=0.1, seed=0)

Build the full trace of tabular SARSA on world (default: a 3x3 grid).


NLP — optimumai.nlp

Byte-pair encoding, TF-IDF, n-gram language models, Levenshtein edit distance, and skip-gram word2vec.

Component CLI What it teaches
BPETokenizer optimumai nlp bpe Vocabulary learning via pair merges
tfidf optimumai nlp tfidf Term distinctiveness: tf · log(N/df)
NGramLM optimumai nlp ngram N-gram LM, add-k smoothing, perplexity
edit_distance optimumai nlp edit-distance Levenshtein DP, O(mn)
word2vec optimumai nlp word2vec Skip-gram, negative sampling, one SGD step
from optimumai.nlp import BPETokenizer, edit_distance

tok = BPETokenizer(num_merges=8)
tok.train(["low", "lower", "lowest", "newer", "newest"])
tok.encode("lowest")                   # -> ['lo', 'west</w>']

edit_distance("kitten", "sitting", explain=True)   # -> 3
optimumai nlp bpe lowest
optimumai nlp bpe --merges 12 lowest
optimumai nlp tfidf "the cat sat" "the dog sat"
optimumai nlp ngram
optimumai nlp edit-distance kitten sitting
optimumai nlp word2vec

optimumai.nlp

Classical NLP — the statistical machinery beneath modern language models.

Before attention, before embeddings even, NLP was tokenization, counting, and dynamic programming. This package covers the fundamentals that still power production search/retrieval systems and explain why the neural approach in :mod:optimumai.transformers and :mod:optimumai.embeddings works:

  • :mod:optimumai.nlp.bpe — byte-pair encoding, how text becomes tokens
  • :mod:optimumai.nlp.tfidf — TF-IDF, weighting words by how distinguishing they are
  • :mod:optimumai.nlp.ngram — n-gram language models, counting your way to "next word"
  • :mod:optimumai.nlp.edit_distance — Levenshtein distance via dynamic programming
  • :mod:optimumai.nlp.word2vec — skip-gram, the seed idea behind every learned embedding

BPETokenizer

Learn BPE merges from a corpus, then encode new words with them.

Parameters:

Name Type Description Default
num_merges int

How many merge rules to learn during :meth:train.

10

train(corpus)

Learn up to num_merges merge rules from a list of training words.

encode(word)

Apply learned merges (in training order) to tokenize word.

NGramModel

A counting-based n-gram language model with add-k smoothing.

Parameters:

Name Type Description Default
n int

Order of the model (2 = bigram, 3 = trigram, ...). Must be >= 1.

2
k float

Add-k smoothing constant (k=1 is classic Laplace smoothing).

1.0

vocab_size property

Number of distinct tokens seen during :meth:fit (including BOS/EOS).

fit(corpus)

Count n-grams (and their contexts) over a list of sentences.

prob(context, word)

Add-k smoothed P(word | context) for a (n-1)-length context.

sentence_log_prob(sentence)

Sum of log P(w_i | context) over every n-gram in a padded sentence.

perplexity(corpus)

PPL = exp(-(1/N) * sum of log-probs) over every n-gram in corpus.

TfidfVectorizer

Fit a vocabulary + idf table on a corpus, then transform documents to vectors.

Mirrors the fit/transform shape of familiar vectorizer APIs, but stays numpy + stdlib only, matching the "tf * smoothed-idf" formula documented in :func:tfidf_trace.

fit(docs)

Learn the vocabulary and idf weights from docs.

transform(docs)

Map each document in docs to a tf-idf row using the fitted idf.

fit_transform(docs)

Fit on docs then transform them in one call.

SkipGramModel

A tiny skip-gram word2vec model trained with full-softmax SGD.

Parameters:

Name Type Description Default
vocab list[str]

The (deduplicated) vocabulary; row i of both embedding matrices belongs to vocab[i].

required
dim int

Embedding dimensionality.

4
seed int

Seed for the initial embedding matrices.

0

predict(center)

Return P(context | center) over the whole vocabulary.

step(center, context, lr=0.1)

One full-softmax SGD step on a single (center, context) pair.

Returns the cross-entropy loss before the update.

most_similar(word, k=3)

Rank the vocabulary by cosine similarity to word in w_in space.

bpe_trace(corpus, num_merges, encode_word)

Train BPE on corpus and trace each merge round, then encode encode_word.

edit_distance_trace(a, b)

Build the full DP-table + backtrace trace for the Levenshtein distance.

edit_script(a, b)

Return the backtraced edit script turning a into b.

Each element is (op, from_char, to_char) with op in {"match", "substitute", "delete", "insert"}; "-" marks the absent side of an insert/delete.

ngram_trace(train_corpus, test_sentence, n=2, k=1.0)

Fit an n-gram model on train_corpus and trace its PPL on test_sentence.

perplexity(model, corpus)

Convenience wrapper: model.perplexity(corpus).

See :func:optimumai.evaluation.perplexity.perplexity for the general formula applied to a bare list of per-token probabilities; this variant is specific to a fitted :class:NGramModel scoring a corpus of sentences.

tfidf_trace(docs)

Build the full TF, IDF, and weighted-matrix trace for a document set.

skipgram_pairs(corpus, window=1)

Build every (center, context) pair within window of each center word.

word2vec_trace(corpus, window=1, dim=4, steps=20, lr=0.1, seed=0)

Build (center, context) pairs, train a few SGD steps, and trace the whole thing.


Computer vision — optimumai.vision

2-D convolution, pooling, Sobel edge detection, and a tiny CNN forward pass.

Component CLI What it teaches
conv2d optimumai vision conv Sliding filter, output size formula
pool2d optimumai vision pool Max & average pooling
sobel optimumai vision sobel Edge detection via gradient magnitude
cnn_forward optimumai vision cnn Conv → relu → pool stack, shape narrated
from optimumai.vision.convolution import conv2d_trace
from optimumai.vision.pooling import pool2d_trace
import numpy as np

image = np.arange(36).reshape(6, 6).astype(float)
kernel = np.array([[1, 0], [0, -1]], dtype=float)
conv2d_trace(image, kernel).render("beginner")    # output shape (5, 5)
optimumai vision conv
optimumai vision conv "[[1,2],[3,4]]" "[[1,0],[0,-1]]" --stride 1
optimumai vision pool
optimumai vision sobel
optimumai vision cnn --level engineer

optimumai.vision

Computer vision fundamentals — how a CNN sees an image.

2D convolution (the local-pattern detector), pooling (translation-tolerant downsampling), Sobel edge detection (a fixed convolution finding boundaries), and a tiny CNN forward pass (conv -> ReLU -> pool -> flatten -> dense -> softmax) that ties the others together and headlines the tensor-shape story.

cnn_forward(image, kernel, dense_weights, dense_bias, pool_size=2)

Run one image through conv -> ReLU -> max-pool -> flatten -> dense -> softmax.

cnn_forward_trace(image, kernel, dense_weights, dense_bias, pool_size=2)

Build the full trace of a tiny CNN forward pass, headlined by shape flow.

dense(flat, weights, bias)

A fully-connected layer: logits = weights @ flat + bias.

relu(z)

Elementwise max(0, z) — zero out negative activations, keep the rest.

conv2d(x, w, stride=1, padding=0, mode='cross-correlate')

Slide kernel w over image x and return the output feature map.

mode="cross-correlate" (default) is what every deep learning framework calls "convolution": no kernel flip. mode="convolve" flips the kernel 180° first, matching the classical signal-processing definition.

conv2d_trace(x, w, stride=1, padding=0, mode='cross-correlate')

Build the full trace of sliding w over x, window by window.

sobel_edges(x, padding=1)

Return (magnitude, orientation) gradient maps for image x.

orientation is in radians, from atan2(Gy, Gx) (range (-π, π]).

sobel_edges_trace(x, padding=1)

Build the full trace of Sobel edge detection: Gx, Gy, magnitude, orientation.

avg_pool2d(x, kernel_size=2, stride=None)

Downsample x by averaging each kernel_size×kernel_size window.

max_pool2d(x, kernel_size=2, stride=None)

Downsample x by taking the max of each kernel_size×kernel_size window.

pool2d_trace(x, kernel_size=2, stride=None, how='max')

Build the full trace of pooling x, window by window.


LLM evaluation — optimumai.evaluation

BLEU, ROUGE-N/L, exact match, token-F1, perplexity, calibration (ECE), and a candid faithfulness/hallucination heuristic.

Metric CLI What it measures
bleu optimumai eval bleu N-gram precision + brevity penalty
rouge_n, rouge_l optimumai eval rouge N-gram / LCS recall
perplexity optimumai eval perplexity Model surprise — lower is better
ece optimumai eval calibration Calibration: confidence ≈ accuracy?
faithfulness_score optimumai eval faithfulness Claim-context overlap heuristic
from optimumai.evaluation import bleu, rouge_l, perplexity, ece, faithfulness_score
from optimumai.evaluation.text_metrics import bleu_trace

bleu("the quick brown fox jumps", "the quick brown fox leaps", max_n=1)
bleu_trace("the quick brown fox jumps", "the quick brown fox leaps").render("beginner")
optimumai eval bleu "the quick brown fox jumps" "the quick brown fox leaps" --max-n 1
optimumai eval rouge "the quick brown fox" "the quick brown fox jumps" -n 1
optimumai eval perplexity "[0.5,0.25,0.8]"
optimumai eval calibration
optimumai eval faithfulness

Short strings can score BLEU = 0

With --max-n 4, a short pair may have no 4-gram overlap and score 0.0. Use --max-n 1 or longer text.

optimumai.evaluation

LLM evaluation — how do you score a model's output when there's no single right answer?

Four complementary angles: surface-overlap text metrics (BLEU/ROUGE/F1/EM), intrinsic language-model quality (perplexity), whether a model's stated confidence can be trusted (calibration/ECE), and whether a generated answer stays grounded in its source (a hallucination/faithfulness heuristic — see :mod:optimumai.evaluation.hallucination for why that last one is an educational proxy, not a solved problem).

ece(confidences, correct, n_bins=5)

Return the Expected Calibration Error in [0, 1] (lower is better calibrated).

ece_trace(confidences, correct, n_bins=5)

Build the full ECE trace: bin the predictions, then show each bin's confidence-vs-accuracy gap.

Parameters:

Name Type Description Default
confidences Sequence[float]

The model's stated confidence for each prediction, in [0, 1].

required
correct Sequence[bool]

Whether each prediction was actually correct.

required
n_bins int

Number of equal-width reliability bins (default 5, i.e. 20%-wide bins).

5

faithfulness_score(answer, context)

Return the claim-overlap faithfulness heuristic in [0, 1] (see module docstring).

faithfulness_trace(answer, context)

Build the full trace: which answer tokens are supported by the context, and the score.

Parameters:

Name Type Description Default
answer str

The model's generated answer to score.

required
context str

The source text the answer was supposed to be grounded in (e.g. retrieved documents, a system prompt's reference material).

required

unsupported_spans(answer, context)

Return the answer's content tokens absent from the context's vocabulary.

These are the heuristic's flagged candidates for hallucinated content — treat them as "worth checking," not as confirmed fabrications (see module docstring).

perplexity_trace(probs)

Build the full trace: per-token surprisal → cross-entropy → perplexity.

Parameters:

Name Type Description Default
probs Iterable[float]

The probability the model assigned to the actual next token at each position (i.e. p(tokenᵢ | tokens_{<i}) for the ground truth sequence), one value per token. Must be in (0, 1].

required

bleu(candidate, reference, max_n=4)

Return the BLEU score of candidate against reference in [0, 1].

bleu_trace(candidate, reference, max_n=4)

Build the full BLEU trace: per-order clipped precision, then the brevity penalty.

exact_match(candidate, reference)

1.0 if the normalized token sequences are identical, else 0.0 (SQuAD-style).

rouge_l(candidate, reference)

Return the ROUGE-L F-measure in [0, 1].

rouge_l_trace(candidate, reference)

Build the ROUGE-L trace: LCS length → recall/precision/F-measure.

rouge_n(candidate, reference, n=1)

Return ROUGE-N recall (the conventionally reported value) in [0, 1].

rouge_n_trace(candidate, reference, n=1)

Build the ROUGE-N trace: recall/precision/F1 of order-n n-gram overlap.

token_f1(candidate, reference)

Return the token-level F1 of candidate against reference in [0, 1].

token_f1_trace(candidate, reference)

Build the token-F1 trace: bag-of-tokens precision/recall/F1 (SQuAD-style).