Database Reference
In-Depth Information
def
def choose_ads ( site_id , zone_id , user_id , keywords ):
site = db . ad . zone . find_one ({
'site_id' : site_id , 'zone_id' : zone_id })
iif site iis None : return
return []
ads = ad_iterator ( site [ 'ads' ], keywords )
user = db . ad . user . find_one ({ 'user_id' : user_id })
iif user iis None : return
return ads
for
for ad iin ads :
advertiser_id = ad [ 'campaign_id' ] . split ( ':' , 1 )[ 0 ]
iif ad_is_acceptable ( ad , user [ advertiser_id ]):
yield
yield ad
return
return None
Our ad_iterator method has been modified to allow us to score ads based on both their
eCPM as well as their relevance:
def
def ad_iterator ( ads , keywords ):
'''Find available ads, sorted by score, with random sort for ties'''
keywords = set ( keywords )
scored_ads = [
( ad_score ( ad , keywords ), ad ) for
for ad iin ads ]
score_groups = groupby (
sorted ( scored_ads ), key = lambda
lambda score , ad : score )
for
for score , ad_group iin score_groups :
ad_group = list ( ad_group )
shuffle ( ad_group )
for
for ad iin ad_group : yield
yield ad
def
def ad_score ( ad , keywords ):
'''Compute a desirability score based on the ad eCPM and keywords'''
matching = set ( ad [ 'keywords' ]) . intersection ( keywords ) return
return
ad [ 'ecpm' ] * math . log ( 1.1 + len ( matching ))
def
def ad_is_acceptible ( ad , profile ):
# same as above
The main thing to note in the preceding code is that ads must now be sorted according to some
score , which in this case is computed based on a combination of the ecpm of the ad as well
as the number of keywords matched. More advanced use cases may boost the importance of
various keywords, but this goes beyond the scope of this use case. One thing to keep in mind
is that because the ads are now being sorted at display time, there may be performance issues
if a large number of ads are competing for the same display slot.
Search WWH ::




Custom Search