Table of contents :

Build a recommendation system using Recombee and PHP

Recombee x PHP

Table of contents :

Recombee is a recommender that offers personalized search & recommendations for e-commerce, media, and other industries. It uses machine learning algorithms to analyze user behavior, preferences, and interactions in order to provide relevant and accurate suggestions. With Recombee, businesses can improve their customer experience by offering personalized product recommendations based on each individual’s browsing history, purchase history, and interests. This helps increase customer engagement and satisfaction, ultimately leading to higher sales and revenue.

If you wish to learn more about Recombee, you can check out our full review.

In this guide, we will learn how to build a recommendation system using Recombee and PHP.

 

Discover it live on our demo for Recombee

But first let’s whet our appetite with several live Recombee recommendation widgets (items-to-item, items-to-user): top categories, top products, flash sales, frequently bougth together, related products:

Image wpsolr-recombee-demo.png of Build a recommendation system using Recombee and PHP

Getting started with Recombee and initializing the project

Create a Recombee account at the following : https://oauth.recombee.com/ and initialize your database.

You can then set up the project directory.

We will create the project directory using :

mkdir ~/Documents/recombee_php_project
cd ~/Documents/recombee_php_project

Parse the example dataset (if you already have your own data, skip this step)

For the purpose of this guide, we will use an existing dataset containing TechCrunch posts.

You can download it from this page and it will be stored in your download directory as “archive.zip”.

You can then create the directory containing the dataset and unzip the CSV file into it :

mkdir dataset
unzip ~/Downloads/archive.zip -d dataset/

In a php file (in the project directory), you can add the following code :

<?php

$dataset_file_path = 'dataset/techcrunch_posts.csv';
$number_of_lines = 20;
$data = parse_csv($dataset_file_path, $number_of_lines);

function parse_csv(string $file_path, int $number_of_lines) {

    
    $parsed_data = [];
    $property_names = [];
    $line = 0;
    $num_properties = 0;
    
    // Open the CSV file
    $file_contents = fopen($file_path, "r");
    
    // Parse the lines of the CSV file
    while (($data = fgetcsv($file_contents, null, ",")) !== FALSE) {
        
        /**
         * If first line, get the property names and store them in an array
         */
        if (0 === $line){

            $num_properties = count($data);
            
            for ($i=0; $i < $num_properties; $i++) {

                // If property name is 'Id', get it's position.
                if ('id' === strtolower($data[$i])){
                    $id_position = $i;
                }
                // Else add the property name to the array
                $property_names[] = $data[$i];   
            }
        }
        /**
         * Else get the property values and store them in the $parsed_data array
         */
        else {
    
            // If an id property exists in the CSV file, set it's value. 
            if (isset($id_position)){
                $id = $data[$id_position];
            }
            // If not set the id value is the current line
            else {
                $id = $line;
            }
            
            // Store all the values in the parsed_data array
            for ($i=0; $i < $num_properties; $i++) {
                // If is not the id
                if (!isset($id_position) || $i !== $id_position){
                    $parsed_data[$id][$property_names[$i]] = $data[$i];
                }
            }

            /**
             * If reached line limit, end the parsing
             */
            if ($line >= $number_of_lines){
                break;
            }
    
            $id = null;
        }
    
        $line++;
    }

    return ['properties' => $property_names, 'values' => $parsed_data];
}

This program will parse the ‘techcrunch_posts.csv’ file and return an array :

  • in the first position is an array containing all the property names to add to Recombee.
  • in the second position is an array containing the first 20 items to import into to Recombee with all their respective properties. If you wish to change which dataset to import, you can modify the value of $dataset_file_path; if you whish to change the number of lines to import, you can modify the value $number_of_lines.

You can view the parsed data by adding the following lines :

$number_of_lines = 1;

$data = parse_csv($dataset_file_path, $number_of_lines);
echo json_encode($data);

It will return the following JSON :

{
   "properties":[
      "authors",
      "category",
      "content",
      "date",
      "id",
      "img_src",
      "section",
      "tags",
      "title",
      "topics",
      "url"
   ],
   "values":{
      "1401293":{
         "authors":"Dale Chang",
         "category":"Startups",
         "content":"\n\nTech investing isn\u2019t what it used to be \u2014 even compared to six months ago.\nInvestors are applying greater scrutiny to deals.",
         "date":"2016-10-15",
         "img_src":"https:\/\/tctechcrunch2011.files.wordpress.com\/2015\/04\/shutterstock_94007068.jpg?w=738",
         "section":"startups\/",
         "tags":"data",
         "title":"How startups can use data to grow smarter",
         "topics":"",
         "url":"https:\/\/techcrunch.com\/2016\/10\/15\/how-startups-can-use-data-to-grow-smarter\/"
      }
   }
}

The ‘properties’ array holds property names like authors, category, and content, crucial for generating item properties. Within the ‘values’ array are multiple arrays, each representing an item. Here, only data for one item is shown due to the $number_of_lines variable being set to one, specifically the item with the ‘1401293’ id.

The dataset has now been correctly formatted to be sent to Recombee using PHP. We will learn how to setup the Recombee PHP client next.

Install the Recombee PHP API client

Ensure that composer is installed.

You can find the Recombee PHP API client in the official github repository.

As detailed in the Github repository, all you need to do is create a composer.json file in your project directory :

touch composer.json
echo "{
    "require": {
        "recombee/php-api-client": "^4.1.1"
    }
}" > composer.json

You can now install the packages using :

composer install

