Text and embedding features

CatBoost · Advanced · 12 min

Many tabular datasets include free text such as descriptions or reviews; CatBoost can use them without a separate NLP pipeline.

Declare free-text columns with `text_features` (in fit or a Pool), alongside numeric and categorical ones. CatBoost then:

  • tokenizes and builds dictionaries of words or n-grams (`tokenizers` and `dictionaries` options),
  • computes feature calcers from them: BoW (bag of words), NaiveBayes and BM25 scores per class,
  • feeds the resulting numeric features into the trees.

Defaults are sensible; text_processing customises tokenization (lowercasing, separators), dictionary size and occurrence limits, n-grams and calcers. Text features work for classification and regression on CPU; GPU and other losses support fewer options, so check the docs for your setup. Text columns must be strings, with missing values filled (for example with an empty string).

For richer semantics, compute embeddings with a language model (such as a sentence-transformer) and pass each vector column as an `embedding_features` entry. In a DataFrame, one column holds a NumPy array per row. CatBoost derives features from them with LDA and KNN calcers.

Built-in text handling is a cheap, strong baseline for short texts like titles and categories of complaints. For nuanced language, fine-tuned transformers or precomputed embeddings usually win; combining embeddings with the tabular features in CatBoost is a common, effective approach.

Example

import pandas as pd
from catboost import CatBoostClassifier, Pool

reviews = ["great battery life", "screen cracked quickly", "fast and great",
           "terrible battery", "love the screen", "broke after a week",
           "great value", "awful support"] * 30
labels = [1, 0, 1, 0, 1, 0, 1, 0] * 30
df = pd.DataFrame({"review": reviews, "price": [199, 249, 299, 149] * 60})

pool = Pool(df, labels, text_features=["review"])
model = CatBoostClassifier(iterations=100, verbose=0, random_seed=0,
                           allow_writing_files=False)
model.fit(pool)

test = pd.DataFrame({"review": ["great screen", "terrible support"],
                     "price": [199, 199]})
print(model.predict(Pool(test, text_features=["review"])))   # [1 0]
print(model.get_feature_importance(prettified=True).iloc[0, 0])   # review

Remember

  • text_features turns raw text into BoW, NaiveBayes and BM25 features
  • text_processing customises tokenizers, dictionaries and calcers
  • embedding_features accepts precomputed vectors (one array per row)
  • Fill missing text and check task/GPU support for your version

Watch out for

  • Passing a text column as a categorical feature, which treats every distinct sentence as one opaque category.

Check yourself

  1. Why not declare a free-text 'review' column as a categorical feature?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: catboost.ai/docs/en/features/text-features

Builds on

Unlocks

Nothing builds on this yet.

Text and embedding features · CatBoost · Topolearn