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])
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])
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])
LinearRegression
¶
Ordinary least squares via the normal equation.
Example
model = LinearRegression().fit([[1], [2], [3]], [2, 4, 6]) model.predict([[4]]) array([8.])
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])
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 |
required | |
y
|
Integer class labels, shape |
required | |
max_depth
|
int
|
Maximum depth of the fitted tree. |
2
|
criterion
|
str
|
|
'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 |
required | |
k
|
int
|
Number of clusters. |
2
|
max_iters
|
int
|
Safety cap on assign/update rounds. |
10
|
init
|
ndarray | None
|
Optional starting centroids, shape |
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 |
required | |
y_train
|
Training labels, shape |
required | |
x_query
|
A single query point, shape |
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 |
required | |
y
|
Binary labels in |
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 |
required | |
y_train
|
Training labels, shape |
required | |
x_query
|
A single query point, shape |
required |
pca_trace(X, n_components=1)
¶
Build the full center/covariance/eigendecomposition/project trace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
Data, shape |
required | |
n_components
|
int
|
How many top principal components to keep ( |
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.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:astarall search a :class:~optimumai.search.problem.Graphor :class:~optimumai.search.problem.GridWorldfor a route from a start state to a goal state. - Adversarial search (:mod:
optimumai.search.adversarial) — :func:minimaxand :func:alpha_betachoose 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. |
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]]
|
|
heuristics |
dict[State, float]
|
Optional straight-line-style estimates |
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 |
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.
uniform_cost_search(problem, start, 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
¶
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. |
actions |
list[str]
|
Action labels, e.g. |
transition |
ndarray
|
|
reward |
ndarray
|
|
gamma |
float
|
Discount factor, |
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: |
10
|
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 ( |
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.
SkipGramModel
¶
A tiny skip-gram word2vec model trained with full-softmax SGD.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vocab
|
list[str]
|
The (deduplicated) vocabulary; row |
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 |
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. |
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).