> For the complete documentation index, see [llms.txt](https://lucid-ai.gitbook.io/devdocs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lucid-ai.gitbook.io/devdocs/products/recommendation/sample-workflows/video-recommendations.md).

# Video Recommendations

## Configuring entities and interactions

### Entity data model

To train your video recommender, the first step is to define the data available to train on.  The more entities and interactions available, the better the recommendations can be.  Examples of entities that can be used include:

* Videos (movies, episodes, etc.)
* Series info (e.g., the series or season a TV episode is part of)
* Creator
* Genre
* Cast member (actors, directors, writiers, etc.)

In addition, users of your site and their attributes can comprise additional entities:

* Users
* Country
* Demographics (if available)

{% hint style="info" %}
**Note that you don't need to create all of these entities yourself!**  You can just create the basics and supply metadata.  Lucid will read your metadata and generate entities for you.
{% endhint %}

Let's look at what our entity data feed might look like to get our video recommender going:

<table><thead><tr><th width="137">entity_type</th><th width="183">entity_name</th><th>metadata</th></tr></thead><tbody><tr><td>video</td><td>Jurassic Park</td><td>{ "creator": "Universal", "writer": "Michael Crichton", "director": "Steven Spielberg", "release_year": 1993, "genre": "sci-fi", "starring": [...], "description": "..." }</td></tr><tr><td>video</td><td>Lost World</td><td>{ "creator": "Universal", "writer": "David Koepp", "director": "Steven Spielberg", "release_year": 1997, "genre": "sci-fi", "starring": [...], "description": "..." }</td></tr><tr><td>video</td><td>Rick &#x26; Morty S1-1</td><td>{ "season": 1, "episode": 1, "genre": "sci-fi", "creator": "Adult Swim", "starring": [...], "description": "..." }</td></tr><tr><td>video</td><td>Rick &#x26; Morth S1-2</td><td>{ "season": 1, "episode": 2, "genre": "sci-fi", "creator": "Adult Swim", "starring": [...], "description": "..." }</td></tr></tbody></table>

From here, we also need entities and metadata about our users:

<table><thead><tr><th width="139">entity_type</th><th width="181">entity_name</th><th>metadata</th></tr></thead><tbody><tr><td>user</td><td>user_0001</td><td>{ "genre": ["sci-fi", "action"], "country": "United States", city: "San Francisco" }</td></tr><tr><td>user</td><td>user_0002</td><td>{ "genre": ["sci-fi", "romance"], "country": "United States", city: "New York" }</td></tr><tr><td>user</td><td>user_0003</td><td>{ "genre": ["mystery", "action"], "country": "France", city: "Paris" }</td></tr></tbody></table>

Note that we could have broken out the metadata into separate entities, but the Lucid backend will do this automatically.  For example, entities could have been created for countries, genres, or cast members, specifying it in JSON format as metadata is faster.  For complex cases where more control is needed on the interactions between the entities they can be broken out and connected using the interaction table.

### Interaction model

Once the entities are tabulated, the interactions can be listed out.  Interactions for video recommendation may include things like:

* Watched videos
* Favorited videos
* Clicks
* Shares
* Mouse-overs

Forming the interaction model simply involves linking together entities and naming that interaction:

<table><thead><tr><th width="227">source_entity</th><th width="210">interaction_name</th><th width="237">target_entity</th></tr></thead><tbody><tr><td>user_0001</td><td>watched</td><td>Jurassic Park</td></tr><tr><td>user_0001</td><td>clicked</td><td>Lost World</td></tr><tr><td>user_0002</td><td>clicked</td><td>Rick &#x26; Morty S1-2</td></tr><tr><td>user_0003</td><td>watched</td><td>Jurassic Park</td></tr><tr><td>user_0003</td><td>watched</td><td>Rick &#x26; Morty S1-1</td></tr></tbody></table>

## Training the model

Once the entity and interaction tables are created, they can be uploaded to the API through the `data_batch` endpoint.  Be sure to add a tag to the datasets, such as `video-data` to differentiate it from other recommender projects you may start.  You can upload as many entity and interaction tables as needed prior to training the model.

When the data is in place, trigger a training run:

```javascript
POST <your-endpoint>/v1/recommend/train
```

You can optionally include parameters to filter the datasets or to only use interactions from the last 30 or 90 days.  A typical training run will take several minutes, and a callback can be used to get an indication of completion.

## Rolling it out

### Personalized video recommendations for each user

With your trained model you can get out many different types of recommendations and trends.  For example, let's say you want to get the top 100 recommendations for each user.  To do so, you want to query the `/recommended_items` endpoint with the following parameters:

```javascript
{
    "model_id": "<your model id>",
    "entity_type": "user",
    "target_entity_type": "video",
    "max_recommendations": 100,
    "output_format": "csv"
}
```

This query will give you back a large batch of recommendations for all users targeting videos.  Because of the batched approach, you can query the results once and then cache them for fast access on your site or app.

An example of what these results might look like are:

<table><thead><tr><th width="174">entity_id</th><th width="226">recommendation_id</th><th width="81">#</th><th width="144">score</th></tr></thead><tbody><tr><td>user_0001</td><td>Lost World</td><td>1</td><td>0.91</td></tr><tr><td>user_0001</td><td>Rick &#x26; Morty S1-1</td><td>2</td><td>0.86</td></tr><tr><td>user_0001</td><td>Alien</td><td>3</td><td>0.84</td></tr><tr><td>...</td><td>...</td><td>...</td><td>...</td></tr><tr><td>user_0001</td><td>Titanic</td><td>100</td><td>0.61</td></tr><tr><td>user_0002</td><td>Jurassic Park</td><td>1</td><td>0.83</td></tr><tr><td>...</td><td>...</td><td>...</td><td>...</td></tr></tbody></table>

### Recommending series instead of episodes

For video recommendation, it may be better to recommend a series instead of an episode.  For example, it probably doesn't make sense to recommend specific episodes from a 10 season series; either you want to recommend the series as a whole or not.

To enable recommendations at the series level, simply change the `target_entity` parameter from `videos` to `series`.  This requires that all of your video entities have a `series` metadata value, or that you create `series` entities and then link them to your videos using an interaction.  However, doing so will improve the quality of results coming out of the recommender to meet the expected outcome.

### Adding a *Watch Next* feature

You can use the same model to generate a **watch next** feature.  Such a feature recommends similar videos based on a target video.  To get watch-next results, you can use a query like this:

```javascript
{
    "model_id": "<your model id>",
    "entity_type": "video",
    "target_entity_type": "series",
    "max_recommendations": 20,
    "output_format": "csv"
}
```

This will generate 20 recommendations of related series for each video in your dataset.  If you want to generate user-specific watch-next recommendations for a given user and video, you can use the following query:

```javascript
{
    "model_id": "<your model id>",
    "entity_id": ["user_0001", "Jurassic Park"],
    "target_entity_type": "series",
    "max_recommendations": 20,
    "output_format": "json"
}
```

This will generate 20 recommendations for that user related to *Jurassic Park*.  Note that caching all such results in CSV is impractical, so the results are instead generate in JSON form (e.g., this would be a real-time query and not a batched query operation).

### Getting fallback video recommendations

It may be convenient to have some fallback recommendations ready to go for new users that don't yet have any history.  This can help address the cold-start problem but still give quality, localized recommendations.  One method is to query for recommendations based on a user's country:

```javascript
{
    "model_id": "<your model id>",
    "entity_type": "country",
    "target_entity_type": "series",
    "max_recommendations": 100,
    "output_format": "csv"
}
```

Thus, even if you have no information on a user, you can at least geolocate their IP address to get a country, and then serve local favorites as initial recommendations.
