保存特征

训练完模型后,我们得到每个用户、电影对应的特征向量,接下来将这些特征向量保存到本地,这样在进行推荐时,不需要使用神经网络重新提取特征,节省时间成本。

保存特征的流程是:

  • 加载预训练好的模型参数。
  • 输入数据集的数据,提取整个数据集的用户特征和电影特征。注意数据输入到模型前,要先转成内置vairable类型并保证尺寸正确。
  • 分别得到用户特征向量和电影特征向量,使用pickle库保存字典形式的特征向量。

使用用户和电影ID为索引,以字典格式存储数据,可以通过用户或者电影的ID索引到用户特征和电影特征。

下面代码中,我们使用了一个pickle库。pickle库为python提供了一个简单的持久化功能,可以很容易的将Python对象保存到本地,但是缺点是,保存的文件对人来说可读性较差。

  1. from PIL import Image
  2. # 加载第三方库Pickle,用来保存Python数据到本地
  3. import pickle
  4. # 定义特征保存函数
  5. def get_usr_mov_features(model, params_file_path, poster_path):
  6. use_gpu = False
  7. place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()
  8. usr_pkl = {}
  9. mov_pkl = {}
  10. # 定义将list中每个元素转成variable的函数
  11. def list2variable(inputs, shape):
  12. inputs = np.reshape(np.array(inputs).astype(np.int64), shape)
  13. return fluid.dygraph.to_variable(inputs)
  14. with fluid.dygraph.guard(place):
  15. # 加载模型参数到模型中,设置为验证模式eval()
  16. model_state_dict, _ = fluid.load_dygraph(params_file_path)
  17. model.load_dict(model_state_dict)
  18. model.eval()
  19. # 获得整个数据集的数据
  20. dataset = model.Dataset.dataset
  21. for i in range(len(dataset)):
  22. # 获得用户数据,电影数据,评分数据
  23. # 本案例只转换所有在样本中出现过的user和movie,实际中可以使用业务系统中的全量数据
  24. usr_info, mov_info, score = dataset[i]['usr_info'], dataset[i]['mov_info'],dataset[i]['scores']
  25. usrid = str(usr_info['usr_id'])
  26. movid = str(mov_info['mov_id'])
  27. # 获得用户数据,计算得到用户特征,保存在usr_pkl字典中
  28. if usrid not in usr_pkl.keys():
  29. usr_id_v = list2variable(usr_info['usr_id'], [1])
  30. usr_age_v = list2variable(usr_info['age'], [1])
  31. usr_gender_v = list2variable(usr_info['gender'], [1])
  32. usr_job_v = list2variable(usr_info['job'], [1])
  33. usr_in = [usr_id_v, usr_gender_v, usr_age_v, usr_job_v]
  34. usr_feat = model.get_usr_feat(usr_in)
  35. usr_pkl[usrid] = usr_feat.numpy()
  36. # 获得电影数据,计算得到电影特征,保存在mov_pkl字典中
  37. if movid not in mov_pkl.keys():
  38. mov_id_v = list2variable(mov_info['mov_id'], [1])
  39. mov_tit_v = list2variable(mov_info['title'], [1, 1, 15])
  40. mov_cat_v = list2variable(mov_info['category'], [1, 6])
  41. mov_in = [mov_id_v, mov_cat_v, mov_tit_v, None]
  42. mov_feat = model.get_mov_feat(mov_in)
  43. mov_pkl[movid] = mov_feat.numpy()
  44. print(len(mov_pkl.keys()))
  45. # 保存特征到本地
  46. pickle.dump(usr_pkl, open('./usr_feat.pkl', 'wb'))
  47. pickle.dump(mov_pkl, open('./mov_feat.pkl', 'wb'))
  48. print("usr / mov features saved!!!")
  49. param_path = "./checkpoint/epoch7"
  50. poster_path = "./work/ml-1m/posters/"
  51. get_usr_mov_features(model, param_path, poster_path)
  1. 3706
  2. usr / mov features saved!!!

保存好有效代表用户和电影的特征向量后,在下一节我们讨论如何基于这两个向量构建推荐系统。