From 66b73fd80461a8fc271ee4dc2a93bcd9bca12332 Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:46:55 +0100 Subject: [PATCH 1/8] added docstring, typehints also made function into 1-liner --- .../matrix_factorization.py | 65 ++++++++++++++----- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index 108c7b0e..a17d7e70 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -16,24 +16,60 @@ class Constants: class MatrixFactorization: + """ + This class implements a Matrix Factorization model, commonly used in recommendation systems + and collaborative filtering. It decomposes a matrix into the product of two lower-dimensional matrices, + capturing latent factors in the data. + + Attributes: + l2_lambda (float): Regularization parameter for L2 regularization. + l2_intercept_multiplier (float): Multiplier for the intercept in L2 regularization. + initLearningRate (float): Initial learning rate for the optimizer. + noInitLearningRate (float): Learning rate used when no initial values are provided. + convergence (float): Convergence threshold for the training process. + numFactors (int): Number of latent factors to model. + useGlobalIntercept (bool): Flag to use a global intercept in the model. + logging (bool): Enable or disable logging. + flipFactorsForIdentification (bool): Adjust factors for model identification. + model (BiasedMatrixFactorization, optional): An instance of a biased matrix factorization model. + featureCols (List[str]): Feature columns to use in the model. + labelCol (str): Label column in the data. + useSigmoidCrossEntropy (bool): Use sigmoid cross-entropy loss if True, else mean squared error loss. + posWeight (optional): Positive weight parameter for the loss function. + + Methods: + get_final_train_error(): Returns the final training error after model fitting. + get_new_mf_with_same_args(): Creates a new instance of MatrixFactorization with the same configuration. + _initialize_note_and_rater_id_maps(ratings): Initializes mappings for note and rater IDs based on the provided ratings DataFrame. + get_note_and_rater_id_maps(ratings): Extracts and returns mappings for note and rater IDs along with processed rating features and labels. + _initialize_parameters(): Initializes or resets the model parameters with given initial values or defaults. + _get_parameters_from_trained_model(): Retrieves parameters from the trained model for analysis or further use. + _create_mf_model(): Initializes the matrix factorization model and its parameters. + _compute_and_print_loss(): Computes and logs the loss during training, useful for monitoring model performance. + _create_train_validate_sets(): Splits the data into training and validation sets for model fitting. + _fit_model(): Executes the model training process, adjusting parameters to minimize the loss. + prepare_features_and_labels(): Prepares features and labels from the dataset for model training. + run_mf(): Main method to run matrix factorization on provided data, returning trained model parameters and performance metrics. + _flip_factors_for_identification(): Adjusts factor sign for model identifiability and interpretation. + """ + def __init__( self, - l2_lambda=0.03, - l2_intercept_multiplier=5, - initLearningRate=0.2, - noInitLearningRate=1.0, - convergence=1e-7, - numFactors=1, - useGlobalIntercept=True, - logging=True, - flipFactorsForIdentification=True, + l2_lambda: float = 0.03, + l2_intercept_multiplier: int = 5, + initLearningRate: float = 0.2, + noInitLearningRate: float = 1.0, + convergence: float = 1e-7, + numFactors: float = 1, + useGlobalIntercept: bool = True, + logging: bool = True, + flipFactorsForIdentification: bool = True, model: Optional[BiasedMatrixFactorization] = None, featureCols: List[str] = [c.noteIdKey, c.raterParticipantIdKey], labelCol: str = c.helpfulNumKey, - useSigmoidCrossEntropy=False, - posWeight=None, - ) -> None: - """Configure matrix factorization note ranking.""" + useSigmoidCrossEntropy: bool = False, + posWeight: Optional[float] = None, + ) -> None: self._l2_lambda = l2_lambda self._l2_intercept_multiplier = l2_intercept_multiplier self._initLearningRate = initLearningRate @@ -72,8 +108,7 @@ def __init__( self.trainModelData: Optional[ModelData] = None self.validateModelData: Optional[ModelData] = None - def get_final_train_error(self) -> Optional[float]: - return self.train_errors[-1] if self.train_errors else None + def get_final_train_error(self) -> Optional[float]: return self.train_errors[-1] if self.train_errors else None def get_new_mf_with_same_args(self): return MatrixFactorization( From 4652a59da2c77e8ba8ed0d761b83d88b145cf0d6 Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:49:18 +0100 Subject: [PATCH 2/8] updated naming convention to follow snake_case --- .../matrix_factorization.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index a17d7e70..c1d90cd6 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -24,8 +24,8 @@ class MatrixFactorization: Attributes: l2_lambda (float): Regularization parameter for L2 regularization. l2_intercept_multiplier (float): Multiplier for the intercept in L2 regularization. - initLearningRate (float): Initial learning rate for the optimizer. - noInitLearningRate (float): Learning rate used when no initial values are provided. + init_lr (float): Initial learning rate for the optimizer. + noinit_lr (float): Learning rate used when no initial values are provided. convergence (float): Convergence threshold for the training process. numFactors (int): Number of latent factors to model. useGlobalIntercept (bool): Flag to use a global intercept in the model. @@ -57,8 +57,8 @@ def __init__( self, l2_lambda: float = 0.03, l2_intercept_multiplier: int = 5, - initLearningRate: float = 0.2, - noInitLearningRate: float = 1.0, + init_lr: float = 0.2, + noinit_lr: float = 1.0, convergence: float = 1e-7, numFactors: float = 1, useGlobalIntercept: bool = True, @@ -72,8 +72,8 @@ def __init__( ) -> None: self._l2_lambda = l2_lambda self._l2_intercept_multiplier = l2_intercept_multiplier - self._initLearningRate = initLearningRate - self._noInitLearningRate = noInitLearningRate + self._init_lr = init_lr + self._noinit_lr = noinit_lr self._convergence = convergence self._numFactors = numFactors self._useGlobalIntercept = useGlobalIntercept @@ -114,8 +114,8 @@ def get_new_mf_with_same_args(self): return MatrixFactorization( l2_lambda=self._l2_lambda, l2_intercept_multiplier=self._l2_intercept_multiplier, - initLearningRate=self._initLearningRate, - noInitLearningRate=self._noInitLearningRate, + init_lr=self._init_lr, + noinit_lr=self._noinit_lr, convergence=self._convergence, numFactors=self._numFactors, useGlobalIntercept=self._useGlobalIntercept, @@ -281,10 +281,10 @@ def _create_mf_model( if (noteInit is not None) and (userInit is not None): self.optimizer = torch.optim.Adam( - self.mf_model.parameters(), lr=self._initLearningRate + self.mf_model.parameters(), lr=self._init_lr ) # smaller learning rate else: - self.optimizer = torch.optim.Adam(self.mf_model.parameters(), lr=self._noInitLearningRate) + self.optimizer = torch.optim.Adam(self.mf_model.parameters(), lr=self._noinit_lr) if self._logging: print(self.mf_model.device) self.mf_model.to(self.mf_model.device) From 0f443bb49f65775efa11cbe3fe64374967b0621a Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 12:59:37 +0100 Subject: [PATCH 3/8] removed hardcoded values --- .../matrix_factorization.py | 109 ++++++++++-------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index c1d90cd6..ac0ec8b7 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -1,3 +1,4 @@ +import os import dataclasses from typing import List, Optional, Tuple @@ -8,6 +9,12 @@ import pandas as pd import torch +import json + +current_file_path = os.path.dirname(os.path.abspath(__file__)) +config_path = os.path.join(current_file_path, "config.json") +with open(config_path) as json_file: + config = json.load(json_file) @dataclasses.dataclass class Constants: @@ -27,15 +34,15 @@ class MatrixFactorization: init_lr (float): Initial learning rate for the optimizer. noinit_lr (float): Learning rate used when no initial values are provided. convergence (float): Convergence threshold for the training process. - numFactors (int): Number of latent factors to model. - useGlobalIntercept (bool): Flag to use a global intercept in the model. + num_factors (int): Number of latent factors to model. + use_global_intercept (bool): Flag to use a global intercept in the model. + use_sigmoid_crossentropy (bool): Use sigmoid cross-entropy loss if True, else mean squared error loss. logging (bool): Enable or disable logging. - flipFactorsForIdentification (bool): Adjust factors for model identification. + flip_factor_identification (bool): Adjust factors for model identification. model (BiasedMatrixFactorization, optional): An instance of a biased matrix factorization model. - featureCols (List[str]): Feature columns to use in the model. - labelCol (str): Label column in the data. - useSigmoidCrossEntropy (bool): Use sigmoid cross-entropy loss if True, else mean squared error loss. - posWeight (optional): Positive weight parameter for the loss function. + feature_cols (List[str]): Feature columns to use in the model. + label_col (str): Label column in the data. + pos_weight (optional): Positive weight parameter for the loss function. Methods: get_final_train_error(): Returns the final training error after model fitting. @@ -55,49 +62,49 @@ class MatrixFactorization: def __init__( self, - l2_lambda: float = 0.03, - l2_intercept_multiplier: int = 5, - init_lr: float = 0.2, - noinit_lr: float = 1.0, - convergence: float = 1e-7, - numFactors: float = 1, - useGlobalIntercept: bool = True, - logging: bool = True, - flipFactorsForIdentification: bool = True, + l2_lambda: float, + l2_intercept_multiplier: int, + init_lr: float, + noinit_lr: float, + convergence: float, + num_factors: int, + use_global_intercept: bool, + use_sigmoid_crossentropy: bool, + logging: bool, + flip_factor_identification: bool, model: Optional[BiasedMatrixFactorization] = None, - featureCols: List[str] = [c.noteIdKey, c.raterParticipantIdKey], - labelCol: str = c.helpfulNumKey, - useSigmoidCrossEntropy: bool = False, - posWeight: Optional[float] = None, + feature_cols: List[str] = [c.noteIdKey, c.raterParticipantIdKey], + label_col: str = c.helpfulNumKey, + pos_weight: Optional[float] = None, ) -> None: self._l2_lambda = l2_lambda self._l2_intercept_multiplier = l2_intercept_multiplier self._init_lr = init_lr self._noinit_lr = noinit_lr self._convergence = convergence - self._numFactors = numFactors - self._useGlobalIntercept = useGlobalIntercept + self._num_factors = num_factors + self._use_global_intercept = use_global_intercept self._logging = logging - self._flipFactorsForIdentification = flipFactorsForIdentification - self._featureCols = featureCols - self._labelCol = labelCol - self._useSigmoidCrossEntropy = useSigmoidCrossEntropy - self._posWeight = posWeight - - if self._useSigmoidCrossEntropy: - if self._posWeight: + self._flip_factor_identification = flip_factor_identification + self._feature_cols = feature_cols + self._label_col = label_col + self._use_sigmoid_crossentropy = use_sigmoid_crossentropy + self._pos_weight = pos_weight + + if self._use_sigmoid_crossentropy: + if self._pos_weight: if logging: - print(f"Using pos weight: {self._posWeight} with BCEWithLogitsLoss") + print(f"Using pos weight: {self._pos_weight} with BCEWithLogitsLoss") self.criterion = torch.nn.BCEWithLogitsLoss( - pos_weight=torch.Tensor(np.array(self._posWeight)) + pos_weight=torch.Tensor(np.array(self._pos_weight)) ) else: if logging: print("Using BCEWithLogitsLoss") self.criterion = torch.nn.BCEWithLogitsLoss() else: - if self._posWeight: - raise ValueError("posWeight is not supported for MSELoss") + if self._pos_weight: + raise ValueError("pos_weight is not supported for MSELoss") self.criterion = torch.nn.MSELoss() self.train_errors: List[float] = [] @@ -117,13 +124,13 @@ def get_new_mf_with_same_args(self): init_lr=self._init_lr, noinit_lr=self._noinit_lr, convergence=self._convergence, - numFactors=self._numFactors, - useGlobalIntercept=self._useGlobalIntercept, + num_factors=self._num_factors, + use_global_intercept=self._use_global_intercept, logging=self._logging, - flipFactorsForIdentification=self._flipFactorsForIdentification, + flip_factor_identification=self._flip_factor_identification, model=None, - featureCols=self._featureCols, - labelCol=self._labelCol, + feature_cols=self._feature_cols, + label_col=self._label_col, ) def _initialize_note_and_rater_id_maps( @@ -147,7 +154,7 @@ def get_note_and_rater_id_maps( """ # We are extracting only the subset of note data from the ratings data frame that is needed to # run matrix factorization. This avoids accidentally losing data through `dropna`. - noteData = ratings[self._featureCols + [self._labelCol]] + noteData = ratings[self._feature_cols + [self._label_col]] assert not pd.isna(noteData).values.any(), "noteData must not contain nan values" raterIdMap = ( @@ -199,10 +206,10 @@ def _initialize_parameters( np.expand_dims(noteInit[c.internalNoteInterceptKey].astype(np.float32).values, axis=1) ) - for i in range(1, self._numFactors + 1): + for i in range(1, self._num_factors + 1): noteInit[c.note_factor_key(i)].fillna(0.0, inplace=True) self.mf_model.note_factors.weight.data = torch.tensor( - noteInit[[c.note_factor_key(i) for i in range(1, self._numFactors + 1)]] + noteInit[[c.note_factor_key(i) for i in range(1, self._num_factors + 1)]] .astype(np.float32) .values ) @@ -217,10 +224,10 @@ def _initialize_parameters( np.expand_dims(userInit[c.internalRaterInterceptKey].astype(np.float32).values, axis=1) ) - for i in range(1, self._numFactors + 1): + for i in range(1, self._num_factors + 1): userInit[c.rater_factor_key(i)].fillna(0.0, inplace=True) self.mf_model.user_factors.weight.data = torch.tensor( - userInit[[c.rater_factor_key(i) for i in range(1, self._numFactors + 1)]] + userInit[[c.rater_factor_key(i) for i in range(1, self._num_factors + 1)]] .astype(np.float32) .values ) @@ -246,7 +253,7 @@ def _get_parameters_from_trained_model(self) -> Tuple[pd.DataFrame, pd.DataFrame c.internalRaterInterceptKey ] = self.mf_model.user_intercepts.weight.data.cpu().numpy() - for i in range(self._numFactors): + for i in range(self._num_factors): noteParams[c.note_factor_key(i + 1)] = self.mf_model.note_factors.weight.data.cpu().numpy()[ :, i ] @@ -254,7 +261,7 @@ def _get_parameters_from_trained_model(self) -> Tuple[pd.DataFrame, pd.DataFrame :, i ] - if self._flipFactorsForIdentification: + if self._flip_factor_identification: noteParams, raterParams = self._flip_factors_for_identification(noteParams, raterParams) return noteParams, raterParams @@ -295,8 +302,8 @@ def _instantiate_biased_mf_model(self): self.mf_model = BiasedMatrixFactorization( n_users, n_notes, - use_global_intercept=self._useGlobalIntercept, - n_factors=self._numFactors, + use_global_intercept=self._use_global_intercept, + n_factors=self._num_factors, logging=self._logging, ) if self._logging: @@ -441,7 +448,7 @@ def prepare_features_and_labels( self.ratingFeaturesAndLabels[c.noteIdKey] == specificNoteId ] - rating_labels = torch.FloatTensor(ratingFeaturesAndLabels[self._labelCol].values).to( + rating_labels = torch.FloatTensor(ratingFeaturesAndLabels[self._label_col].values).to( self.mf_model.device ) user_indexes = torch.LongTensor(ratingFeaturesAndLabels[Constants.raterIndexKey].values).to( @@ -492,7 +499,7 @@ def run_mf( assert self.mf_model.note_factors.weight.data.cpu().numpy().shape[0] == self.noteIdMap.shape[0] globalIntercept = None - if self._useGlobalIntercept: + if self._use_global_intercept: globalIntercept = self.mf_model.global_intercept if self._logging: print("Global Intercept: ", globalIntercept.item()) @@ -517,7 +524,7 @@ def _flip_factors_for_identification( Returns: Tuple[pd.DataFrame, pd.DataFrame]: noteParams, raterParams """ - for i in range(1, self._numFactors + 1): + for i in range(1, self._num_factors + 1): noteFactorName = c.note_factor_key(i) raterFactorName = c.rater_factor_key(i) From 7d97c545a10962438774057c257241468b831791 Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:06:56 +0100 Subject: [PATCH 4/8] removed json import --- .../scoring/matrix_factorization/matrix_factorization.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index ac0ec8b7..7fc4ac7d 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -9,13 +9,6 @@ import pandas as pd import torch -import json - -current_file_path = os.path.dirname(os.path.abspath(__file__)) -config_path = os.path.join(current_file_path, "config.json") -with open(config_path) as json_file: - config = json.load(json_file) - @dataclasses.dataclass class Constants: noteIndexKey = "noteIndex" From 65aa79d2acb55fb9f0ea1c57e547e3a72c6f97d4 Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:09:15 +0100 Subject: [PATCH 5/8] added json config --- .../scoring/matrix_factorization/matrix_factorization.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index 7fc4ac7d..ac0ec8b7 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -9,6 +9,13 @@ import pandas as pd import torch +import json + +current_file_path = os.path.dirname(os.path.abspath(__file__)) +config_path = os.path.join(current_file_path, "config.json") +with open(config_path) as json_file: + config = json.load(json_file) + @dataclasses.dataclass class Constants: noteIndexKey = "noteIndex" From 0aa222055bdefc9bbf73205bb83e4cb8f57058a9 Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:25:40 +0100 Subject: [PATCH 6/8] removed hardcoded arguments and added config.json --- .../scoring/matrix_factorization/config.json | 13 ++++++ .../matrix_factorization.py | 46 +++++++++++-------- 2 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 sourcecode/scoring/matrix_factorization/config.json diff --git a/sourcecode/scoring/matrix_factorization/config.json b/sourcecode/scoring/matrix_factorization/config.json new file mode 100644 index 00000000..b226c372 --- /dev/null +++ b/sourcecode/scoring/matrix_factorization/config.json @@ -0,0 +1,13 @@ +{ + "PARAMS": { + "l2_lambda": 0.03, + "l2_intercept_multiplier": 5, + "init_lr": 0.2, + "noinit_lr": 1.0, + "convergence": 1e-7, + "num_factors": 1, + "use_global_intercept": true, + "logging": true, + "flip_factor_identification": true, + } +} \ No newline at end of file diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index ac0ec8b7..a00a46c8 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -16,6 +16,20 @@ with open(config_path) as json_file: config = json.load(json_file) +CONFIG_PARAMS = config.get("PARAMS", {}) +EXPECTED_TYPES = { + "l2_lambda": float, + "l2_intercept_multiplier": int, + "init_lr": float, + "noinit_lr": float, + "convergence": float, + "num_factors": int, + "use_global_intercept": bool, + "use_sigmoid_crossentropy": bool, + "logging": bool, + "flip_factor_identification": bool +} + @dataclasses.dataclass class Constants: noteIndexKey = "noteIndex" @@ -61,34 +75,26 @@ class MatrixFactorization: """ def __init__( - self, - l2_lambda: float, - l2_intercept_multiplier: int, - init_lr: float, - noinit_lr: float, - convergence: float, - num_factors: int, - use_global_intercept: bool, - use_sigmoid_crossentropy: bool, - logging: bool, - flip_factor_identification: bool, + self, + config = CONFIG_PARAMS, model: Optional[BiasedMatrixFactorization] = None, feature_cols: List[str] = [c.noteIdKey, c.raterParticipantIdKey], label_col: str = c.helpfulNumKey, pos_weight: Optional[float] = None, ) -> None: - self._l2_lambda = l2_lambda - self._l2_intercept_multiplier = l2_intercept_multiplier - self._init_lr = init_lr - self._noinit_lr = noinit_lr - self._convergence = convergence - self._num_factors = num_factors - self._use_global_intercept = use_global_intercept - self._logging = logging + for param, expected_type in EXPECTED_TYPES.items(): + value = config.get(param, CONFIG_PARAMS[param]) + if value is not None and not isinstance(value, expected_type): + try: + value = expected_type(value) + except ValueError: + raise ValueError(f"Parameter {param} is expected to be of type {expected_type.__name__}, but got {type(value).__name__}") + + setattr(self, f"_{param}", value) + self._flip_factor_identification = flip_factor_identification self._feature_cols = feature_cols self._label_col = label_col - self._use_sigmoid_crossentropy = use_sigmoid_crossentropy self._pos_weight = pos_weight if self._use_sigmoid_crossentropy: From 9db09c5a604ad77c4f4f8d9c4cb0b510ed336912 Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:41:08 +0100 Subject: [PATCH 7/8] updated safeload json --- sourcecode/scoring/matrix_factorization/config.json | 2 +- sourcecode/scoring/matrix_factorization/matrix_factorization.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sourcecode/scoring/matrix_factorization/config.json b/sourcecode/scoring/matrix_factorization/config.json index b226c372..0934e4c3 100644 --- a/sourcecode/scoring/matrix_factorization/config.json +++ b/sourcecode/scoring/matrix_factorization/config.json @@ -8,6 +8,6 @@ "num_factors": 1, "use_global_intercept": true, "logging": true, - "flip_factor_identification": true, + "flip_factor_identification": true } } \ No newline at end of file diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index a00a46c8..789ae278 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -83,7 +83,7 @@ def __init__( pos_weight: Optional[float] = None, ) -> None: for param, expected_type in EXPECTED_TYPES.items(): - value = config.get(param, CONFIG_PARAMS[param]) + value = config.get(param, CONFIG_PARAM.get(param)) if value is not None and not isinstance(value, expected_type): try: value = expected_type(value) From 84e26666c60e69d9c031d59f48bc9928745e2e38 Mon Sep 17 00:00:00 2001 From: Jako Rostami <51382407+jakorostami@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:41:48 +0100 Subject: [PATCH 8/8] updated safeload json and typo --- sourcecode/scoring/matrix_factorization/matrix_factorization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sourcecode/scoring/matrix_factorization/matrix_factorization.py b/sourcecode/scoring/matrix_factorization/matrix_factorization.py index 789ae278..9ad184b9 100644 --- a/sourcecode/scoring/matrix_factorization/matrix_factorization.py +++ b/sourcecode/scoring/matrix_factorization/matrix_factorization.py @@ -83,7 +83,7 @@ def __init__( pos_weight: Optional[float] = None, ) -> None: for param, expected_type in EXPECTED_TYPES.items(): - value = config.get(param, CONFIG_PARAM.get(param)) + value = config.get(param, CONFIG_PARAMS.get(param)) if value is not None and not isinstance(value, expected_type): try: value = expected_type(value)