phpjuice / opencf

PHP implementation of the (Weighted Slopeone,Cosine, Weighted Cosine) rating-based collaborative filtering schemes.
https://phpjuice.gitbook.io/opencf
MIT License
94 stars 7 forks source link

Export/Import the recommender object #12

Open imhaggarwal opened 8 months ago

imhaggarwal commented 8 months ago

I was wondering if the time taken to create/train the recommender depends on the number of records. If yes then what if there are billions of records in the dataset which is used to train the recommender service. The training time would be needed every time there is a request.

Is there any anyway to just train once and use the same object on mulitple requests instead of creating a mew object everytime. I thought being able to export and import the object would help in achieving it.

I had one concern with this approach. If its dynamic site whose dataset keeps changing, if it was possible to just update the recommender service model and not create the whole new object.

the-dijkstra commented 8 months ago

Hello thanks for your feedback, acctualy the recommender accepts a second constructor argument for the model, https://github.com/phpjuice/opencf/blob/3f27dfdd08594d95a69682316ad892ed7f274b92/src/Algorithms/Recommender.php#L44

So storing the model in a file or a Redis cache after calculation can be done, and you can import it at request time later without the need to recalculate, I Imagine such a workflow to be like this:


use OpenCF\RecommenderService;
use OpenCF\Algorithms\Slopeone\WeightedSlopeone;

// Training Dataset
$dataset = [
    "squid" => [
        "user1" => 1,
        "user2" => 1,
        "user3" => 0.2,
    ],
    "cuttlefish" => [
        "user1" => 0.5,
        "user3" => 0.4,
        "user4" => 0.9,
    ]
];

// Create a recommender service instance
$recommenderService = new RecommenderService($dataset);

// Retrieve a recommender (Weighted Slopeone)
$recommender = $recommenderService->weightedSlopeone();

// Retrieve a modal and save it to disk/cache
$redis = new Redis(); 
$redis->set('weightedSlopeone:model', $recommender->getModel());

// Retreive a model from cache or disk and build the recommender
$model = $redis->get('weightedSlopeone:model');

// Caveat, you need to build a recommender instance here manually not through recommendation service, since right
// now the interface doesn't account for passing the model to the underlying recommender.
$recommender = new WeightedSlopeone($dataset, $model);
$results = $recommender->predict([
    "squid" => 0.4
]);
robera92 commented 8 months ago

Hello! I can't get this to work. Any ideas what might be wrong? Thank you.

$recommender = new WeightedSlopeone($dataset, $model);
$results = $recommender->predict(['388273' => 0.5]);

Fatal error: Uncaught Error: Typed property OpenCF\Algorithms\Recommender::$predictor must not be accessed before initialization
the-dijkstra commented 8 months ago

Hey @robera92 Thanks for reporting on this, I think this an error on the package it self, since it was not intended in the first place to run recommenders without the recommender service. I will fix and push the new fixes soon.

Again thanks.