2

Is it possible to remove the pattern cards matched in sitecore by the current user when he navigates back to a specific page programmatically?

Just want to have an idea on how to do this.

Thank you in advance.

2 Answers 2

5

Simple answer

No - there is no way to remove a Pattern matched by the current visitor when the visitor navigates back to a specific page.

How does pattern matching work and why isn't this possible?

Computing Pattern Matches

Pattern matching is based on Euclidean Distance across vectors. This means that Sitecore calculates the pattern that a visitor matches by taking all of the possible patterns, using their configured profile key scores as vectors, using the visitor's interaction scores as vectors, and then deducing which pattern vector has the shortest distance (i.e. is the most similar) to visitor's interaction vector.

In English, this means that Sitecore looks at the visitor's scores, as accumulated from the visitor's interactions with the site, and finds the pattern with the scores that are most similar (often most proportionate).

Why we can't disassociate a visitor from a pattern

Because the matched pattern is always the pattern with the most similar scores to the visitor's interactions, the only way to disassociate a visitor from a pattern is to change the visitor's interaction scores. You have to do this manually, if it is really something that you want to do, and there's no way to really guarantee accuracy, as the computation is based entirely on computing the smallest distance between two vectors.

Think of it this way: assume that you have a visitor with a bunch of scores for a profile, and that the visitor currently matches the Foo pattern. You have an item reference to the Foo pattern (assume from configs or something like that) and you can see what profile key scores are configured for it. How would you remove this pattern from the user? You can remove all of the scores for which the Foo pattern has points, but then you might remove scores for other patterns, as well. You could try removing scores proportionate to Foo's scores in a loop until the visitor no longer matches Foo, but then you may, again, remove scores for other patterns. No matter what you do, here, there is no way to guarantee that you are removing the pattern match from the visitor without affecting other patterns.

How can I attempt to remove a pattern match?

There are two ways to change scores: by increasing them or by decreasing them. It would be very difficult (and bad for performance) to try to accurately roll a visitor back to a specific pattern, but you could back a visitor's scores from specific interactions.

If you store the profile and score values that were associated with each interaction and you know the interaction that you want to roll back to then you should be able to simply roll back all of the scores that were added after that point.

Caution and Recommendation

I do not recommend that you roll back scores or interactions, under any circumstances. When you do that, you are taking good analytics data and tainting it and/or throwing it out, programmatically.

I have had clients and UX team members ask me about doing things like this and it has been my experience that each time they are just trying to use the wrong tool for the job.

If the goal is to personalize and always show the same personalized content to the visitor when they navigate back to the page then add a custom rule for that in Sitecore. Store on the visitor's profile or in session (depending on long-term vs. short term), etc. a value that indicates which rendering you showed previously and add the custom logic to show it on repeat visits before attempting to render the personalized component (you can do this via pipelines or code in your controllers - I recommend pipelines over controllers).

What are we missing in Sitecore that would make this possible?

Pattern exclusions, in concept

In Sitecore, there is currently no concept of "exclusion" with regard to pattern matches for a specific visitor. In other words, there is no way to do something like the following, given that you want to update the visitor to match the closest pattern that is not the Foo pattern:

profile.UpdatePattern(excludedPatterns: new [] { "Foo" });

Conceptually, what the above code would (ideally) do is compute the Euclidean Distance between the visitor's profile, profile, and each of the patterns except for the Foo pattern. This way, analytics data would not have to be modified and you could still ensure that the visitor doesn't match a specific pattern when navigating back to a given page.

Doing this through customization of Sitecore

Before writing this post, I took a look inside the decompiled Sitecore.Analytics assemblies in order to see how difficult it would be to add support for these computations yourself. The answer is that it would be very high effort and risk. You would have to rewrite some pretty large pieces of Sitecore.Analytics in order to do this, so my recommendation is that you instead open a support ticket and request that this feature be added to a future release of Sitecore.

What's wrong with deleting the Interaction records and the Behavior Profiles?

In the solution that @HishaamNamooya posted, he advises that you delete the Interaction records and the Behavior Profiles in order to delete the pattern. That code will do what you are looking for in the same way that an elephant gun can be used to kill a mouse...you'll be doing a lot more damage than you probably intended.

Deleting the interaction records and behavior profiles will remove the Pattern, but it will also obliterate all scores and interactions that the visitor has had with the site in their behavior profiles, and all scores and interactions from the current visit within the profile that contains the pattern you are trying to remove. Effectively, you're throwing out other good data that you probably don't mean to get rid of.

By Example

