Package: marketing-attribution-models
Marketing Attribution Models1. About the ClassPython Class created to address problems regarding Digital Marketing Attribution.2. About Multi-Channel AttributionWhile browsing online, an user has multiple touchpoints before converting, which could lead to ever so longer and more complex journeys.How to duly credit conversions and optmize investment on media?To adress this, we applyAttribution Models.2.1 Attribution ModelsHeuristic Models:Last Interaction:Default attribution in Gogle Analytics and other media platforms such as Google Ads and Facebook Business manager;Only the last touchpoint is credited for the conversion.Last Click Non-Direct:All direct traffic is ignored and so 100% of the result goes to the last channel through which the client got to the website before converting.First Interaction:The result is wholly attributed to the first touchpoint.Linear:Every touchpoint is equally credited.Time Decay:The more recent a touchpoint is, the more credit it gets.Position Based:In this model, 40% of the result is attributed to the last touchpoint, another 40% to the first and the remaining 20% is equally distributed among the midway channels.Algotithmic ModelsShapley ValueUsed in Game Theory, this value is an estimation of the contribution of each individual player in a cooperative game.Conversions are credited to the channels by a process of permutating the journeys. In each permutation a channel is given out to estimate how essencial it is overall.As an example, let's look at the following hypotherical journey:Organic Search > Facebook > Direct >$19(as revenue)To obtain each channel's Shapley Value, we first need to consider all conversion values for the component permutations of this given journey.Organic Search >$7Facebook >$6Direct >$4Organic Search > Facebook >$15Organic Search > Direct >$7Facebook > Direct >$9Organic Search > Facebook > Direct >$19The number of component joneys increases exponentially the more distinct channels you have: The rate is 2^n (2 to the power of n) forn channels.In other words, with 3 distinct touchpoints there are 8 permutations.With over 15, for instance, this process is unfeasible.By default, the order of the touchpoints isn't taken into consideration when calculating the Shapley Value, only their presence or lack there of. In order to do so, the number of permutationsincreases.With that in mind, note that it is pretty difficult to use this model when considering the order of interactions. For n channels, not only there are 2^n permutations of a given channeli, but alsoevery permutation containing i in a different position.Some issues and limitations of Shapley ValueThe number of distinct channels is limited by the exponential nature of the permutations.When not considering the order of the touchpoints, the contribution estimated for channel A is considered the same being it preceded by B or C.If the order is taken into account, the number of combinations skyrockets and if any combination does not exist among the observations the model considers that journey as existent with zero conversions.Touchpoints that are unfrequent or are only present in longer journeys have their contribution underestimated.Markov ChainsA Markov Chain is a particular Stochastic process in which the probability distribution of any next state depends only on what the current state is, disregarding any preceeding states and their sequence.In multichannel attriution, we can use the Markov Chains to calculate the probability of interaction between pairs of media channels with theTransition Matrix.In regard to each channel's contribution in conversions, theRemoval Effectcomes in: For each jorney a given channel is removed and a conversion probability is calculated.The value attributed to a channel, then, is obtained by the ratio of the difference between the probability of conversion in general and the probability once said channel is removed over the general probability again.In other words, the bigger a channel's removal effect, the larger their contribution is.**When working with Markovian Processes there are no restrictions due to the quantity or order of channels. Their sequence, itself, is a fundamental part of the algorithm.2.2 ReferencesAttribution Models in MarketingAttribution Theory: The Two Best Models for Algorithmic Marketing Attribution – Implemented in Apache Spark and RGame Theory Attribution: The Model You’ve Probably Never Heard OfMarketing Channel Attribution With Markov Models In RMulti-Channel Funnels Data-Driven AttributionMarketing Multi-Channel Attribution model with R (part 1: Markov chains concept)Marketing Multi-Channel Attribution model with R (part 2: practical issues)ml-book/shapleyOverview of Attribution modeling in MCF3. Importing the Class>>pipinstallmarketing_attribution_modelsfrommarketing_attribution_modelsimportMAM4. DemonstrationCreation of the MAM ObjectWhencreating a MAM Objecttwo Data Frametemplatescan be used as input depending on what is the value of the parametergroup_channels.group_channels= True: The input Data Frame hasone sessionof each user's jorneyper row.The values required in each row (in other words, the required columns) are somedistinctuser identification, abooleanindication of convertion or lack there of and the session'ssource channel.group_channels= False: The input Data Frame hasthe whole journeyof each userper row. In case you use Google Analytics, this template can be obtained by downloading theTop Conversion Pathsreport.In this case, both the channels and time to conversion columns are agregated by journey with each touchpoint being separated by '>' (the bigger than sign) by default. A different separator can be set in thepath_separatorparameter.For this demostration we'll be using a Data Frame in which the journeys arenot yet grouped, with each row as a different session and without an unique journey id.Note:The MAM Class has a built in parameter for journey id creation,create_journey_id_based_on_conversion, that ifTrue, an id is created based on the user id, input in thegroup_channels_id_listparameter, and the column indicating wether there is a conversion or not, whose name is defined by thejourney_with_conv_colnameparameter.In this scenario, all sessions from each distinct user will be ordered and for every conversion a new journey id is created. However, wehighly encouragethat this journey id creation is customized based onknowledge specific to the business in handand exploratory conclusions. For instance if in a given business it is noted that the average journey duration is about a week, a new critereon may be defined so that once any user doesn't have any interaction for seven days the journey breaks under the assumption there was a loss of interest.As for the parameters now, here's how they're configured for ourgroup_ channels= True scenario:APandas DataFrameis input as a database;Thegroup_channelsparameter is set to True;The name of the column containing the channels in the original DataFrame is informed though thechannels_colnameparameter;The name of the boolean column that determines wether there is a conversion or not is informed through thejourney_with_conv_colnameparameter;The list containing the names of the columns used to compose the journey id is informed through thegroup_channels_by_id_list. Although the list could be longer, we're creating this id based on conversions (see item 7), so the user id alone is enough.The start time of each session is informed in thegroup_timestamp_colnameparameter as the name of said column in the original Data Frame. It can be a date or a timestamp.And finally, in our scenario, we want to generate a journey id based on the columns already indicated on the parametersgroup_channels_by_id_listandjourney_with_conv_colnameby settingcreate_journey_id_based_on_conversionasTrue.attributions=MAM(df,group_channels=True,channels_colname='channels',journey_with_conv_colname='has_transaction',group_channels_by_id_list=['user_id'],group_timestamp_colname='visitStartTime',create_journey_id_based_on_conversion=True)In order to explore and understand the capabilities of MAM, a "Random DataFrame Generator" was implemented through the use ofrandom_dfparameter when set toTrue.attributions=MAM(random_df=True)After the Object MAM is created, we can check out our database now with the addition of ourjourney_idand with sessions grouped injourneysusing theattriute".DataFrame".attributions.DataFramejourney_idchannels_aggtime_till_conv_aggconverted_aggconversion_value0id:0_J:0Facebook0.0True11id:0_J:1Google Search0.0True12id:0_J:10Google Search > Organic > Email Marketing72.0 > 24.0 > 0.0True13id:0_J:11Organic0.0True14id:0_J:12Email Marketing > Facebook432.0 > 0.0True1..................20341id:9_J:5Direct > Facebook120.0 > 0.0True120342id:9_J:6Google Search > Google Search > Google Search48.0 > 24.0 > 0.0True120343id:9_J:7Organic > Organic > Google Search > Google Search480.0 > 480.0 > 288.0 > 0.0True120344id:9_J:8Direct > Organic168.0 > 0.0True120345id:9_J:9Google Search > Organic > Google Search > Emai...528.0 > 528.0 > 408.0 > 240.0 > 0.0True1This attribute isupdatedforevery attribution modelgenerated. Only in the case of heuristic models, a new column is appended containing the attribution value given by said model.Note:The attribute.DataFramedoes not interfere with any model calculations. Should it be altered by usage, the following results aren't affected.attributions.attribution_last_click()attributions.DataFramejourney_idchannels_aggtime_till_conv_aggconverted_aggconversion_value0id:0_J:0Facebook0.0True11id:0_J:1Google Search0.0True12id:0_J:10Google Search > Organic > Email Marketing72.0 > 24.0 > 0.0True13id:0_J:11Organic0.0True14id:0_J:12Email Marketing > Facebook432.0 > 0.0True1..................20341id:9_J:5Direct > Facebook120.0 > 0.0True120342id:9_J:6Google Search > Google Search > Google Search48.0 > 24.0 > 0.0True120343id:9_J:7Organic > Organic > Google Search > Google Search480.0 > 480.0 > 288.0 > 0.0True120344id:9_J:8Direct > Organic168.0 > 0.0True120345id:9_J:9Google Search > Organic > Google Search > Emai...528.0 > 528.0 > 408.0 > 240.0 > 0.0True1Usually the volume of data worked with is extensive, so it is impractical or even impossible to analyse results attributed toeachjourney with transaction. With the attributegroup_by_channels_models, however, all results can be seen grouped by channel.Note: Grouped resultsdo not overwriteeach other in case the same model is used in two distinct instances. Both (or even more) of them are shown in "group_by_channels_models".attributions.group_by_channels_modelschannelsattribution_last_click_heuristicDirect2133Email Marketing1033Facebook3168Google Display1073Google Search4255Instagram1028Organic6322Youtube1093As with the.DataFrameattribute,group_by_channels_modelsis also updated for every model usedwithout the limitationof not displaying algorithmic results.attributions.attribution_shapley()attributions.group_by_channels_modelschannelsattribution_last_click_heuristicattribution_shapley_size4_conv_rate_algorithmic0Direct10974.9268491Email Marketing5470.5584282Facebook160160.6289453Google Display65110.6493524Google Search193202.1795195Instagram6472.9824336Organic315265.7685497Youtube5860.305925About the ModelsAll heuristic models behave the same when using the attributes.DataFrameand.group_by_channels_models, as explained before, and theoutputof all heuristicmodel's methodsreturn atuplecontaining twopandas Series.attribution_first_click=attributions.attribution_first_click()ThefirstSeries of the tuple are the results in ajourney granularity, similar to the observed in the.DataFrameattributeattribution_first_click[0]0                          [1, 0, 0, 0, 0]
    1                                      [1]
    2              [1, 0, 0, 0, 0, 0, 0, 0, 0]
    3                                   [1, 0]
    4                                      [1]
                           ...                
    20512                               [1, 0]
    20513                            [1, 0, 0]
    20514    [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    20515                            [1, 0, 0]
    20516                         [1, 0, 0, 0]
    Length: 20517, dtype: objectThesecondone contains the results with achannel granularity, as seen in the.group_by_channels_modelsattribute.attribution_first_click[1]channelsattribution_first_click_heuristic0Direct20781Email Marketing10952Facebook31773Google Display10664Google Search42595Instagram10076Organic63617Youtube1062Customizing ModelsOf all models present in the Object MAM, only Last Click, First Click and Linear haveno customizable parametersbutgroup_by_channels_models, which has aboolean valuethat when set toFalsethe model doesn't return the attribution goruped by channels.Last Click Non- ModelCreated to replicate Google Analytics' default attriution (Last Click Non Direct) in whichDirect trafficisoverwrittenin case previous interations have a specific traffic source other than Direct itself in a given timespan (6 months by default).If unspecified, the parameterbut_not_this_channelis set to'Direct', but it can be set to any other channel of interest to the business.attributions.attribution_last_click_non(but_not_this_channel='Direct')[1]channelsattribution_last_click_non_Direct_heuristic0Direct111Email Marketing602Facebook1723Google Display694Google Search2245Instagram676Organic3507Youtube65Position Based ModelThis model has a parameterlist_positions_first_middle_lastin which the weights respective to the positions of channels in each journey can me specified according tobusiness relateddecisions. The default distribution of the parameter is40%for theintroducingchannel,40%for theconverting / lastchannel and20%for theintermidiateones.attributions.attribution_position_based(list_positions_first_middle_last=[0.3,0.3,0.4])[1]channelsattribution_position_based_0.3_0.3_0.4_heuristic0Direct95.6850851Email Marketing57.6171912Facebook145.8175013Google Display56.3406934Google Search193.2823055Instagram54.6785576Organic288.1488967Youtube55.629772Time Decay ModelThere are two customizable settings: Thedecay rate, throght thedecay_over_time* parameter, and the time (in hours)between each decaimentthrough thefrequencyparameter.It is worth noting, however, that in case there is more than one touchpoint between frequency intervals the conversion value will be equally distributed among these channels.As an example:Channels:Facebook > Organic > Paid SearchTime between touchpoints:14 > 12 > 0Decay Frequence:7Results:25% goes to Facebook;25% goes to Organic;50% goes to Paid Search;attributions.attribution_time_decay(decay_over_time=0.6,frequency=7)[1]channelsattribution_time_decay0.6_freq7_heuristic0Direct108.6795381Email Marketing54.4259142Facebook159.5922163Google Display64.3501074Google Search192.8388845Instagram64.6114146Organic314.9200827Youtube58.581845Markov ChainsUppon being called, this model returns a tuple withfourcomponents. The first two (indexed 0 and 1) are just like with the heuristic models, with the representation of the.DataFrameand.group_by_channels_modelsrespectively. As for the third and fourth components (indexed 2 and 3) the results are thetransition matrixand theremoval effect table.To start off, it is possible to indicate if samestate transitionsare considered or not (e.g.Direct to Direct).attribution_markov=attributions.attribution_markov(transition_to_same_state=False)channelsattribution_markov_algorithmic0Direct2305.3243621Email Marketing1237.4007742Facebook3273.9188323Youtube1231.1839384Google Search4035.2606855Instagram1205.9490956Organic5358.2706447Google Display1213.691671This configurationdoes not affectthe overall attributed results for each channel, but the values observed in thetransition matrix. Because we settransition_to_same_statetoFalse, the diagonal, indicating states transitioning to themselves, is nulled.ax,fig=plt.subplots(figsize=(15,10))sns.heatmap(attribution_markov[2].round(3),cmap="YlGnBu",annot=True,linewidths=.5)Removal Effect, the fourthattribution_markovoutput, is obtained by the ratio of the difference between the probability of conversion in general and the probability once said channel is removed over the general probability again.ax,fig=plt.subplots(figsize=(2,5))sns.heatmap(attribution_markov[3].round(3),cmap="YlGnBu",annot=True,linewidths=.5)Shapley ValueFinally, the second algorith model ofMAMwhose concept comes fromGame Theory. The objective here is to distribute the contribution of each player (in our case, channel) in a game of cooperation calculated using combinations of journeys with and without a given channel.The parametersizedefines a limit of howlongachain of channelsis in every journey. By default, it's value is set to4, meaning only thefour last channels preceding a conversionare considered.The calculation method of marginal contributions of each channel can vary with theorderparameter. By default it is set toFalse, which means the contribution is calculated disregarding the order of each channel in the journeys.attributions.attribution_shapley(size=4,order=True,values_col='conv_rate')[0]combinationsconversionstotal_sequencesconversion_valueconv_rateattribution_shapley_size4_conv_rate_order_algorithmic0Direct9099269090.981641[909.0]1Direct > Email Marketing2728270.964286[13.948270234099155, 13.051729765900845]2Direct > Email Marketing > Facebook5551.000000[1.6636366232390172, 1.5835883671498818, 1.752...3Direct > Email Marketing > Facebook > Google D...1111.000000[0.2563402919193473, 0.2345560799963515, 0.259...4Direct > Email Marketing > Facebook > Google S...1111.000000[0.2522517802130265, 0.2401286956930936, 0.255........................1278Youtube > Organic > Google Search > Google Dis...1210.500000[0.2514214624662836, 0.24872101523605275, 0.24...1279Youtube > Organic > Google Search > Instagram1111.000000[0.2544401477637237, 0.2541071889956603, 0.253...1280Youtube > Organic > Instagram4441.000000[1.2757196742326997, 1.4712839059493295, 1.252...1281Youtube > Organic > Instagram > Facebook1111.000000[0.2357631944623868, 0.2610913781266248, 0.247...1282Youtube > Organic > Instagram > Google Search3331.000000[0.7223482210689489, 0.7769049003203142, 0.726...Finally, the parameter indicating what metric is used to calculate the Shapley Value isvalues_col, which by default is set toconversion rate. In doing so, journeyswithout conversionsare taken into acount.It is possible, however, to consider onlyliteral conversionswhen using the model as seen below.attributions.attribution_shapley(size=3,order=False,values_col='conversions')[0]combinationsconversionstotal_sequencesconversion_valueconv_rateattribution_shapley_size3_conversions_algorithmic0Direct1118180.611111[11.0]1Direct > Email Marketing4550.800000[2.0, 2.0]2Direct > Email Marketing > Google Search1220.500000[-3.1666666666666665, -7.666666666666666, 11.8...3Direct > Email Marketing > Organic4660.666667[-7.833333333333333, -10.833333333333332, 22.6...4Direct > Facebook3440.750000[-8.5, 11.5].....................75Instagram > Organic > Youtube461231230.373984[5.833333333333332, 34.33333333333333, 5.83333...76Instagram > Youtube2440.500000[2.0, 0.0]77Organic6492920.695652[64.0]78Organic > Youtube811110.727273[30.5, -22.5]79Youtube1115150.733333[11.0]VisualizationAfter obtaining every attribution from different models stored in our.group_by_channels_modelsobject it is possible to plot and compare results for insightsattributions.plot()In case you're only interested in the algorithmic models, this can me specified in themodel_typeparameter.attributions.plot(model_type='algorithmic')