def _load_hot_videos(self): """加载热门视频""" if redis_client.exists(hot_video_key1): videos = redis_client.zrangebyscore(hot_video_key1, '-inf', '+inf', withscores=True) for key, value in videos: self.hot_videos[key.decode('utf8')] = value else: self.hot_videos.update(self._get_hot_videos(size=100)) self.hot_videos.update(self._get_hot_videos(tag='india', size=100)) self.hot_videos.update( self._get_hot_videos(tag='bollywood', size=200)) self.hot_videos.update(self._get_hot_videos(tag='series', size=100)) self.hot_videos.update(self._get_hot_videos(tag='funny', size=300)) self.hot_videos.update( self._get_hot_videos(tag='cricket', size=100)) self.hot_videos.update(self._get_hot_videos(tag='status', size=100)) zset_args = [] for key, value in self.hot_videos.items(): zset_args.append(value) zset_args.append(key) redis_client.zadd(hot_video_key1, *zset_args)
def get_recommend_videos(self, device, size): """获取推荐视频数据 Args: device (str): 设备id size (int): 个数 """ device_key = 'device|{}|recommend'.format(device) recommend_list = redis_client.zrange(device_key, 0, size - 1, desc=True) recommend_list = [x.decode('utf8') for x in recommend_list] # 推荐列表为空 if not recommend_list: video_ids = random.sample(self.hot_videos.keys(), 100) recommend_videos = video_ids[:size] zset_args = [] for video in video_ids[size:]: zset_args.append(1.0) zset_args.append(video) redis_client.zadd(device_key, *zset_args) redis_client.expire(device_key, 2592000) else: recommend_videos = recommend_list redis_client.zrem(device_key, *recommend_videos) return recommend_videos
def update_recommend_list(self, device, video, operation): """针对用户操作视频的行为更新推荐列表 Args: device (str): 设备id video (str): 视频id operation (int): 操作类型 """ device_key = 'device|{}|recommend'.format(device) recommend_list = redis_client.zrangebyscore(device_key, '-inf', '+inf', withscores=True, start=0, num=1000) if not recommend_list: return video_map = self.get_similar_videos(video, 16) if not video_map: return recommend_map = { key.decode('utf8'): value for key, value in recommend_list } recommend_map[video] = (time.time() - 2147483647) / 200000000 for key, value in video_map.items(): if key in recommend_map: recommend_map[key] += video_operation_score[operation] * log10( value) else: recommend_map[key] = log10(value) recommend_list = sorted(recommend_map.items(), key=lambda kv: kv[1], reverse=True) recommending, recommended = 0, 0 zset_args = [] for key, value in recommend_list: if value > 0: if recommending >= 500: # 一个用户最多有500个推荐视频 continue zset_args.append(value) zset_args.append(key) recommending += 1 else: if recommended >= 500: # 最近500条视频不重复 continue zset_args.append(value) zset_args.append(key) recommended += 1 redis_client.delete(device_key) redis_client.zadd(device_key, *zset_args)
def get_recommend_videos(self, device, size): """获取推荐视频数据 Args: device (str): 设备id size (int): 个数 """ device_key = 'device|{}|recommend'.format(device) recommend_list = redis_client.zrevrangebyscore(device_key, min=0, max='+inf', withscores=True, start=0, num=size) recommend_list = [x[0].decode('utf8') for x in recommend_list] # 推荐列表为空 if not recommend_list: redis_client.delete(device_key) video_ids = random.sample(self.hot_videos.keys(), 200) recommend_videos = video_ids[:size] zset_args = [] for video in video_ids[size:]: zset_args.append(1.0) zset_args.append(video) redis_client.zadd(device_key, *zset_args) redis_client.expire(device_key, 2592000) else: recommend_videos = recommend_list # 把推荐过的权值换成当前时间戳的负值,防止重复推荐 zset_args = [] score = (time.time() - 2147483647) / 200000000 for video in recommend_videos: zset_args.append(score) zset_args.append(video) redis_client.zadd(device_key, *zset_args) return recommend_videos
def update_recommend_list(self, device, video, operation): """针对用户操作视频的行为更新推荐列表 Args: device (str): 设备id video (str): 视频id operation (int): 操作类型 """ device_key = 'device|{}|recommend'.format(device) recommend_list = redis_client.zrangebyscore(device_key, '-inf', '+inf', withscores=True) if not recommend_list: return recommend_map = { key.decode('utf8'): value for key, value in recommend_list } try: tags = self._get_video_tag(video) except: tags = None # 视频没有标签 不推荐数据 if not tags: return video_map = self._query_videos_by_tag(tags, 20) if not video_map: return video_records = video_model.VideoBehavior.query_by_device(device) recent_videos = {x.video for x in video_records} recent_videos.add(video) for key, value in video_map.items(): if key in recommend_map: recommend_map[key] += video_operation_score[operation] * log10( value) else: recommend_map[key] = log10(value) recommend_list = sorted(recommend_map.items(), key=lambda kv: kv[1], reverse=True) count = 0 zset_args = [] for key, value in recommend_list: if count > 1000: break if key in recent_videos: continue zset_args.append(value) zset_args.append(key) count += 1 redis_client.delete(device_key) redis_client.zadd(device_key, *zset_args)