Fine-tuning Your Results
Introduction
The following sections provide additional tools and methodologies for tailoring your search and recommendation results to align with your business objectives.
Diversifying your results
To make sure that you increase product discovery, it can be useful to ensure that there's a good diversity of products shown side-by-side.
The diversification
parameter lets you tells Miso's ranking algorithms to try to maintain the desired minimum distance between any two products that have the same attributes (you can specify which attributes). For example, the following query will tell Miso that products with the same brand
should be at least two slots apart from each other in the ranked results.
{
"boost_fq": "tags:\"ON SALE\"",
"diversification": {
"brand": {"minimum_distance": 2}
}
}
Revenue optimization
Miso's default behavior is to optimize for the goals that you set in your engine training. For example, you might want to increase conversions by having your engine suggest products that will lead to more add_to_cart
and checkout
interactions. For many customers, this is enough — but some Miso customers see even better revenue numbers when we trade off conversion rate slightly against other attributes of products, such as price.
To do revenue optimization against the likelihood of conversion, Miso provides an uprank
parameter. For example, if you uprank by price, Miso will not simply rank products by conversion probability, as in the default behavior. Instead, products will be ranked by conversion probability price to the power of* α (alpha), where α is a value between 0 and 1. In essence, this factors price into the ranking to boost products that have a higher price, potentially increasing your average order value. Miso's team will run experiments that find the value for αthat gives you the best revenue returns.
{
"q": *,
"category": ["Ice Cream," "All Pints"]
"uprank": {
"fields": ["price"],
"power": 0.15 // alpha
}
}
Another option is to optimize for margin in addition to price, in order to slightly favor products that give you a higher return. This is an advanced feature, and we recommend consulting with your Miso solutions engineer to learn more.
Tuning your rankings
For each call to a Search API or the Product to Products API, Miso returns a _score
field that contains up to four numbers. Miso's default ranking algorithm is a four-step process. The numbers in the _score
field correspond to the scores that Miso uses to calculate the ranking at each step.
_tie_break_score
field.
-
Search Relevance or
_search_score
: In the first step, Miso generates a score that rates the degree of "match" between search keywords and a product's catalog, with a focus on the product's titles. This score is mostly based on a variant of BM25, but additionally considers the term proximity, typos, and term semantic similarity. Its value is always larger than 0, but its range is unbounded.After calculating the
_search_score
, Miso applies a soft-tie breaking mechanism with a heavier threshold. This means that products with a similar relevancy will be ranked by the boosting score. -
Boosting Score or
_boost_score
: Next, Miso determines whether the product is boosted by yourboost_fq
query. This score is a binary number and can be used to break ties. -
Search Relevance or
_search_score
: Because the product might still be tied with other results after the first two steps, Miso uses the search relevance score again but with a smaller tie-break threshold to do more fine-grained ranking based on the personalization score. -
Personalization Score or
_personalization_score
: Finally, we estimate the probability that a user will interact with a product based on your Miso Search Engine's personalization models. The range of this score is between [0, 1] and scores are non-uniformly distributed. Products that are relevant to the user's interests will have scores much closer to 1 than products that are not.The personalization score is used as the final tie-breaker among scores that are still tied in ranking after the first three steps.
Here is an example of what a potential _score
and _tie_break_score
could look like for your results:
{
"_tie_break_score:" [...] {
"0": "1",
"1": "0",
"2": "5",
"3": "0.61959601656602987"
},
{
"_score:" [...] {
"0": "43.775826",
"1": "0",
"2": "43.775826",
"3": "0.61959601656602987",
}
}
order_by
Changing the default search result ranking with You can override the behavior described above by using the order_by
parameter to specify your own ranking steps and tie-breakers.
For example, the following code tells Miso to use the _personalization_score
to rank the products. Then, In the case of soft ties (as explained below), the tie-breaker will be the custom_attributes.promote_score
field.
{
"order_by": [
{
"field": "_personalization_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.05"
},
"order": "desc"
},
{
"field": "custom_attributes.promote_score",
"order": "desc"
}
]
}
Using Tie-Breakers
For scores that have granular resolutions, for example _personalization_score
,_search_scores
, or products' sale_price
, we usually want to set a threshold where products are considered close enough to be "tied." After all, a 0.001 difference in _personalization_score
or $0.01 difference in sale price typically will not make a difference in users' preferences. Instead, you probably want to default to another field to determine the ranking.
That's why we allow you to specify where this threshold is and when a tie_breaker
is needed for each field that Miso uses for ranking. For example, in the query above, we would consider two products a "soft tie" for ranking purposes if the relative difference between their _personalization_score
is no more than threshold of 0.05
or 5%
. When there is such a tie, the next field (i.e. custom_attributes.promote_score
) will be used to determine their ranking.
It's also common to set a large tie-breaker threshold when you want to combine the effects of two types of scores. For example, in the following query, we set threshold=0.2
or 20%
for _personalization_score
. Then, only the products that users are 20% more likely to interact with will be ranked higher, and the remaining products will be ranked by their sale prices. In this way, we combine the effect of personalization score and sale prices, where the products are roughly ranked by personalization, but favor the pricier products when they have comparable personalization scores.
{
"order_by": [
{
"field": "_personalization_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.20"
},
"order": "desc"
},
{
"field": "sale_price",
"order": "desc"
}
]
}
Also note that, when search keywords are present, it is recommended to always include _search_score
as the first field (plus a tie-breaker) to maintain the relevance of the search results.
{
"q": "toy story",
"order_by": [
{
"field": "_search_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.20"
},
"order": "desc"
},
{
"field": "_personalization_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.20"
},
"order": "desc"
},
{
"field": "sale_price",
"order": "desc"
}
]
}
Enabling partial matches in search
By default, Miso's Search API only returns products that contain all the keywords in the search query (i.e. an AND operator over keywords). This strategy usually leads to highly relevant results.
However, when we don't have enough search results to return to the users, you can tell the API can relax its criteria by setting enable_partial_match_threshold
to an integer value. When the number of products the exact search query matches is lower or equal to that number, Miso will return results that match only some of the keywords. This strategy is particularly useful to avoid users from seeing an empty search results page and abandoning the search.
For example, let's consider the query request below:
{
"query": "Toy story 5",
"enable_partial_match_threshold": 3
}
Since there is no movie called "Toy story 5", we have zero products to return by default. However, because we set enable_partial_match_threshold=3
, we will return other products that partially match the query in the partially_matched_products
field as follows:
{
"data": {
"products": [],
"total": 0,
"partially_matched_products": [
{
"title": "Toy Story",
"_missing_keywords": ["5"]
},
{
"title": "Toy story 2",
"_missing_keywords": ["5"]
},
...
]
}
}
As you can see from the result above, when we don't have the exact products the user is looking for, showing partially_matched_products
is a decent strategy to let them know what alternatives are available, and prevent them from seeing an empty search results page.
Filtering out low-relevance search results
When Miso returns many results for a query, it's likely that the top results are highly relevant. However, if only a few results are available, they may be low relevance but will still appear at the top of the results page. In this case, you may want to exclude these results and show partial matches instead. You have a few criteria that you can use to determine whether your results might be low-relevance:
products[ ]._matched_fields
: By turning onenable_matched_fields
in the API request, Miso will tell you which product fields contained tokens matching the search query. This lets you filter out products where the search query only matched thedescription
field, for example.products[ ]._search_score
: If the score is less than -2, it is not likely to be relevant.- Length of products array: If there are only a few results, you may want to exclude low-relevance results and use partial matches instead.
Tuning the search spellcheck
It's possible to enable auto spelling correction in search only when Miso has high confidence about the correction. The confidence will be a function of edit distance between the query and correction + # of search results + query logs.
{"spellcheck":
{"enable_auto_spelling_correction": "high"}
}
While spellcheck is turned on by default for all queries, you can also disable spellcheck entirely if needed.
{"spellcheck":
{"enable_spellcheck": false}
}