deepbox/preprocess
Encoders & Vectorizers
Label, one-hot, ordinal, target and multilabel encoders, and count, TF-IDF and hashing text vectorizers.
- Categorical
- Text
Overview
- Encoders accept a tensor or a plain array (
[["cat"], ["dog"]]for 2-D input). Categories are sorted, numbers numerically and strings by code point, unless you passcategories.OrdinalEncodertherefore numbers"low","medium","high"as 1, 2, 0. Passcategories: [["low", "medium", "high"]]to keep your own order. OneHotEncoderreturns a dense tensor by default, andsparse: truereturns aCSRMatrix. Unknown categories throw. UsehandleUnknown: "ignore"(all zeros) forOneHotEncoder, orhandleUnknown: "useEncodedValue"withunknownValueforOrdinalEncoder.TargetEncoder.fitTransformuses cross-fitting withcv: 5folds, so a training row never sees its own target, andsmoothdefaults to 5.transformon new data uses encodings learned from all rows.- Text vectorizers take arrays of strings through
fitText,transformTextandfitTransformText. The default tokenizer lowercases the text and keeps runs of two or more letters, digits or underscores. Options includestopWords,ngramRangeandbinary, andmaxFeaturesonCountVectorizer.
CountVectorizerOptions
typeOptions accepted by CountVectorizer.
type CountVectorizerOptions = TextOptions & { readonly maxFeatures?: number; readonly minDf?: number; readonly maxDf?: number;};HashingVectorizerOptions
typeOptions accepted by HashingVectorizer.
type HashingVectorizerOptions = TextOptions & { readonly nFeatures?: number; readonly norm?: "l1" | "l2" | undefined; readonly alternateSign?: boolean;};TfidfVectorizerOptions
typeOptions accepted by TfidfVectorizer.
type TfidfVectorizerOptions = CountVectorizerOptions & { readonly norm?: "l1" | "l2" | undefined; readonly sublinearTf?: boolean; readonly smoothIdf?: boolean; readonly useIdf?: boolean;};LabelBinarizer
Binarize labels in a one-vs-all fashion.
This transformer creates a binary matrix representation of labels where each class gets its own column. For multi-class problems, this creates a one-hot encoding of the labels.
Time Complexity: - fit: O(n) where n is the number of samples - transform: O(n*k) where k is the number of classes
Space Complexity: O(n*k) for the output matrix
const y = tensor([0, 1, 2, 0, 1]);const binarizer = new LabelBinarizer();const yBin = binarizer.fitTransform(y);// Result shape: [5, 3] with one-hot encodingMembers (6)
constructor(options?: { posLabel?: number; negLabel?: number; sparse?: boolean; sparseOutput?: boolean; })Creates a new LabelBinarizer instance.
classes: Tensor | undefinedThe sorted classes learned during fit (a new tensor on every access), or
undefinedbefore fit.fit(y: EncoderInput1D): thisFit label binarizer to a set of labels.
transform(y: EncoderInput1D): Tensor | CSRMatrixTransform labels to binary matrix.
fitTransform(y: EncoderInput1D): Tensor | CSRMatrixFit binarizer and transform labels in one step.
inverseTransform(Y: Tensor | CSRMatrix): TensorTransform binary matrix back to labels.
LabelEncoder
Encode target labels with value between 0 and n_classes-1.
This transformer encodes categorical labels (strings or numbers) into integers in the range [0, n_classes-1]. It maintains a mapping of unique classes to their integer representations and can reverse the transformation. Classes are sorted: numbers numerically, bigints numerically and strings by Unicode code point (so "B" sorts before "a", as in NumPy).
Time Complexity: - fit: O(n + k log k) where n is the number of samples and k the number of classes - transform: O(n) with O(1) lookup per sample - inverseTransform: O(n)
Space Complexity: O(k) where k is the number of unique classes
import { LabelEncoder } from 'deepbox/preprocess';import { tensor } from 'deepbox/ndarray'; const y = tensor(['cat', 'dog', 'cat', 'bird']);const encoder = new LabelEncoder();encoder.fit(y);const yEncoded = encoder.transform(y); // [1, 2, 1, 0]const yDecoded = encoder.inverseTransform(yEncoded); // ['cat', 'dog', 'cat', 'bird']Members (5)
classes: Tensor | undefinedThe sorted classes learned during fit (a new tensor on every access), or
undefinedbefore fit.fit(y: EncoderInput1D): thisFit label encoder to a set of labels.
transform(y: EncoderInput1D): TensorTransform labels to normalized encoding.
fitTransform(y: EncoderInput1D): TensorFit label encoder and return encoded labels in one step.
inverseTransform(y: EncoderInput1D): TensorTransform integer labels back to original encoding.
MultiLabelBinarizer
Transform multi-label classification data to binary format.
This transformer handles multi-label classification where each sample can belong to multiple classes simultaneously. It creates a binary matrix where each column represents a class and multiple columns can be active (set to 1) for a single sample.
Time Complexity: - fit: O(n*k) where n is samples, k is avg labels per sample - transform: O(n*k*c) where c is total unique classes
Space Complexity: O(n*c) for the output matrix
const y = [['sci-fi', 'action'], ['comedy'], ['action', 'drama']];const binarizer = new MultiLabelBinarizer();const yBin = binarizer.fitTransform(y);// Each row can have multiple 1sMembers (6)
constructor(options?: { sparse?: boolean; sparseOutput?: boolean; classes?: ReadonlyArray<Category>; })Creates a new MultiLabelBinarizer instance.
classes: Tensor | undefinedThe classes in column order (a new tensor on every access), or
undefinedbefore fit.fit(y: ReadonlyArray<ReadonlyArray<Category>>): thisFit multi-label binarizer to label sets.
transform(y: ReadonlyArray<ReadonlyArray<Category>>): Tensor | CSRMatrixTransform label sets to binary matrix.
fitTransform(y: ReadonlyArray<ReadonlyArray<Category>>): Tensor | CSRMatrixFit binarizer and transform label sets in one step.
inverseTransform(Y: Tensor | CSRMatrix): Category[][]Transform binary matrix back to label sets.
OneHotEncoder
Encode categorical features as one-hot numeric array.
This encoder transforms categorical features into a binary one-hot encoding. Each categorical feature with n unique values is transformed into n binary features, with only one active (set to 1) per sample. Categories of each feature are sorted (numbers numerically, strings by Unicode code point) unless given explicitly through the categories option.
Time Complexity: - fit: O(n*m + sum(k_i log k_i)) where n is samples, m is features, k_i the categories of feature i - transform: O(n*m) with O(1) lookup per value, plus O(n * sum(k_i)) to allocate the dense output - Sparse mode avoids the dense allocation, which matters for high-cardinality features
Space Complexity: - Dense: O(n * sum(k_i)) where k_i is unique categories for feature i - Sparse: O(nnz) where nnz is number of non-zero elements
const X = tensor([['red', 'S'], ['blue', 'M'], ['red', 'L']]);const encoder = new OneHotEncoder({ sparse: false });encoder.fit(X);const encoded = encoder.transform(X);// Categories: [blue, red] and [L, M, S]// Result: [[0,1,0,0,1], [1,0,0,1,0], [0,1,1,0,0]]Members (6)
constructor(options?: { sparse?: boolean; sparseOutput?: boolean; handleUnknown?: "error" | "ignore"; drop?: "first" | "if_binary" | null; categories?: CategoriesOption; })Creates a new OneHotEncoder instance.
categories: Category[][] | undefinedThe categories learned for each feature (a copy), or
undefinedbefore fit.fit(X: EncoderInput2D): thisFit OneHotEncoder to X.
transform(X: EncoderInput2D): Tensor | CSRMatrixTransform X using one-hot encoding.
fitTransform(X: EncoderInput2D): Tensor | CSRMatrixFit encoder and transform X in one step.
inverseTransform(X: Tensor | CSRMatrix): TensorConvert one-hot encoded data back to the original categories.
OrdinalEncoder
Encode categorical features as integer array.
This encoder transforms categorical features into ordinal integers. Each feature's categories are mapped to integers [0, n_categories-1] based on their sorted order (or the order of the categories option). Unlike OneHotEncoder, this maintains a single column per feature.
Time Complexity: - fit: O(n*m + sum(k_j log k_j)) where n=samples, m=features, k_j=categories of feature j - transform: O(n*m) with O(1) map lookup per value
Space Complexity: O(m*k) where m=features, k=avg categories per feature
const X = tensor([['low', 'red'], ['high', 'blue'], ['medium', 'red']]);const encoder = new OrdinalEncoder();encoder.fit(X);const encoded = encoder.transform(X);// Result: [[1, 1], [0, 0], [2, 1]] (alphabetically sorted)Members (6)
constructor(options?: { handleUnknown?: "error" | "useEncodedValue"; unknownValue?: number; categories?: CategoriesOption; })Creates a new OrdinalEncoder instance.
categories: Category[][] | undefinedThe categories learned for each feature (a copy), or
undefinedbefore fit.fit(X: EncoderInput2D): thisFit OrdinalEncoder to X.
transform(X: EncoderInput2D): TensorTransform X using ordinal encoding.
fitTransform(X: EncoderInput2D): TensorFit encoder and transform X in one step.
inverseTransform(X: EncoderInput2D): TensorTransform ordinal integers back to original categories.
TargetEncoder
Target-based encoding for categorical features.
Replaces each category with a smoothed mean of the target for that category: (n * categoryMean + smooth * targetMean) / (n + smooth), which pulls rare categories toward the overall target mean. Categories not seen during fit encode as the overall target mean. Features may be numbers, bigints or strings.
fitTransform uses cross-fitting (as scikit-learn does), so the training encoding of a row never uses that row's own target. Rows are assigned to cv folds deterministically (row i goes to fold i % cv).
import { TargetEncoder } from 'deepbox/preprocess'; const enc = new TargetEncoder({ smooth: 10 });enc.fit(tensor([[0],[1],[0],[1],[2]]), tensor([10, 20, 12, 18, 15]));const encoded = enc.transform(tensor([[0],[1],[2]]));Members (7)
constructor(options?: { smooth?: number; cv?: number; })isFitted: booleantargetMean: number | undefinedMean of the training target, used for unseen categories (
undefinedbefore fit).encodings: Array<Map<Category, number>> | undefinedLearned encoding of every category, one map per feature (copies;
undefinedbefore fit).fit(X: EncoderInput2D, y: EncoderInput1D): thisFit the encoder to training data.
transform(X: EncoderInput2D): TensorTransform categorical features to target-encoded values.
fitTransform(X: EncoderInput2D, y: EncoderInput1D): TensorFit and transform in one step using internal cross-fitting (scikit-learn's TargetEncoder.fit_transform behavior): each row's encoding is computed from the OTHER folds, so a row never sees its own target.
CountVectorizer
Convert a collection of text documents to a matrix of token counts.
Implements the bag-of-words model: each document becomes a vector of word counts. The vocabulary is learned from the training data and sorted alphabetically by UTF-16 code unit, which is scikit-learn's order except for rare characters outside the Basic Multilingual Plane. Features whose document frequency is outside [minDf, maxDf] are dropped, then at most maxFeatures of the most frequent terms are kept. Fitting throws a DataValidationError when no term survives.
The result is a dense matrix of the default float dtype; for very large vocabularies use maxFeatures or HashingVectorizer.
import { CountVectorizer } from 'deepbox/preprocess'; const cv = new CountVectorizer();const X = cv.fitTransformText(['hello world', 'hello deepbox world']);// X is a 2D tensor of shape [2, vocabulary_size]Members (8)
constructor(options?: CountVectorizerOptions)vocabulary: ReadonlyMap<string, number>The learned vocabulary mapping each term to its index
fitText(documents: readonly string[]): thisLearn vocabulary from documents.
transformText(documents: readonly string[]): TensorTransform documents to a document-term matrix.
fitTransformText(documents: readonly string[]): TensorLearn vocabulary and return document-term matrix.
getFeatureNames(): string[]Feature names (terms) in vocabulary order
getParams(): Record<string, unknown>Current parameters.
setParams(params: Record<string, unknown>): thisChange parameters.
HashingVectorizer
Convert text documents to a fixed-size feature matrix using the hashing trick.
Unlike CountVectorizer and TfidfVectorizer, HashingVectorizer does not need to build a vocabulary, making it suitable for large-scale or streaming data. Features are token hashes mapped to a fixed number of buckets.
Trade-offs: - No need to fit (stateless transform) - Fixed memory usage regardless of vocabulary size - Cannot retrieve feature names (hash collisions are possible) - Signed hashing (alternateSign) reduces collision bias
The output is a dense [nDocs, nFeatures] matrix, so the default of 2^20 features costs 8 MB per document; choose a smaller nFeatures for many documents.
import { HashingVectorizer } from 'deepbox/preprocess'; const hv = new HashingVectorizer({ nFeatures: 1024 });const X = hv.transformText(['hello world', 'hello deepbox world']);// X is a 2D tensor of shape [2, 1024]Members (6)
constructor(options?: HashingVectorizerOptions)fitText(documents: readonly string[]): thisNo-op, provided so the vectorizer can be used where
fitTextis expected.transformText(documents: readonly string[]): TensorTransform documents to a fixed-size hash feature matrix.
fitTransformText(documents: readonly string[]): TensorAlias for transformText (no fitting needed).
getParams(): Record<string, unknown>Current parameters.
setParams(params: Record<string, unknown>): thisChange parameters.
TfidfVectorizer
Convert a collection of text documents to a TF-IDF feature matrix.
Combines CountVectorizer with TF-IDF weighting. TF-IDF (Term Frequency - Inverse Document Frequency) down-weights terms that appear in many documents and up-weights rare, discriminative terms.
IDF formula: log((1 + n) / (1 + df)) + 1 with smoothIdf (default), or log(n / df) + 1 without it, where n is the number of fitted documents and df the number of documents containing the term. Rows are normalized to unit L2 norm by default. The results match scikit-learn's TfidfVectorizer for the same options.
import { TfidfVectorizer } from 'deepbox/preprocess'; const tfidf = new TfidfVectorizer();const X = tfidf.fitTransformText(['hello world', 'hello deepbox']);// X is a 2D tensor of shape [2, vocabulary_size] with TF-IDF weightsMembers (9)
constructor(options?: TfidfVectorizerOptions)vocabulary: ReadonlyMap<string, number>The learned vocabulary mapping each term to its index
idf: Float64ArrayThe learned IDF vector (all ones when
useIdfis false)fitText(documents: readonly string[]): thisLearn vocabulary and IDF weights from documents.
transformText(documents: readonly string[]): TensorTransform documents to TF-IDF weighted matrix.
fitTransformText(documents: readonly string[]): TensorLearn vocabulary/IDF and return TF-IDF matrix.
getFeatureNames(): string[]Feature names (terms) in vocabulary order
getParams(): Record<string, unknown>Current parameters.
setParams(params: Record<string, unknown>): thisChange parameters.
import { CountVectorizer, OneHotEncoder, OrdinalEncoder, TfidfVectorizer,} from "deepbox/preprocess"; const oneHot = new OneHotEncoder({ handleUnknown: "ignore" }).fit([["cat"], ["dog"], ["cat"]]);console.log(oneHot.transform([["dog"], ["bird"]]).toString()); // "bird" encodes as zeros const ordinal = new OrdinalEncoder({ categories: [["low", "medium", "high"]] });console.log(ordinal.fitTransform([["low"], ["medium"], ["high"]]).toString()); // 0, 1, 2 const tfidf = new TfidfVectorizer();console.log(tfidf.fitTransformText(["deepbox docs", "deepbox ml"]).toString());const counts = new CountVectorizer({ stopWords: "english" });console.log(counts.fitTransformText(["the cat sat", "the cat saw the dog"]).toString());Found a mistake? Open an issue.