Source code for rtb.bidding

"""Bidding module"""
import collections
import numpy as np


RunResults = collections.namedtuple('RunResults', ['total_clicks',
                                                   'total_impressions',
                                                   'total_ad_spend'])


[docs]class BidSimulator: """Simulates given bidding strategy on a dataset"""
[docs] def __init__(self, data, bidding_strategy): """Initialize bidding simulator. Parameters ---------- data : pandas.DataFrame Historical data containing features for model predicti n, bidding price, winning price, impressions and click indicators. bidding_strategy : func Function that retuns bid given prospenity to click and data row """ self._data = data self._bidding_strategy = bidding_strategy
[docs] def run(self, ctr_model=None): """Run bidding simulator Parameters ---------- ctr_model : sklearn-like model Binary classifier for click prospenity Returns ------- bids : list Bids for each entry in the data""" total_impressions = 0 total_ad_spend = 0 total_clicks = 0 for i, row in self._data.iterrows(): if ctr_model is not None: prospenity = ctr_model.predict_proba( row.drop(['click', 'paying_price']).values.reshape(1, -1))[0][1] else: prospenity = None bid = self._bidding_strategy(prospenity, row) if bid >= row['paying_price']: total_impressions += 1 total_ad_spend += row['paying_price'] if row['click']: total_clicks += 1 return RunResults(total_clicks, total_impressions, total_ad_spend)
[docs] @staticmethod def metrics_report(run_results): """Generate metric let g:pymode_lint = 0u Parameters ---------- run_results : RunResults Returns ------- cpc : float Cost Per Click. ctr : float Click Through Rate. cpm : float Cost Per Mille. """ ctr = BidSimulator.ctr(run_results.total_clicks, run_results.total_impressions) cpm = BidSimulator.cpm(run_results.total_ad_spend, run_results.total_impressions) cpc = BidSimulator.cpc(run_results.total_ad_spend, run_results.total_clicks) report = "CTR:\t%.2f\nCPM:\t%.3f\nCPC:\t%.3f" % (ctr, cpm, cpc) return report
[docs] @staticmethod def ctr(num_of_clicks, num_of_impressions): """Claculate Click Through Rate - frequency of clicks on ads.""" return num_of_clicks / num_of_impressions \ if num_of_impressions > 0 else 0
[docs] @staticmethod def cpm(total_spendings, num_of_impressions): """Calculate Cost Per Mille - total cost advertiser pays for 1000 impressions.""" return total_spendings / num_of_impressions * 1000 \ if num_of_impressions > 0 else 0
[docs] @staticmethod def cpc(total_spendings, num_of_clicks): """Calculate Cost Per Click""" return total_spendings / num_of_clicks if num_of_clicks > 0 else 0
def __repr__(self): return "%s(%s)" % (self.__class__.__name__, self._bidding_strategy.__class__.__name__)
[docs]class RandomBiddingStrategy(object): """Random strategy that places random pertribations of a base bid"""
[docs] def __init__(self, bid): """Create random bidding strategy Parameters ---------- bid : float Bid value """ self._bid = bid
[docs] def __call__(self, prospenity, row): """Execute bidding strategy Parameters ---------- prospenity : float prospenity to click row : dict-like data row with features, pricing, impression and click data Returns ------- bid_price : float """ return np.random.rand() * self._bid
[docs]class FlatBiddingStrategy(): """Constant bid"""
[docs] def __init__(self, bid): """Create flat bidding strategy Parameters ---------- bid : float Bid value """ self._bid = bid
[docs] def __call__(self, prospenity, row): """Execute bidding strategy Parameters ---------- prospenity : float prospenity to click row : dict-like data row with features, pricing, impression and click data Returns ------- bid_price : float """ return self._bid
[docs]class GoalBiddingStrategy(): """Bid based on prospenity"""
[docs] def __init__(self, bid): """Create bidding strategy Parameters ---------- bid : float Bid value """ self._bid = bid
[docs] def __call__(self, prospenity, row): """Execute bidding strategy Parameters ---------- prospenity : float prospenity to click row : dict-like data row with features, pricing, impression and click data Returns ------- bid_price : float """ return prospenity * self._bid
[docs]class EffectiveCPCBiddingStrategy(GoalBiddingStrategy): """Bid based on prospenity and CPC calculated from training data"""
[docs] def __init__(self, data): """Create bidding strategy Parameters ---------- data : pd.DataFrame Historical data """ effective_cpc = data['paying_price'].sum() / data['click'].sum() print(effective_cpc) super().__init__(effective_cpc)