This package generates recommendation list for elequent models objects. It provides a simple API to work with to generate and list recommendations for a model.
composer require "umutphp/laravel-model-recommendation"
php artisan vendor:publish --provider="Umutphp\LaravelModelRecommendation\ModelRecommendationServiceProvider"
php artisan migrate
Append the following line to the providers
array in config/app.php
;
Umutphp\LaravelModelRecommendation\ModelRecommendationServiceProvider::class,
Add HasRecommendation
trait and InteractWithRecommendation
interface to the class definition of the model. Please do not forget to implement the config function of the interface.
getRecommendationConfig()
: It should returns a multi dimensional array as follows with correct values. The definition of values in inner arrays are;
db_relation
and similarity
for now. Some of the other keys are mandatory according to the choice.db_relation
algorithm is choosen.db_relation
algorithm is choosen. The array will contain fields and values as key-value pairs.db_relation
algorithm is choosen.db_relation
algorithm is choosen.db_relation
algorithm is choosen.asc
, desc
, random
. It is optional and the default value from config file is used instead.color
, material
for a product model etc.).category
=> name
). You should use empty string as the value if your taxonomy is in a simple field (tag
=> ''
). 1
as the default value is used instead to make all the calculations are in equal weight.1
as the default value is used instead to make all the calculations are in equal weight.1
as the default value is used instead to make all the calculations are in equal weight.A sample model class definition is as follows;
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Umutphp\LaravelModelRecommendation\InteractWithRecommendation;
use Umutphp\LaravelModelRecommendation\HasRecommendation;
class ModelName extends Model implements InteractWithRecommendation
{
use HasFactory, HasRecommendation;
public static function getRecommendationConfig() :array
{
return [
'recommendation_name' => [
'recommendation_algorithm' => 'db_relation',
'recommendation_data_table' => 'recommendation_data_table',
'recommendation_data_table_filter' => [
'field' => 'value'
],
'recommendation_data_field' => 'recommendation_data_field',
'recommendation_data_field_type' => 'recommendation_data_field_type',
'recommendation_group_field' => 'recommendation_group_field',
'recommendation_count' => 5,
'recommendation_order' => 'desc'
]
];
}
}
Here are a few short examples of what you can do.
ModelName::generateRecommendations('recommendation_name');
$recommendations = $model->getRecommendations('recommendation_name');
For these functions (generateRecommendations() and getRecommendations()) to be executed correctly, you should implement the config function described in Add The Trait And Interface To The Model section. The methods used to generate the recommendations and some use cases thay may help you are explained below.
This is an item based filtering (collaborative filtering) method by using the co-occurrence of the models in a data table under same group defined with a field.
Inspired from the great articale "Building a Product Recommender System with Machine Learning in Laravel" by Oliver Lundquist.
The recommendation list is generated from a similarity calculation between models by using the field and taxonomy values of the objects.
Assume that you want to get recommendations for products (sold together) in an e-commerce site. You have Product
model and order_products
table storing the relation between orders and products.
order_products table;
Field1 | Field2 | Field3 | Field4 | Field5 | Field6 |
---|---|---|---|---|---|
id | order_id | product_id | product_count | created_at | updated_at |
Product model class;
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Umutphp\LaravelModelRecommendation\InteractWithRecommendation;
use Umutphp\LaravelModelRecommendation\HasRecommendation;
class Product extends Model implements InteractWithRecommendation
{
use HasFactory, HasRecommendation;
public static function getRecommendationConfig() :array
{
return [
'sold_together' => [
'recommendation_algorithm' => 'db_relation',
'recommendation_data_table' => 'order_products',
'recommendation_data_table_filter' => [],
'recommendation_data_field' => 'product_id',
'recommendation_data_field_type' => self::class,
'recommendation_group_field' => 'order_id',
'recommendation_count' => 5
]
];
}
}
Function calls;
<?php
...
use App\Model\Product;
Product::generateRecommendations('sold_together');
$product1 = Product::find(1);
$recommendations = $product1->getRecommendations('sold_together');
Assume that you want to get recommendations for users in a dating site. You have User
model and user_friends
table storing the relation between users.
user_friends table;
Field1 | Field2 | Field3 | Field4 | Field5 |
---|---|---|---|---|
id | user_id | friend_id | created_at | updated_at |
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Umutphp\LaravelModelRecommendation\InteractWithRecommendation;
use Umutphp\LaravelModelRecommendation\HasRecommendation;
class User extends Model implements InteractWithRecommendation
{
use HasFactory, HasRecommendation;
public static function getRecommendationConfig() :array
{
return [
'possible_match' => [
'recommendation_algorithm' => 'db_relation',
'recommendation_data_table' => 'user_friends',
'recommendation_data_table_filter' => [],
'recommendation_data_field' => 'friend_id',
'recommendation_data_field_type' => self::class,
'recommendation_group_field' => 'user_id',
'recommendation_count' => 5
]
];
}
}
Function calls;
<?php
...
use App\Model\User;
User::generateRecommendations('possible_match');
$user1 = User::find(1);
$recommendations = $user1->getRecommendations('possible_match');
A use case for generating recommendations from product similarity. We have products
and category
table as follows and a one-to-one relation between them.
products table;
Field1 | Field2 | Field3 | Field4 | Field5 |
---|---|---|---|---|
id | color | material | price | category_id |
category table;
Field1 | Field2 |
---|---|
id | name |
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Umutphp\LaravelModelRecommendation\InteractWithRecommendation;
use Umutphp\LaravelModelRecommendation\HasRecommendation;
class Product extends Model implements InteractWithRecommendation
{
use HasFactory, HasRecommendation;
public static function getRecommendationConfig() :array
{
return [
'similar_products' => [
'recommendation_algorithm' => 'similarity',
'similarity_feature_weight' => 1,
'similarity_numeric_value_weight' => 1,
'similarity_numeric_value_high_range' => 1,
'similarity_taxonomy_weight' => 1,
'similarity_feature_attributes' => [
'material', 'color'
],
'similarity_numeric_value_attributes' => [
'price'
],
'similarity_taxonomy_attributes' => [
[
'category' => 'name'
]
],
'recommendation_count' => 2,
'recommendation_order' => 'desc'
]
];
}
/**
* Get the category associated with the product.
*/
public function category()
{
return $this->hasOne(Category::class);
}
}
A hybrid use case (Use case 2 + Use case 3) containing both of the algorithms.
products table;
Field1 | Field2 | Field3 | Field4 | Field5 |
---|---|---|---|---|
id | color | material | price | category_id |
category table;
Field1 | Field2 |
---|---|
id | name |
order_products table;
Field1 | Field2 | Field3 | Field4 | Field5 | Field6 |
---|---|---|---|---|---|
id | order_id | product_id | product_count | created_at | updated_at |
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Umutphp\LaravelModelRecommendation\InteractWithRecommendation;
use Umutphp\LaravelModelRecommendation\HasRecommendation;
class Product extends Model implements InteractWithRecommendation
{
use HasFactory, HasRecommendation;
public static function getRecommendationConfig() :array
{
return [
'sold_together' => [
'recommendation_algorithm' => 'db_relation',
'recommendation_data_table' => 'order_products',
'recommendation_data_table_filter' => [],
'recommendation_data_field' => 'product_id',
'recommendation_data_field_type' => self::class,
'recommendation_group_field' => 'order_id',
'recommendation_count' => 5,
'recommendation_order' => 'random'
],
'similar_products' => [
'recommendation_algorithm' => 'similarity',
'similarity_feature_weight' => 1,
'similarity_numeric_value_weight' => 1,
'similarity_numeric_value_high_range' => 1,
'similarity_taxonomy_weight' => 1,
'similarity_feature_attributes' => [
'material', 'color'
],
'similarity_numeric_value_attributes' => [
'price'
],
'similarity_taxonomy_attributes' => [
[
'category' => 'name'
]
],
'recommendation_count' => 2,
'recommendation_order' => 'desc'
]
];
}
/**
* Get the category associated with the product.
*/
public function category()
{
return $this->hasOne(Category::class);
}
}
A use case for using with Laravel Follow package (User follow unfollow system for Laravel).
Laravel Follow package stores the data in user_follower
table (Please check the migration). So, the implementation of the config function should be as follows;
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Umutphp\LaravelModelRecommendation\InteractWithRecommendation;
use Umutphp\LaravelModelRecommendation\HasRecommendation;
class User extends Model implements InteractWithRecommendation
{
use HasFactory, HasRecommendation;
public static function getRecommendationConfig() :array
{
return [
'users_to_be_followed' => [
'recommendation_algorithm' => 'db_relation',
'recommendation_data_table' => 'user_follower',
'recommendation_data_table_filter' => [],
'recommendation_data_field' => 'following_id',
'recommendation_data_field_type' => self::class,
'recommendation_group_field' => 'follower_id',
'recommendation_count' => 5
]
];
}
}
Function calls;
<?php
...
use App\Model\User;
User::generateRecommendations('users_to_be_followed');
$user1 = User::find(1);
$recommendations = $user1->getRecommendations('users_to_be_followed');
A use case for using with Laravel Acquaintances package (to manage friendships (with groups), followships along with Likes, favorites etc.).
Laravel Acquaintances package stores the data in interactions
table (Please check the migration). So, the implementation of the config function should be as follows;
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Umutphp\LaravelModelRecommendation\InteractWithRecommendation;
use Umutphp\LaravelModelRecommendation\HasRecommendation;
class User extends Model implements InteractWithRecommendation
{
use HasFactory, HasRecommendation;
public static function getRecommendationConfig() :array
{
return [
'users_to_follow' => [
'recommendation_algorithm' => 'db_relation',
'recommendation_data_table' => 'interactions',
'recommendation_data_table_filter' => [
'relation' => 'follow' // possible values are follow/like/subscribe/favorite/upvote/downvote. Choose the one that you want to generate the recommendation for.
],
'recommendation_data_field' => 'subject_id',
'recommendation_data_field_type' => self::class,
'recommendation_group_field' => 'user_id',
'recommendation_count' => 5
]
];
}
}
Function calls;
<?php
...
use App\Model\User;
User::generateRecommendations('users_to_follow');
$user1 = User::find(1);
$recommendations = $user1->getRecommendations('users_to_follow');
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.