cbrkit.adapt

Adaptation functions for modifying retrieved cases to better suit a query.

This module contains built-in adaptation functions for common data types. Adaptation functions are used in the reuse phase (cbrkit.reuse) to transform retrieved cases before scoring. All adaptation functions follow one of three signatures:

  • Pair: adapted = f(case, query)
  • Map: adapted_casebase = f(casebase, query)
  • Reduce: key, adapted = f(casebase, query)

Submodules:

Top-Level Functions:

Example:
>>> adapter = attribute_value(
...     attributes={
...         "price": numbers.aggregate(pooling="mean"),
...         "color": strings.regex("CASE_PATTERN", "QUERY_PATTERN", "REPLACEMENT"),
...     }
... )
 1"""Adaptation functions for modifying retrieved cases to better suit a query.
 2
 3This module contains built-in adaptation functions for common data types.
 4Adaptation functions are used in the reuse phase (`cbrkit.reuse`) to transform
 5retrieved cases before scoring.
 6All adaptation functions follow one of three signatures:
 7
 8- Pair: `adapted = f(case, query)`
 9- Map: `adapted_casebase = f(casebase, query)`
10- Reduce: `key, adapted = f(casebase, query)`
11
12Submodules:
13- `cbrkit.adapt.numbers`: Numeric adaptation (e.g., `aggregate` with pooling).
14- `cbrkit.adapt.strings`: String adaptation (e.g., `regex` replacement).
15- `cbrkit.adapt.generic`: Generic adaptation functions.
16
17Top-Level Functions:
18- `attribute_value`: Applies per-attribute adaptation functions to
19  attribute-value based cases, analogous to `cbrkit.sim.attribute_value`.
20  Supports nesting for object-oriented data structures.
21
22Example:
23    >>> adapter = attribute_value(
24    ...     attributes={
25    ...         "price": numbers.aggregate(pooling="mean"),
26    ...         "color": strings.regex("CASE_PATTERN", "QUERY_PATTERN", "REPLACEMENT"),
27    ...     }
28    ... )
29"""
30
31from . import generic, numbers, strings
32from .attribute_value import attribute_value
33
34__all__ = [
35    "generic",
36    "strings",
37    "numbers",
38    "attribute_value",
39]
@dataclass(slots=True, frozen=True)
class attribute_value(cbrkit.typing.AdaptationFunc[V], typing.Generic[V]):
17@dataclass(slots=True, frozen=True)
18class attribute_value[V](AdaptationFunc[V]):
19    """Adapt values of attributes using specified adaptation functions.
20
21    This class allows for the adaptation of multiple attributes of a case by applying
22    one or more adaptation functions to each attribute. It supports different data structures
23    like mappings (dictionaries) and dataframes
24
25    Args:
26        attributes: A mapping of attribute names to either single adaptation functions or
27            sequences of adaptation functions that will be applied in order.
28        value_getter: Function to retrieve values from objects. Defaults to dictionary/attribute access.
29        value_setter: Function to set values on objects. Defaults to dictionary/attribute assignment.
30
31    Returns:
32        A new case with adapted attribute values.
33
34    Examples:
35        >>> func = attribute_value({
36        ...     "name": lambda x, y: x if x == y else y,
37        ...     "age": lambda x, y: x if x > y else y,
38        ... })
39        >>> result = func(
40        ...     {"name": "Alice", "age": 30},
41        ...     {"name": "Peter", "age": 25}
42        ... )
43        >>> result
44        {'name': 'Peter', 'age': 30}
45    """
46
47    attributes: Mapping[str, MaybeSequence[SimpleAdaptationFunc[Any]]]
48    value_getter: Callable[[Any, str], Any] = getitem_or_getattr
49    value_setter: Callable[[Any, str, Any], None] = setitem_or_setattr
50
51    @override
52    def __call__(self, case: V, query: V) -> V:
53        for attr_name in self.attributes:
54            adapt_funcs = produce_sequence(self.attributes[attr_name])
55
56            case_attr_value = self.value_getter(case, attr_name)
57            query_attr_value = self.value_getter(query, attr_name)
58
59            for adapt_func in adapt_funcs:
60                case_attr_value = unbatchify_adaptation(adapt_func)(
61                    case_attr_value, query_attr_value
62                )
63
64            self.value_setter(case, attr_name, case_attr_value)
65
66        return case

Adapt values of attributes using specified adaptation functions.

This class allows for the adaptation of multiple attributes of a case by applying one or more adaptation functions to each attribute. It supports different data structures like mappings (dictionaries) and dataframes

Arguments:
  • attributes: A mapping of attribute names to either single adaptation functions or sequences of adaptation functions that will be applied in order.
  • value_getter: Function to retrieve values from objects. Defaults to dictionary/attribute access.
  • value_setter: Function to set values on objects. Defaults to dictionary/attribute assignment.
Returns:

A new case with adapted attribute values.

Examples:
>>> func = attribute_value({
...     "name": lambda x, y: x if x == y else y,
...     "age": lambda x, y: x if x > y else y,
... })
>>> result = func(
...     {"name": "Alice", "age": 30},
...     {"name": "Peter", "age": 25}
... )
>>> result
{'name': 'Peter', 'age': 30}
attribute_value( attributes: Mapping[str, MaybeSequence[SimpleAdaptationFunc[typing.Any]]], value_getter: Callable[[typing.Any, str], typing.Any] = <function getitem_or_getattr>, value_setter: Callable[[typing.Any, str, typing.Any], None] = <function setitem_or_setattr>)
attributes: Mapping[str, MaybeSequence[SimpleAdaptationFunc[typing.Any]]]
value_getter: Callable[[typing.Any, str], typing.Any]
value_setter: Callable[[typing.Any, str, typing.Any], None]