After executing this command, the Recombee PHP client will have been installed.

Connect to the Recombee API

You can connect to your Recombee API using their PHP client, by adding the following lines to the script :

require_once 'vendor/autoload.php';
use Recombee\RecommApi\Client;
use Recombee\RecommApi\Requests as Reqs;

$client = new Client('your API identifier', 'your private token', ['region' => 'your-region']);

The $client variable will be used by each following function/method to connect to your Recombee database. The values in the Client object are placeholders. You can find your own values to add in the Recombee dashboard.

You can learn more about this in the official documentation.

Add items to Recombee

Before importing the items into Recombee, you need to create the item properties.

To do that, you can add the following code in the PHP file :

recombee_create_item_properties($client, $data['properties']);

function recombee_create_item_properties($client, $property_names){
    foreach ($property_names as $property){
        /**
         * To avoid : PHP Fatal error:  Uncaught Recombee\RecommApi\Exceptions\ResponseException: {"message": "Property name \"Id\" is a reserved keyword!"}
         * Do not send the id property
        */
        if ('id' !== strtolower($property)){
            $client->send(new Reqs\AddItemProperty($property, 'string'));
        }
    }
}

This will add all the item properties to your Recombee database. It will also ensure that the id property will not be created in Recombee, since it is reserved.

Once the properties have been created, you can import the items by adding the following code :

recombee_send_items($client, $data['values']);

function recombee_send_items(object $client, array $data){
    

    foreach ($data as $id => $line) {

        $client->send(new Reqs\SetItemValues("$id",
            $line,
            [
                "cascadeCreate" => true
            ]
        ));

    }

}

For each item in the dataset, a new item will be created in the Recombee database (using the ‘cascadeCreate’ parameter) with the corresponding property values.

You can now verify that the items have been correctly created in the Recombee dashboard :

Recombee dashboard - The items have been created

 

For this and all the following examples, you could use batch processing for increased perfomance but it is not the focus of this guide.

You can learn more about sending items in the official documentation.

Add users to Recombee

It is now important to import the users into Recombee. But first, you will need to create the properties.

In our case, all we need to add is the ‘username’ property, so you can add the following code :

recombee_add_user_properties($client, 'username');

function recombee_add_user_properties(object $client, string $user_property){
    $client->send(new Reqs\AddUserProperty($user_property, 'string'));
}

Now we can send the users from the dataset to Recombee. They can be found in the ‘authors’ columns in the dataset. You can add the following lines in your PHP file :

recombee_send_user($client, $data['values'], 'authors', 'username');

function recombee_send_user(object $client, array $data, string $users_column_name, string $user_property_name){
    $userid = 1;
    foreach ($data as $line){
        foreach ($line as $property_name => $property_value){
            
            if ($property_name === $users_column_name){
                

                // Each item could have multiple authors
                foreach (str_getcsv($property_value, ',') as $user){
                    
                    $user_already_exists = $client->send(new Reqs\ListUsers(['filter' => '\'' . $user_property_name . '\' == "' . $user . '"']));
                    if (empty($user_already_exists)){
                        $client->send(new Reqs\SetUserValues("$userid", 
                            [$user_property_name => $user], 
                            [
                            'cascadeCreate' => true
                            ])
                        );
                        $userid++;
                    }
                }
                
            }
    
        }
        
    }
}

You can now verify that the users have been created correctly in the Recombee dashboard :

Recombee dashboard - The items have been created

You can learn more about sending items in the official documentation.

Send interactions

Let’s consider that the user ‘Dale Chang’ (user id ‘1’) viewed three posts : “ComplyAdvantage raises $8.2M Series A to help firms manage compliance” (item id ‘1400646’), “Soylent Bars recalled after some customers get sick” (item id ‘1401205’) and “Pinterest hits 150M monthly users, missing earlier leaked projections in 2015” (item id ‘1401338’).

You can send the detailed view interactions using :

recombee_send_detailed_view_interaction($client, '1', '1400646');
recombee_send_detailed_view_interaction($client, '1', '1401205');
recombee_send_detailed_view_interaction($client, '1', '1401338');


function recombee_send_detailed_view_interaction(object $client, string $user_id, string $item_id){
    $client->send(new Reqs\AddDetailView($user_id, $item_id, ['timestamp' => time(), 'cascadeCreate' => true]));  
}

You can learn more about sending interactions in the official documentation.

Recommend items to user

If you wish to get personalized recommendations for a specific user (id ‘1’), you can add the following lines :

echo json_encode(recombee_recommend_items_to_user($client, '1', 10));

function recombee_recommend_items_to_user(object $client, string $user_id, int $number_items){
    return $client->send(new Reqs\RecommendItemsToUser($user_id, $number_items, ['cascadeCreate' => true]));
}

A JSON string similar to the follwoing will be returned :

{
   "recommId":"9ba000479a69298064538661b367c154",
   "recomms":[
      {
         "id":"1401954"
      },
      {
         "id":"1401248"
      },
      {
         "id":"1390023"
      },
      {
         "id":"1401633"
      },
      {
         "id":"1401629"
      },
      {
         "id":"1401338"
      },
      {
         "id":"1401293"
      },
      {
         "id":"1401284"
      },
      {
         "id":"1401205"
      },
      {
         "id":"1401193"
      }
   ],
   "numberNextRecommsCalls":0
}

The Recombee recommendation has returned the following ids in the correct positions. You can then use them to get each item’s respective data and display them in the frontend to the users.

You can learn more about getting recommendations in the official documentation.

Trending posts