Skip to content

Context Aware

ContextAwareRecommender

A context-aware recommender system that adapts recommendations based on contextual factors.

This recommender system incorporates contextual information to provide more relevant recommendations by adjusting feature weights based on the current context. It considers various contextual factors such as time, location, user state, and other environmental variables to modify the importance of different item features.

Attributes:

Name Type Description
context_factors Dict[str, Dict]

Mapping of context factors to their value-specific weights. Format: { "factor_name": { "value": { "feature": weight } } }

item_features Dict[int, Dict]

Mapping of item IDs to their feature dictionaries. Format: { item_id: { "feature_name": value } }

feature_weights Dict[str, float]

Current active feature weights based on context.

Methods:

Name Description
update_context

Updates the current context and recalculates feature weights.

recommend

Generates recommendations considering the current context.

_initialize_feature_weights

Initializes weights based on context.

_encode_item_features

Encodes and weights item features.

Source code in engines/contentFilterEngine/context_personalization/context_aware.py
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
class ContextAwareRecommender:
    """
    A context-aware recommender system that adapts recommendations based on contextual factors.

    This recommender system incorporates contextual information to provide more relevant 
    recommendations by adjusting feature weights based on the current context. It considers
    various contextual factors such as time, location, user state, and other environmental 
    variables to modify the importance of different item features.

    Attributes:
        context_factors (Dict[str, Dict]): Mapping of context factors to their value-specific weights.
            Format: {
                "factor_name": {
                    "value": {
                        "feature": weight
                    }
                }
            }
        item_features (Dict[int, Dict]): Mapping of item IDs to their feature dictionaries.
            Format: {
                item_id: {
                    "feature_name": value
                }
            }
        feature_weights (Dict[str, float]): Current active feature weights based on context.

    Methods:
        update_context: Updates the current context and recalculates feature weights.
        recommend: Generates recommendations considering the current context.
        _initialize_feature_weights: Initializes weights based on context.
        _encode_item_features: Encodes and weights item features.
    """

    def __init__(
        self, 
        context_config_path: str, 
        item_features: Dict[int, Dict[str, Any]]
    ):
        """
        Initialize the context-aware recommender with a configuration file for context factors and item features.

        Parameters:
        - context_config_path (str): Path to the JSON configuration file for context factors and weights.
        - item_features (dict): A dictionary of item features.
        """
        self.context_factors = self._load_context_config(context_config_path)
        self.item_features = item_features
        self.user_profiles = defaultdict(lambda: defaultdict(float))
        self.feature_weights = self._initialize_feature_weights()

    def _load_context_config(self, config_path: str) -> Dict[str, Any]:
        """
        Load context factors and their configurations from a JSON file.

        Parameters:
        - config_path (str): Path to the JSON configuration file.

        Returns:
        - Dict[str, Any]: Configuration for context factors.
        """
        if not os.path.exists(config_path):
            raise FileNotFoundError(f"Configuration file not found: {config_path}")
        with open(config_path, 'r') as file:
            config = json.load(file)
        return config

    def _initialize_feature_weights(self, current_context: Optional[Dict[str, Any]] = None) -> Dict[str, float]:
        """
        Initialize and calculate feature weights based on the current context.

        This method processes the current context to determine appropriate weights for different
        item features. It combines weights from multiple context factors when they affect the
        same feature.

        Args:
            current_context (Optional[Dict[str, Any]]): Dictionary containing current context
                information. Keys are context factor names, values are the current factor values.
                If None, uses default context.

        Returns:
            Dict[str, float]: Dictionary mapping feature names to their calculated weights
                based on the current context.

        Example:
            >>> context = {"time": "evening", "location": "home"}
            >>> recommender._initialize_feature_weights(context)
            {"genre_action": 1.2, "genre_drama": 0.8, "length": 1.5}
        """
        weights = {}
        context = current_context or self.context_factors.get("default", {})
        for factor, value in context.items():
            factor_config = self.context_factors.get(factor, {})
            value_weights = factor_config.get(str(value), {})
            for feature, weight in value_weights.items():
                weights[feature] = weight
        return weights

    def _encode_item_features(self, item_id: int) -> Dict[str, float]:
        """
        Encode item features into a weighted feature vector based on current context.

        This method transforms an item's raw features into a weighted feature representation,
        applying the current context-dependent weights. It handles both categorical and
        numerical features appropriately.

        Args:
            item_id (int): The unique identifier of the item to encode.

        Returns:
            Dict[str, float]: Dictionary containing the encoded and weighted features.
                For categorical features: {feature_name_value: weight}
                For numerical features: {feature_name: value * weight}

        Example:
            >>> recommender._encode_item_features(123)
            {"genre_action": 1.2, "duration": 90.5, "rating": 4.5}

        Note:
            - Categorical features are encoded as separate binary features
            - Numerical features are scaled by their corresponding weights
        """
        features = self.item_features.get(item_id, {})
        encoded = {}
        for feature, value in features.items():
            key = f"{feature}_{value}" if isinstance(value, str) else feature
            weight = self.feature_weights.get(key, 1.0)
            if isinstance(value, str):
                encoded[key] = weight
            else:
                encoded[feature] = value * weight
        return encoded

    def fit(self, data: Dict[int, List[int]]):
        """
        Train the recommender system by building user profiles based on their interactions.

        Parameters:
        - data (dict): The data used for training the model, containing user interactions.
        """
        for user_id, items in data.items():
            for item_id in items:
                encoded_features = self._encode_item_features(item_id)
                for feature, value in encoded_features.items():
                    self.user_profiles[user_id][feature] += value

    def recommend(
        self, 
        user_id: int, 
        context: Optional[Dict[str, Any]] = None, 
        top_n: int = 10
    ) -> List[int]:
        """
        Generate top-N item recommendations for a given user considering context.

        Parameters:
        - user_id (int): The ID of the user.
        - context (dict, optional): The current context to consider. If provided, updates context factors.
        - top_n (int): The number of recommendations to generate.

        Returns:
        - List[int]: List of recommended item IDs.
        """
        if context:
            self.feature_weights = self._initialize_feature_weights(context)
        else:
            self.feature_weights = self._initialize_feature_weights()

        user_profile = self.user_profiles.get(user_id, {})
        if not user_profile:
            return []

        scores = {}
        interacted_items = set()
        # Collect all items the user has interacted with to exclude them from recommendations
        interacted_items = user_profile.get('interacted_items', set())

        for item_id, features in self.item_features.items():
            if item_id in interacted_items:
                continue
            encoded_features = self._encode_item_features(item_id)
            score = 0.0
            for feature, value in encoded_features.items():
                score += user_profile.get(feature, 0.0) * value
            scores[item_id] = score

        # Sort items based on the computed scores in descending order
        ranked_items = sorted(scores.items(), key=lambda x: x[1], reverse=True)

        # Return the top-N item IDs
        return [item_id for item_id, score in ranked_items[:top_n]]

