diff --git a/recommender_system/README.md b/recommender_system/README.md index f0e320ee7819b27746b097ce784e0d53f83ca9fb..90c1e74b798e74a67f5b046e604a52c441c31759 100644 --- a/recommender_system/README.md +++ b/recommender_system/README.md @@ -12,7 +12,7 @@ - 基于内容过滤推荐[[1](#参考文献)](Content-based Filtering Recommendation):该方法利用商品的内容描述,抽象出有意义的特征,通过计算用户的兴趣和商品描述之间的相似度,来给用户做推荐。优点是简单直接,不需要依据其他用户对商品的评价,而是通过商品属性进行商品相似度度量,从而推荐给用户所感兴趣商品的相似商品;缺点是对于没有任何行为的新用户同样存在冷启动的问题。 - 组合推荐[[2](#参考文献)](Hybrid Recommendation):运用不同的输入和技术共同进行推荐,以弥补各自推荐技术的缺点。 -其中协同过滤是应用最广泛的技术之一,它又可以分为多个子类:基于用户 (User-Based)的推荐[[3](#参考文献)] , 基于物品(Item-Based)的推荐[[4](#参考文献)],基于社交网络关系(Social-Based)的推荐[[5](#参考文献)],基于模型(Model-based的推荐等。1994年明尼苏达大学推出的GroupLens 系统[[3](#参考文献)]一般被认为是推荐系统成为一个相对独立的研究方向的标志。该系统首次提出了基于协同过滤来完成推荐任务的思想,此后,基于该模型的协同过滤推荐引领了推荐系统十几年的发展方向。 +其中协同过滤是应用最广泛的技术之一,它又可以分为多个子类:基于用户 (User-Based)的推荐[[3](#参考文献)] 、基于物品(Item-Based)的推荐[[4](#参考文献)]、基于社交网络关系(Social-Based)的推荐[[5](#参考文献)]、基于模型(Model-based)的推荐等。1994年明尼苏达大学推出的GroupLens系统[[3](#参考文献)]一般被认为是推荐系统成为一个相对独立的研究方向的标志。该系统首次提出了基于协同过滤来完成推荐任务的思想,此后,基于该模型的协同过滤推荐引领了推荐系统十几年的发展方向。 深度学习具有优秀的自动提取特征的能力,能够学习多层次的抽象特征表示,并对异质或跨域的内容信息进行学习,可以一定程度上处理推荐系统冷启动问题[[6](#参考文献)]。本教程主要介绍个性化推荐的深度学习模型,以及如何使用PaddlePaddle实现模型。 @@ -41,35 +41,43 @@ YouTube是世界上最大的视频上传、分享和发现网站,YouTube推荐 #### 候选生成网络(Candidate Generation Network) -候选生成网络将推荐问题建模为一个类别数极大的多类分类问题:对于一个Youtube用户,使用其观看历史(视频ID)、搜索词记录(search tokens)、人口学信息(如地理位置、用户登录设备)等特征,对视频库中所有视频进行多分类,得到每一类别的分类结果(即每一个视频的推荐概率),最终输出概率较高的几百个视频。 +候选生成网络将推荐问题建模为一个类别数极大的多类分类问题:对于一个Youtube用户,使用其观看历史(视频ID)、搜索词记录(search tokens)、人口学信息(如地理位置、用户登录设备)、二值特征(如性别,是否登录)和连续特征(如用户年龄)等,对视频库中所有视频进行多分类,得到每一类别的分类结果(即每一个视频的推荐概率),最终输出概率较高的几百个视频。 -对于用户$U$和历史信息$C$,预测$t$时刻用户要观看的视频$\omega_t$为视频$i$的概率为: +首先,将观看历史及搜索词记录这类历史信息,映射为向量后取平均值得到定长表示;同时,输入人口学特征以优化新用户的推荐效果,并将二值特征和连续特征归一化处理到[0, 1]范围。接下来,将所有特征表示拼接为一个向量,并输入给非线形多层感知器(MLP,详见[识别数字](https://github.com/PaddlePaddle/book/blob/develop/recognize_digits/README.md)教程)处理。最后,训练时将MLP的输出给softmax做分类,预测时计算用户的综合特征(MLP的输出)与所有视频的相似度,取得分最高的$K$个作为候选生成网络的筛选结果。图2显示了候选生成网络结构。 -$$P(\omega_t=i|U,C)=\frac{e^{v_{i}u}}{\sum_{j \in V}e^{v_{j}u}}$$ -其中,$V$表示视频库集合,大小在数百万量级;$u\in \mathbb{R}^N$是用户及相应历史信息的向量表示;$v_j\in \mathbb{R}^N$是ID为$j$的视频的向量表示。 - -将观看历史(视频ID)及搜索词记录这类历史信息映射为向量后取平均值得到定长表示,同时输入人口学特征(地理位置等)以优化新用户的推荐效果,将二值特征(如性别,是否登录)和连续特征(如用户年龄)归一化处理到[0, 1]。接下来将所有特征表示拼接为一个很长的向量并输入给多个非线形变换层(这里应用的是全连接的 ReLU)处理。最高层的非线形变换得到的即是$u$,最后将其输入给 softmax 做分类,如图2所示:
图2. 候选生成网络结构
@@ -102,11 +110,7 @@ movies.dat ratings.dat users.dat README pip install -r data/requirements.txt ``` -其次,在预处理过程中,我们将字段配置文件`data/config.json`转化为meta配置文件`meta_config.json`,并生成对应的meta文件`meta.bin`,以完成数据文件的序列化。然后再将`ratings.dat`分为训练集、测试集两部分,把它们的地址写入`train.list`和`test.list`。 - -```bash -./preprocess.sh -``` +其次在预处理`./preprocess.sh`过程中,我们将字段配置文件`data/config.json`转化为meta配置文件`meta_config.json`,并生成对应的meta文件`meta.bin`,以完成数据文件的序列化。然后再将`ratings.dat`分为训练集、测试集两部分,把它们的地址写入`train.list`和`test.list`。 运行成功后目录`./data` 新增以下文件: @@ -157,7 +161,7 @@ def process(settings, filename): for line in f: # 从评分文件中读取评分 user_id, movie_id, score = map(int, line.split('::')[:-1]) - # 将评分放缩到[-2, +2]范围内的整数 + # 将评分平移到[-2, +2]范围内的整数 score = float(score - 3) movie_meta = settings.meta['movie'][movie_id] @@ -197,8 +201,8 @@ is_predict = get_config_arg('is_predict', bool, False) META_FILE = 'data/meta.bin' +# 加载 meta 文件 with open(META_FILE, 'rb') as f: - # 加载 meta 文件 meta = pickle.load(f) if not is_predict: @@ -241,7 +245,7 @@ settings( 2. 构造“电影”特征。 ```python - # 电影 ID 和电影类型分别映射到其对应的特征隐层(256维)。 + # 电影ID和电影类型分别映射到其对应的特征隐层(256维)。 movie_id_emb = embedding_layer(input=movie_id, size=embsize) movie_id_hidden = fc_layer(input=movie_id_emb, size=embsize) @@ -303,13 +307,13 @@ settings( ```shell set -e paddle train \ - --config=trainer_config.py \ # 神经网络配置文件 - --save_dir=./output \ # 模型保存路径 - --use_gpu=false \ # 是否使用 GPU (默认不使用) - --trainer_count=4\ # 一台机器上面的线程数量 - --test_all_data_in_one_period=true \ # 每个训练周期训练一次所有数据。否则每个训练周期测试batch_size个batch的数据。 - --log_period=100 \ # 训练 log_period 个 batch 后打印日志 - --dot_period=1 \ # 每训练 dot_period 个 batch 后打印一个"." + --config=trainer_config.py \ # 神经网络配置文件 + --save_dir=./output \ # 模型保存路径 + --use_gpu=false \ # 是否使用GPU(默认不使用) + --trainer_count=4\ # 一台机器上面的线程数量 + --test_all_data_in_one_period=true \ # 每个训练周期训练一次所有数据,否则每个训练周期测试batch_size个batch数据 + --log_period=100 \ # 训练log_period个batch后打印日志 + --dot_period=1 \ # 每训练dot_period个batch后打印一个"." --num_passes=50 2>&1 | tee 'log.txt' ```