Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Evidentlyai Evidently Legacy Generated Features

From Leeroopedia
Revision as of 12:28, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Evidentlyai_Evidently_Legacy_Generated_Features.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Sources
Domains ML Monitoring, Feature Engineering, Framework Architecture
Last Updated 2026-02-14 12:00 GMT

Overview

Defines the core abstract base classes and mixins for the Evidently generated features framework, including GeneratedFeatures, GeneratedFeature, ApplyColumnGeneratedFeature, DataFeature, and the descriptor hierarchy (BaseDescriptor, FeatureDescriptor, GeneralDescriptor, MultiColumnFeatureDescriptor).

Description

This module is the foundational framework for all generated (computed) features in the Evidently legacy pipeline. It establishes the class hierarchy and contracts that all feature implementations must follow.

Core Feature Classes

GeneratedFeatures is the top-level abstract base class. It defines:

  • generate_features(data, data_definition, options) - Abstract method that must return a DataFrame with new feature columns.
  • generate_features_renamed() - Wrapper that renames generated columns using fingerprint-based unique identifiers and reindexes to match the source data.
  • list_columns() - Abstract method returning a list of ColumnName objects identifying the feature's output columns.
  • as_column(subcolumn) - Resolves a specific output column, supporting multi-column features via the subcolumn parameter.
  • Column name management methods (_create_column_name, _extract_subcolumn_name, _create_column) that use the object's fingerprint for globally unique column identification.

GeneratedFeature extends GeneratedFeatures for single-output features. It introduces:

  • generate_feature(data, data_definition) - Simplified abstract method that returns a single-column DataFrame.
  • __feature_type__ - A class variable specifying the ColumnType (Numerical, Categorical, etc.).
  • Automatic implementation of generate_features() that delegates to generate_feature() with an assertion that exactly one column is produced.

FeatureTypeFieldMixin is a Pydantic mixin that moves the feature type from a class variable to an instance field, enabling runtime-configurable feature types.

ApplyColumnGeneratedFeature extends GeneratedFeature for features that apply a per-value transformation to a single column. It requires:

  • column_name - The target column.
  • display_name_template - A class-level format string for generating display names.
  • apply(value) - Abstract method implementing the per-value transformation.

DataFeature extends GeneratedFeature with a generate_data() abstract method returning a pd.Series, plus auto-generated UUID-based naming.

FeatureResult

FeatureResult is a generic dataclass holding the computed feature data for both current and optional reference datasets.

Descriptor Classes

The descriptor classes provide a higher-level API for declaring features:

  • BaseDescriptor - Root descriptor with an optional display_name.
  • FeatureDescriptor - For single-column features; its feature(column_name) method returns a GeneratedFeatures instance. Provides for_column() and on() convenience methods that return a ColumnName.
  • GeneralDescriptor - For features that do not require a column name parameter; its feature() method takes no arguments.
  • MultiColumnFeatureDescriptor - For features operating on multiple columns; its feature(columns) method accepts a list of column names. Provides for_columns() and on() convenience methods.

Usage

This module is not used directly for feature computation. Instead, it serves as the base framework that all concrete feature implementations (BERTScoreFeature, ContainsLink, ExactMatchFeature, OOVWordsPercentage, CustomFeature, etc.) and all descriptor classes (CustomColumnEval, ExcludesWords, IncludesWords, etc.) extend. Developers creating new custom features should subclass GeneratedFeature or ApplyColumnGeneratedFeature, and developers creating new descriptors should subclass FeatureDescriptor or GeneralDescriptor.

Code Reference

Source Location

Signature

@dataclasses.dataclass
class FeatureResult(Generic[TEngineDataType]):
    current: TEngineDataType
    reference: Optional[TEngineDataType]


class GeneratedFeatures(EvidentlyBaseModel):
    display_name: Optional[str] = None

    @abc.abstractmethod
    def get_type(self, subcolumn: Optional[str] = None) -> ColumnType: ...
    @abc.abstractmethod
    def generate_features(self, data: pd.DataFrame, data_definition: DataDefinition, options: Options) -> pd.DataFrame: ...
    def generate_features_renamed(self, data: pd.DataFrame, data_definition: DataDefinition, options: Options) -> pd.DataFrame: ...
    @abc.abstractmethod
    def list_columns(self) -> List[ColumnName]: ...
    def as_column(self, subcolumn: Optional[str] = None) -> ColumnName: ...


class GeneratedFeature(GeneratedFeatures):
    __feature_type__: ClassVar[ColumnType]

    @abc.abstractmethod
    def generate_feature(self, data: pd.DataFrame, data_definition: DataDefinition) -> pd.DataFrame: ...
    def generate_features(self, data, data_definition, options) -> pd.DataFrame: ...
    def list_columns(self) -> List[ColumnName]: ...
    @abc.abstractmethod
    def _as_column(self) -> ColumnName: ...
    def get_type(self, subcolumn=None): ...