Consider that you have configured a Profile in Sitecore, named Cars (going to go somewhat 2D, here, for Simplicity's sake). The Cars profile has the following profile keys:

  • Outdoors
  • Manual Labor
  • Power
  • Wealth
  • Family
  • Environment

When a visitor clicks on one of your pages, that page has scores for each of those profile keys that are proportional to how likely the key is to be "important" to the user.

Additionally, assume that you have the following Patterns configured for the Cars profile (generally, I try to go more abstract with pattern names, but the below is meant for demonstration):

  • Pickup
  • All-Terrain
  • Supercar
  • Luxury SUV
  • Minivan
  • Hybrid
  • Luxury Hybrid
  • Sedan

Assume that you have a visitor who browses to a few pages that indicate that they are interested the outdoors and family. Right now, this visitor matches the All-Terrain pattern the closest. The visitor then navigates to a few other pages, indicating a strong interest in manual labor (construction, carpentry, etc.). With this new information added to the visitor's scores, the visitor now matches the Pickup pattern the closest.

Now consider that our site should implement logic as described in the OP. When the visitor navigates back to some specific page, Foo, the visitor's match with the Pickup pattern should be removed. Implicitly, the result is that the visitor should once again be matched with the All-Terrain pattern.

If you achieve this logic by deleting all of the interaction records and behavior profiles then the results will not be as expected. What will actually happen is that you will be erasing everything that you currently know about the user and their interactions, as they relate to the "Cars" profile, including all of their interactions that led up to the match with the All-Terrain pattern, as well as the Pickup pattern. You would be throwing out good data and there would be no way to distinguish between data that matches the Pickup pattern vs data that matches the All-Terrain pattern.

Alternative

What you likely want to do instead is remember the pattern that a visitor had on the specific page. Once you have that, you can work from there to manually override your personalization flow (my recommendation is to do this through a pipeline) to use the stored pattern rather than the visitor's current pattern.

In a situation like this, you could even leverage Sitecore Caching, though I don't recommend that you rely on this alone. If you set your rendering caching options to Vary By User, then the rendered output that was first displayed to the user will be the output that is "always" (until the cache clears) shown to the user. Again, I don't recommend that you solely rely on Sitecore Caching, but if that is the general logic that you're looking to implement then that should point you in the right direction.

In Summary

While Hishaam's solution is more of a blunt object, there really isn't a scalpel that will get you what you want. Regardless, I believe that deleting interactions and behavior profiles is typically a far more drastic solution than what is needed, and will have repercussions that you may not be willing to accept.

My recommendation is that you take a hard look at what you are trying to accomplish and find a different and better way to do so. Ask yourself what it is that you're actually trying to implement and accomplish and then ask the community. I recommend, asking your question in the #sitecore-chat channel of the Sitecore Community Slack to see if other developers and MVPs can help you to brainstorm alternatives. Feel free to direct message me @zachary_kniebel too, if you just want to talk through your thoughts, needs or implementation.

1
  • Thanks for the very informative explanation for this one.
    – Jovit Mayo
    Aug 8, 2017 at 7:55
0

You need to remove the Pattern from both Interaction and BehaviorProfiles. When the user enters the specific page, you need to trigger the methods below.

Remove from the Interaction

Tracker.Current.Interaction.Profiles.Remove("Your Profile Name");

Remove from Behavioral Profile

private static void UpdateBehaviorProfile(Session session)
{
    var profileConverterBase = BehaviorProfileConverterBase.Create();

    if (session?.Contact == null || Tracker.Current.Interaction == null)
    {
        return;
    }

    session.Contact.BehaviorProfiles.RemoveAll();

    foreach (var profileName in session.Interaction.Profiles.GetProfileNames())
    {
        var profile = session.Interaction.Profiles[profileName];

        if (!IgnoreInteractionProfile(profile))
        {
            var matchedBehaviorProfile = profileConverterBase.Convert(profile);

            session.Contact.BehaviorProfiles.Add(matchedBehaviorProfile.Id, matchedBehaviorProfile);
        }
    }
}

private static bool IgnoreInteractionProfile(Profile profile)
{
    Assert.ArgumentNotNull(profile, "profile");

    // Logic goes here whether to add the profile to the contact behavior or not

    return false;
}

Warning

Point to note here is that when removing the pattern from the user profile interaction and behavior, you'll no longer be able to have the values again as it will remove it completely.

5
  • Technically, this doesn't remove the Pattern; it removes the entire interaction record for the given profile and for all behavior profiles. I think this is a lot more extreme than what the OP was asking for and you should probably add some words of caution and explanation to that end. Aug 7, 2017 at 16:35
  • Yeah but based on the OP, it says that he wants to remove a given pattern when a specific page is viewed. So i assume that by remove he means remove completely Aug 7, 2017 at 16:38
  • I hear you, but the code you posted is not just removing the pattern; it's removing the whole profile record. That means that all interactions and scores against that profile are lost. Mouse, meet Elephant Gun. I'm just saying that you need to add some warnings and words of caution about this. I'm about to post an answer with some, myself, along with some additional explanation. Aug 7, 2017 at 16:40
  • 1
    Yeah i got your point now and will add some comments :) Aug 7, 2017 at 16:45
  • You can still have values; you just lose all of the values that you already had and not just for those that are shared with the current pattern, but for all the profile keys in the profile. Have a read through the last two sections of my post ("What's wrong with..." and "In Summary") and I think you will have a better understanding of what I mean. Aug 7, 2017 at 18:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.