__init__(context_config_path, item_features)

Initialize the context-aware recommender with a configuration file for context factors and item features.

Parameters: - context_config_path (str): Path to the JSON configuration file for context factors and weights. - item_features (dict): A dictionary of item features.

Source code in engines/contentFilterEngine/context_personalization/context_aware.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def __init__(
    self, 
    context_config_path: str, 
    item_features: Dict[int, Dict[str, Any]]
):
    """
    Initialize the context-aware recommender with a configuration file for context factors and item features.

    Parameters:
    - context_config_path (str): Path to the JSON configuration file for context factors and weights.
    - item_features (dict): A dictionary of item features.
    """
    self.context_factors = self._load_context_config(context_config_path)
    self.item_features = item_features
    self.user_profiles = defaultdict(lambda: defaultdict(float))
    self.feature_weights = self._initialize_feature_weights()

fit(data)

Train the recommender system by building user profiles based on their interactions.

Parameters: - data (dict): The data used for training the model, containing user interactions.

Source code in engines/contentFilterEngine/context_personalization/context_aware.py
139
140
141
142
143
144
145
146
147
148
149
150
def fit(self, data: Dict[int, List[int]]):
    """
    Train the recommender system by building user profiles based on their interactions.

    Parameters:
    - data (dict): The data used for training the model, containing user interactions.
    """
    for user_id, items in data.items():
        for item_id in items:
            encoded_features = self._encode_item_features(item_id)
            for feature, value in encoded_features.items():
                self.user_profiles[user_id][feature] += value

recommend(user_id, context=None, top_n=10)

Generate top-N item recommendations for a given user considering context.

Parameters: - user_id (int): The ID of the user. - context (dict, optional): The current context to consider. If provided, updates context factors. - top_n (int): The number of recommendations to generate.

Returns: - List[int]: List of recommended item IDs.

Source code in engines/contentFilterEngine/context_personalization/context_aware.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
def recommend(
    self, 
    user_id: int, 
    context: Optional[Dict[str, Any]] = None, 
    top_n: int = 10
) -> List[int]:
    """
    Generate top-N item recommendations for a given user considering context.

    Parameters:
    - user_id (int): The ID of the user.
    - context (dict, optional): The current context to consider. If provided, updates context factors.
    - top_n (int): The number of recommendations to generate.

    Returns:
    - List[int]: List of recommended item IDs.
    """
    if context:
        self.feature_weights = self._initialize_feature_weights(context)
    else:
        self.feature_weights = self._initialize_feature_weights()

    user_profile = self.user_profiles.get(user_id, {})
    if not user_profile:
        return []

    scores = {}
    interacted_items = set()
    # Collect all items the user has interacted with to exclude them from recommendations
    interacted_items = user_profile.get('interacted_items', set())

    for item_id, features in self.item_features.items():
        if item_id in interacted_items:
            continue
        encoded_features = self._encode_item_features(item_id)
        score = 0.0
        for feature, value in encoded_features.items():
            score += user_profile.get(feature, 0.0) * value
        scores[item_id] = score

    # Sort items based on the computed scores in descending order
    ranked_items = sorted(scores.items(), key=lambda x: x[1], reverse=True)

    # Return the top-N item IDs
    return [item_id for item_id, score in ranked_items[:top_n]]