class FeatureTypeFieldMixin(BaseModel):
    feature_type: ColumnType
    def get_type(self, subcolumn=None): ...


class ApplyColumnGeneratedFeature(GeneratedFeature):
    display_name_template: ClassVar[str]
    column_name: str

    @abc.abstractmethod
    def apply(self, value: Any): ...
    def generate_feature(self, data, data_definition) -> pd.DataFrame: ...
    def _as_column(self) -> ColumnName: ...


class DataFeature(GeneratedFeature):
    display_name: str
    name: str = Field(default_factory=lambda: str(uuid6.uuid7()))

    @abc.abstractmethod
    def generate_data(self, data: pd.DataFrame, data_definition: DataDefinition) -> pd.Series: ...
    def generate_feature(self, data, data_definition) -> pd.DataFrame: ...
    def _as_column(self) -> ColumnName: ...


class BaseDescriptor(EvidentlyBaseModel):
    display_name: Optional[str] = None


class GeneralDescriptor(BaseDescriptor):
    @abc.abstractmethod
    def feature(self) -> GeneratedFeatures: ...
    def as_column(self) -> ColumnName: ...


class MultiColumnFeatureDescriptor(BaseDescriptor):
    def feature(self, columns: List[str]) -> GeneratedFeature: ...
    def for_columns(self, columns: List[str]) -> ColumnName: ...
    def on(self, columns: List[str]) -> ColumnName: ...


class FeatureDescriptor(BaseDescriptor):
    @abc.abstractmethod
    def feature(self, column_name: str) -> GeneratedFeatures: ...
    def for_column(self, column_name: str) -> ColumnName: ...
    def on(self, column_name: str) -> ColumnName: ...

Import

from evidently.legacy.features.generated_features import GeneratedFeatures
from evidently.legacy.features.generated_features import GeneratedFeature
from evidently.legacy.features.generated_features import ApplyColumnGeneratedFeature
from evidently.legacy.features.generated_features import DataFeature
from evidently.legacy.features.generated_features import FeatureTypeFieldMixin
from evidently.legacy.features.generated_features import FeatureResult
from evidently.legacy.features.generated_features import BaseDescriptor
from evidently.legacy.features.generated_features import FeatureDescriptor
from evidently.legacy.features.generated_features import GeneralDescriptor
from evidently.legacy.features.generated_features import MultiColumnFeatureDescriptor

I/O Contract

Inputs

GeneratedFeatures.generate_features():

Name Type Required Description
data pd.DataFrame Yes The source DataFrame to compute features from.
data_definition DataDefinition Yes The data definition describing column types and roles.
options Options Yes Configuration options for feature generation.

GeneratedFeature.generate_feature():

Name Type Required Description
data pd.DataFrame Yes The source DataFrame to compute the feature from.
data_definition DataDefinition Yes The data definition describing column types and roles.

ApplyColumnGeneratedFeature.apply():

Name Type Required Description
value Any Yes A single cell value from the target column.

FeatureDescriptor.feature():

Name Type Required Description
column_name str Yes The column to generate features for.

Outputs

Name Type Description
generate_features() return pd.DataFrame A DataFrame with one or more new feature columns.
generate_feature() return pd.DataFrame A single-column DataFrame with the computed feature.
apply() return Any The transformed value for a single cell.
list_columns() return List[ColumnName] A list of ColumnName objects identifying the feature's output columns.
as_column() return ColumnName A ColumnName reference for use in metrics and tests.
feature() return GeneratedFeatures A GeneratedFeatures instance ready for computation.

Usage Examples

import pandas as pd
from evidently.legacy.features.generated_features import (
    GeneratedFeature, ApplyColumnGeneratedFeature, FeatureDescriptor
)
from evidently.legacy.core import ColumnType
from evidently.legacy.base_metric import ColumnName
from evidently.legacy.utils.data_preprocessing import DataDefinition
from typing import ClassVar, Any

# Example: Creating a custom feature by subclassing ApplyColumnGeneratedFeature
class TextLengthFeature(ApplyColumnGeneratedFeature):
    __feature_type__: ClassVar = ColumnType.Numerical
    display_name_template: ClassVar = "Text Length for {column_name}"

    def __init__(self, column_name: str):
        super().__init__(column_name=column_name)

    def apply(self, value: Any):
        if value is None:
            return 0
        return len(str(value))

# Example: Creating a descriptor for the custom feature
class TextLengthDescriptor(FeatureDescriptor):
    def feature(self, column_name: str):
        return TextLengthFeature(column_name=column_name)

# Using the descriptor
descriptor = TextLengthDescriptor()
column_ref = descriptor.on("response_text")

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment