Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add eALS #77

Merged
merged 15 commits into from
Dec 18, 2023
Merged

Add eALS #77

merged 15 commits into from
Dec 18, 2023

Conversation

dkkim1005
Copy link
Contributor

@dkkim1005 dkkim1005 commented Oct 18, 2023

eALS

Element-wise ALS algorithm, dubbed as eALS, is added to the buffalo framework.
(Detailed algorithm flow is presented in "Fast Matrix Factorization for Online Recommendation with Implicit Feedback")

Because eALS is an extended version of ALS, it shares the same interfaces as ALS. One could deploy a code just substituting "ALS" into "EALS". But eALS needs the additional hyperparameters to construct a loss function for training, such as "c0" and "exponent" where "c0" is the strength of the negative feedback and "exponent" is the control parameter of how item popularity affects the user preferences for unseen items(No user-item interactions). User should give hyperparameters "c0" and "exponent" to eALS when an instance is instantiated.

linking BLAS

A BLAS subroutine SSYRK will be called during the training process. Using OpenBLAS is highly recommended so that it is employed as a default setting in setup.py. One can switch from OpenBLAS to any compatible BLAS library that supports multithreading operations.

usecase

eALS supports the same interfaces as ALS. The example code is presented as follows,

import os
from os.path import join as pjoin
from typing import Any, Union

import buffalo
from buffalo.misc import aux


class EALS:
    def __init__(
        self,
        matrix: Union[str, os.PathLike],
        uid_fname: str,
        iid_fname: str,
        D: int = 20,
        **kwargs: Any,
    ):
        data_opt = buffalo.MatrixMarketOptions().get_default_option()
        data_opt.input.main = matrix
        data_opt.input.uid = uid_fname
        data_opt.input.iid = iid_fname
        data_opt.data.value_prepro = aux.Option({'name': 'OneBased'})

        self.data = buffalo.data.load(data_opt)
        self.data.create()
        # Set model option
        self.opt = buffalo.EALSOption().get_default_option()
        self.opt.d = D
        self.opt.num_iters = kwargs.get('iter', 10)
        self.opt.alpha = kwargs.get('alpha', 32.0)
        self.opt.reg_u = kwargs.get('reg_u', 1.0)
        self.opt.reg_i = kwargs.get('reg_i', 1.0)
        self.opt.c0 = kwargs.get('c0', 64)
        self.opt.save_factors = True
        self.opt.exponent = kwargs.get('exponent', 0.5)
        self.opt.compute_loss_on_training = kwargs.get('check_rmse', True)
        self.opt.num_workers = kwargs.get('num_proc', 4)
        self.model = buffalo.EALS(self.opt, data=self.data)
        self.model.initialize()

    def train(self) -> float:
        metrics = self.model.train()
        self.trained = True
        return metrics.get('train_loss', 0.0)


if __name__ == '__main__':
    prefix_for_path='blabla'
    D = 20
    iter = 10
    alpha = 32.0
    reg_u = 1.0
    reg_i = 1.0
    num_proc = 4
    c0 = 64.0
    exponent = 0.5
    model = EALS(
        matrix=pjoin(prefix_for_path, 'test.mm'),
        uid_fname=pjoin(prefix_for_path, 'uid'),
        iid_fname=pjoin(prefix_for_path, 'iid'),
        D=D,
        iter=iter,
        alpha=alpha,
        reg_u=reg_u,
        reg_i=reg_i,
        num_proc=num_proc,
        c0=c0,
        exponent=exponent,
    )

    model.train()

@CLAassistant
Copy link

CLAassistant commented Oct 18, 2023

CLA assistant check
All committers have signed the CLA.

@chiwanpark chiwanpark self-requested a review October 20, 2023 14:49
@ita9naiwa ita9naiwa self-requested a review December 11, 2023 03:34
@ita9naiwa
Copy link
Collaborator

테스트 좀 추가해주실 수 있나요?

@dkkim1005
Copy link
Contributor Author

@ita9naiwa 테스트 코드 추가하였습니다.

@ita9naiwa ita9naiwa merged commit d2d9b19 into kakao:dev Dec 18, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants