ad_predict.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import json
  2. import random
  3. import time
  4. import gevent
  5. from db_helper import RedisHelper
  6. from config import set_config
  7. from log import Log
  8. from gevent import monkey, pool
  9. monkey.patch_all()
  10. config_ = set_config()
  11. log_ = Log()
  12. redis_helper = RedisHelper()
  13. def thompson_process(creative_id):
  14. # 获取creative_id对应的Thompson参数
  15. # st_time1 = time.time()
  16. thompson_param = redis_helper.get_data_from_redis(key_name=f"{config_.THOMPSON_PARAM_KEY_PREFIX}{creative_id}")
  17. # get_redis_time = int(time.time() - st_time1) * 1000
  18. thompson_time = {}
  19. if thompson_param is None or thompson_param == '':
  20. # 参数不存在,随机生成[0, 1)之间的浮点数
  21. st_time2 = time.time()
  22. score = random.random()
  23. # thompson_time['random'] = int(time.time() - st_time2) * 1000
  24. random_flag = 'random'
  25. else:
  26. # 参数存在
  27. # st_time3 = time.time()
  28. param_alpha, param_beta = json.loads(thompson_param.strip())
  29. param_alpha, param_beta = int(param_alpha), int(param_beta)
  30. if param_alpha + param_beta >= 100:
  31. # ad_idea_id 曝光数 >= 100,生成参数为(param_alpha+1, param_beta+1)的beta分布随机数
  32. score = random.betavariate(alpha=param_alpha+1, beta=param_beta+1)
  33. random_flag = 'beta'
  34. else:
  35. # ad_idea_id 曝光数 < 100,随机生成[0, 1)之间的浮点数
  36. score = random.random()
  37. random_flag = 'random'
  38. # thompson_time['beta'] = int(time.time() - st_time3) * 1000
  39. thompson_res = [creative_id, score, thompson_param, random_flag]
  40. # log_.info(f"get_redis_time: {get_redis_time}, thompson_time: {thompson_time}")
  41. return thompson_res
  42. def get_creative_id_with_thompson(mid, creative_id_list):
  43. """利用Thompson采样获取此次要展示的广告创意ID"""
  44. # 限制协程最大并发数:20
  45. st_time6 = time.time()
  46. gevent_pool = pool.Pool(100)
  47. gevent_pool_time = int(time.time() - st_time6) * 1000
  48. st_time5 = time.time()
  49. tasks = [gevent_pool.spawn(thompson_process, creative_id) for creative_id in creative_id_list]
  50. gevent.joinall(tasks)
  51. thompson_res_list = [t.get() for t in tasks]
  52. get_random_time = int(time.time() - st_time5) * 1000
  53. # 按照score排序
  54. st_time4 = time.time()
  55. thompson_res_rank = sorted(thompson_res_list, key=lambda x: x[1], reverse=True)
  56. sort_time = int(time.time() - st_time4) * 1000
  57. rank_res = {
  58. 'mid': mid,
  59. 'creative_id': thompson_res_rank[0][0],
  60. 'score': thompson_res_rank[0][1],
  61. 'thompson_param': thompson_res_rank[0][2],
  62. 'random_flag': thompson_res_rank[0][3],
  63. 'thompson_res_rank': thompson_res_rank
  64. }
  65. log_.info({'gevent_pool_time': gevent_pool_time, 'get_random_time': get_random_time, 'sort_time': sort_time})
  66. return rank_res