保存特征
训练完模型后,我们得到每个用户、电影对应的特征向量,接下来将这些特征向量保存到本地,这样在进行推荐时,不需要使用神经网络重新提取特征,节省时间成本。
保存特征的流程是:
- 加载预训练好的模型参数。
- 输入数据集的数据,提取整个数据集的用户特征和电影特征。注意数据输入到模型前,要先转成内置vairable类型并保证尺寸正确。
- 分别得到用户特征向量和电影特征向量,使用pickle库保存字典形式的特征向量。
使用用户和电影ID为索引,以字典格式存储数据,可以通过用户或者电影的ID索引到用户特征和电影特征。
下面代码中,我们使用了一个pickle库。pickle库为python提供了一个简单的持久化功能,可以很容易的将Python对象保存到本地,但是缺点是,保存的文件对人来说可读性较差。
from PIL import Image
# 加载第三方库Pickle,用来保存Python数据到本地
import pickle
# 定义特征保存函数
def get_usr_mov_features(model, params_file_path, poster_path):
use_gpu = False
place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()
usr_pkl = {}
mov_pkl = {}
# 定义将list中每个元素转成variable的函数
def list2variable(inputs, shape):
inputs = np.reshape(np.array(inputs).astype(np.int64), shape)
return fluid.dygraph.to_variable(inputs)
with fluid.dygraph.guard(place):
# 加载模型参数到模型中,设置为验证模式eval()
model_state_dict, _ = fluid.load_dygraph(params_file_path)
model.load_dict(model_state_dict)
model.eval()
# 获得整个数据集的数据
dataset = model.Dataset.dataset
for i in range(len(dataset)):
# 获得用户数据,电影数据,评分数据
# 本案例只转换所有在样本中出现过的user和movie,实际中可以使用业务系统中的全量数据
usr_info, mov_info, score = dataset[i]['usr_info'], dataset[i]['mov_info'],dataset[i]['scores']
usrid = str(usr_info['usr_id'])
movid = str(mov_info['mov_id'])
# 获得用户数据,计算得到用户特征,保存在usr_pkl字典中
if usrid not in usr_pkl.keys():
usr_id_v = list2variable(usr_info['usr_id'], [1])
usr_age_v = list2variable(usr_info['age'], [1])
usr_gender_v = list2variable(usr_info['gender'], [1])
usr_job_v = list2variable(usr_info['job'], [1])
usr_in = [usr_id_v, usr_gender_v, usr_age_v, usr_job_v]
usr_feat = model.get_usr_feat(usr_in)
usr_pkl[usrid] = usr_feat.numpy()
# 获得电影数据,计算得到电影特征,保存在mov_pkl字典中
if movid not in mov_pkl.keys():
mov_id_v = list2variable(mov_info['mov_id'], [1])
mov_tit_v = list2variable(mov_info['title'], [1, 1, 15])
mov_cat_v = list2variable(mov_info['category'], [1, 6])
mov_in = [mov_id_v, mov_cat_v, mov_tit_v, None]
mov_feat = model.get_mov_feat(mov_in)
mov_pkl[movid] = mov_feat.numpy()
print(len(mov_pkl.keys()))
# 保存特征到本地
pickle.dump(usr_pkl, open('./usr_feat.pkl', 'wb'))
pickle.dump(mov_pkl, open('./mov_feat.pkl', 'wb'))
print("usr / mov features saved!!!")
param_path = "./checkpoint/epoch7"
poster_path = "./work/ml-1m/posters/"
get_usr_mov_features(model, param_path, poster_path)
- 3706
- usr / mov features saved!!!
保存好有效代表用户和电影的特征向量后,在下一节我们讨论如何基于这两个向量构建推荐系统。