keras深度学习实战——推荐系统数据编码(代码片段)

盼小辉丶 盼小辉丶     2022-10-22     449

关键词:

Keras深度学习实战——推荐系统数据编码

0. 前言

《自编码器详解》中,我们介绍了数据编码的必要性,同时以图像编码为例实现了自编码器 (AutoEncoder) 及其多种变体。推荐系统是利用客户和商品信息,根据用户的兴趣特点和购买行为,向用户推荐用户感兴趣的信息和商品。在本节中,我们将在电影评价相关的数据集中对用户和电影进行编码。

1. 推荐系统数据编码的必要性

为了了解推荐系统中数据编码的必要性,我们考虑对用户进行电影推荐的应用场景。与文本分析类似,如果我们要对每部电影/用户进行独热编码,由于有成千上万部电影,则最终将为每部电影提供一个数千维的向量编码。
根据用户的观看习惯以较低的维度对用户进行编码,从而可以根据电影的相似性对电影进行分组,这将帮助我们挖掘用户更可能需要观看的电影。类似的思想也可以应用于电子商务推荐系统,以及向超市中的顾客推荐产品。

2. 推荐系统数据编码

在本文中,我们主要考虑对用户进行电影推荐的应用场景,在此类数据库中可能有数以百万计的用户和有成千上万的电影,我们无法对数据进行独热编码。在这种情况下,数据编码便会派上用场。推荐系统编码中使用的最流行的技术之一是矩阵分解。接下来,我们将了解其工作原理并为用户和电影生成嵌入。

2.1 在推荐系统中对用户和电影进行编码

对用户和电影进行编码的原理如下:在考虑用户对不同电影的偏好方面,如果两个用户喜欢的电影相似,则表示两个用户编码向量应该同样是相似的,按照同样的逻辑,如果两部电影相似,例如它们属于同一类型或具有类似的演员表,则表示两部电影应具有相似的编码向量。

2.2 数据集介绍

用于模型训练的数据集中包含用户信息以及他们对其观看过的电影评分信息,其中第一列表示用户编号,第二列表示电影编号,第三列表示用户对电影的评分,最后一列表示时间戳,下图中展示了下载完成的部分数据。

该数据集可从以下链接下载:https://pan.baidu.com/s/1yYQw6uuXVsj9PHsT68rx1w,提取码: ifjr

2.3 用于推荐系统的编码策略

在开始实现模型之前,我们首先介绍用于推荐系统的编码策略工作流程,以便根据用户观看的电影历史记录推荐新的电影:

  • 加载数据集,为用户和电影分配 ID
  • 将用户和电影转换为 32 维编码向量
  • 使用 Keras 中的函数式 API 计算电影和用户的 32 维向量的点积:
    • 如果有 1000000 个用户和 10000 个电影,则编码后的电影矩阵尺寸为 10000 × 32,而用户矩阵尺寸为 1000000 × 32 尺寸
    • 两者的点积的尺寸为 1000000 × 10000
  • 将点积后的输出展平并通过一个全连接层,然后连接到输出层,输出层使用线性激活函数,输出值的范围为 15,表示预测的用户对电影的评分
  • 拟合模型
  • 分别提取用户和电影的嵌入权重
  • 可以通过计算用户感兴趣的电影与数据集中其他电影的相似度来找到与给定电影相似的电影

接下来,我们将实现在推荐系统中将用户和电影编码为嵌入向量。

2.4 实现推荐系统编码模型

(1) 首先,导入数据集与所需库:

import numpy as np
import pandas as pd
from keras.layers import Input, Embedding, Dense, Dropout, merge, Flatten, dot
from keras.models import Model
from keras.optimizers import Adam

column_names = ['User', 'Movies', 'rating', 'timestamp']
ratings = pd.read_csv('u.data', sep='\\t', names=column_names)

print(ratings.head())

打印出的使用 head() 方法读取的数据集数据样本信息如下:

   User  Movies  rating  timestamp
0   196     242       3  881250949
1   186     302       3  891717742
2    22     377       1  878887116
3   244      51       2  880606923
4   166     346       1  886397596

(2) 将用户和电影转换为分类变量,创建了两个新变量:User2Movies2,用于分类:

ratings['User2']=ratings['User'].astype('category')
ratings['Movies2']=ratings['Movies'].astype('category')

(3) 为每个用户和电影分配唯一的 ID

users = ratings.User.unique()
movies = ratings.Movies.unique()

print(len(users))
print(len(movies))

userid2idx = o:i for i,o in enumerate(users)
moviesid2idx = o:i for i,o in enumerate(movies)
idx2userid = i:o for i,o in enumerate(users)
idx2moviesid = i:o for i,o in enumerate(movies)

(4)ID 作为新列添加到原始表中:

ratings['Movies2'] = ratings.Movies.apply(lambda x: moviesid2idx[x])
ratings['User2'] = ratings.User.apply(lambda x: userid2idx[x])

print(ratings.head())

再次使用 head() 方法读取的添加新列后的数据集数据样本信息如下:

   User  Movies  rating  timestamp  User2  Movies2
0   196     242       3  881250949      0        0
1   186     302       3  891717742      1        1
2    22     377       1  878887116      2        2
3   244      51       2  880606923      3        3
4   166     346       1  886397596      4        4

(5) 为每个用户 ID 和电影 ID 定义嵌入:

n_users = ratings.User.nunique()
n_movies = ratings.Movies.nunique()

在以上代码中,提取来数据集中的不同用户和不同电影的总数。接下来,定义函数 embedding_input,该函数将一个 ID 作为输入并将其转换为一个嵌入向量,该向量的维数为 n_out,共有 n_in 个输入值:

def embedding_input(name,n_in,n_out):
    inp = Input(shape=(1,),dtype='int64',name=name)
    return inp, Embedding(n_in,n_out,input_length=1)(inp)

接下来,为每个用户以及每个电影提取一个 32 维的编码向量。

n_factors = 32
user_in, u = embedding_input('user_in', n_users, n_factors)
movie_in, a = embedding_input('article_in', n_movies, n_factors)

(6) 构建神经网络模型:

import keras.backend as K
def rmse(y_true,y_pred):
  score = K.sqrt(K.mean(K.pow(y_true - y_pred, 2)))
  return score

x = dot([u,a], axes=1)
x=Flatten()(x)
x = Dense(500, activation='relu')(x)
x = Dense(1)(x)
model = Model([user_in, movie_in],x)
adam = Adam(lr=0.01)
model.compile(adam,loss='mse', metrics=[rmse])
model.summary()

模型的简要架构信息输出如下:

Model: "functional_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
user_in (InputLayer)            [(None, 1)]          0                                            
__________________________________________________________________________________________________
article_in (InputLayer)         [(None, 1)]          0                                            
__________________________________________________________________________________________________
embedding (Embedding)           (None, 1, 32)        30176       user_in[0][0]                    
__________________________________________________________________________________________________
embedding_1 (Embedding)         (None, 1, 32)        53824       article_in[0][0]                 
__________________________________________________________________________________________________
dot (Dot)                       (None, 32, 32)       0           embedding[0][0]                  
                                                                 embedding_1[0][0]                
__________________________________________________________________________________________________
flatten (Flatten)               (None, 1024)         0           dot[0][0]                        
__________________________________________________________________________________________________
dense (Dense)                   (None, 500)          512500      flatten[0][0]                    
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 1)            501         dense[0][0]                      
==================================================================================================
Total params: 597,001
Trainable params: 597,001
Non-trainable params: 0
__________________________________________________________________________________________________

(7) 拟合模型:

model.fit([ratings.User2,ratings.Movies2], ratings.rating,
            epochs=50,
            batch_size=128)

(8) 提取每个用户或电影的向量:

# Extracting user vectors
model.get_weights()[0]
# Extracting movie vectors
model.get_weights()[1]

(9) 最后,我们将验证相似的电影是否具有相似的嵌入。在计算嵌入之间的相似度时,我们通常使用余弦相似度进行度量。选择第 600 个电影,余弦相似度计算如下:

from sklearn.metrics.pairwise import cosine_similarity
print(np.argmax(cosine_similarity(model.get_weights()[1][600].reshape(1,-1),model.get_weights()[1][:600].reshape(600,32))))

根据以上代码,我们可以计算出与第 600 个位置的电影最相似的 ID

89

查看电影ID列表,可以直观地看出,与第 600 个电影最相似的电影确实是第 89 个电影。

相关链接

Keras深度学习实战(1)——神经网络基础与模型训练过程详解
Keras深度学习实战(2)——使用Keras构建神经网络
Keras深度学习实战(7)——卷积神经网络详解与实现
Keras深度学习实战(16)——自编码器详解

keras深度学习实战——基于编码器-解码器的机器翻译模型(代码片段)

Keras深度学习实战——基于编码器-解码器的机器翻译模型0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.基于编码器-解码器结构的机器翻译模型2.1基于编码器-解码器体系结构2.2基于注意力机制的编码器-解码器体系结构小结... 查看详情

keras深度学习实战(39)——音乐音频分类(代码片段)

Keras深度学习实战(39)——音乐音频分类0.前言1.数据集与模型分析1.1数据集分析1.2模型分析2.歌曲流派分类模型2.1数据加载与预处理2.2模型构建与训练3.聚类分析小结系列链接0.前言音乐音频分类技术能够基于音乐内容为... 查看详情

keras深度学习实战(24)——从零开始构建单词向量(代码片段)

Keras深度学习实战(24)——从零开始构建单词向量0.前言1.单词向量1.1Word2Vec原理1.2构建单词向量1.3神经网络架构2.使用Keras从零开始构建单词向量3.测量单词向量之间的相似度小结系列链接0.前言在解决文本相关问题时,传统方法... 查看详情

keras深度学习实战(16)——自编码器详解(代码片段)

Keras深度学习实战(16)——自编码器详解0.前言1.编码的必要性1.1对文本进行编码1.2对图像进行编码2.使用自编码器编码图像2.1自编码器模型分析2.2原始自编码器2.2多层自编码器2.3卷积自编码器3.自编码器应用3.1低维潜编... 查看详情

keras深度学习实战(41)——语音识别(代码片段)

Keras深度学习实战(41)——语音识别0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.语音识别模型2.1数据加载与预处理2.2模型构建与训练小结系列链接0.前言语音识别(AutomaticSpeechRecognition,ASR,或称语音转录文本)... 查看详情

keras深度学习实战(24)——从零开始构建单词向量(代码片段)

Keras深度学习实战(24)——从零开始构建单词向量0.前言1.单词向量1.1Word2Vec原理1.2构建单词向量1.3神经网络架构2.使用Keras从零开始构建单词向量3.测量单词向量之间的相似度小结系列链接0.前言在解决文本相关问题时ÿ... 查看详情

keras深度学习实战——新闻文本分类(代码片段)

Keras深度学习实战(9)——新闻文本分类0.前言1.新闻文本分类任务与神经网络模型分析1.1数据集1.2神经网络模型2.使用神经网络进行新闻文本分类小结系列链接0.前言在先前的应用实战中,我们分析了结构化的数据集&... 查看详情

keras深度学习实战(37)——手写文字识别(代码片段)

Keras深度学习实战(37)——手写文字识别0.前言1.手写文字识别相关背景1.1Connectionisttemporalclassification(CTC)1.2解码CTC1.3计算CTC损失值2.模型与数据集分析2.1数据集分析2.2模型分析3.实现手写文字识别模型3.1数据集加载与预处... 查看详情

keras深度学习实战(26)——文档向量详解(代码片段)

Keras深度学习实战(26)——文档向量详解0.前言1.文档向量基本概念2.神经网络模型与数据集分析2.1模型分析2.2数据集介绍3.利用Keras构建神经网络模型生成文档向量小结系列链接0.前言在《从零开始构建单词向量》一节中,我们... 查看详情

keras深度学习实战(10)——迁移学习(代码片段)

Keras深度学习实战(10)——迁移学习0.前言1.迁移学习1.1迁移学习原理1.2ImageNet数据集介绍2.利用预训练VGG16模型进行性别分类2.1VGG16架构2.2微调模型2.3错误分类的图片示例小结系列链接0.前言在《卷积神经网络的局限性》... 查看详情

keras深度学习实战(38)——图像字幕生成(代码片段)

Keras深度学习实战(38)——图像字幕生成0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.实现图像字幕生成模型2.1数据集加载与预处理2.2模型构建与训练3.使用束搜索生成字幕3.1束搜索原理3.2利用束搜索改进预测结... 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型,其... 查看详情

keras深度学习实战——车辆转弯角度预测(代码片段)

Keras深度学习实战——车辆转弯角度预测0.前言1.数据集与模型分析1.1模型分析1.2数据集分析2.车辆转弯角度预测2.1数据集读取与预处理2.2模型构建预训练2.3模型测试相关链接0.前言自动驾驶已经引发了各界的广泛关注,无人驾... 查看详情

keras深度学习实战(18)——语义分割详解(代码片段)

Keras深度学习实战(18)——语义分割详解0.前言1.语义分割基本概念2.模型与数据集分析2.1模型训练流程2.2模型输出3.实现语义分割模型3.1加载数据集3.2模型构建与训练小结系列链接0.前言在《使用U-Net架构进行图像分割》... 查看详情

keras深度学习实战(39)——音乐音频分类

Keras深度学习实战(39)——音乐音频分类0.前言1.数据集与模型分析1.1数据集分析1.2模型分析2.歌曲流派分类模型2.1数据加载与预处理2.2模型构建与训练3.聚类分析小结系列链接0.前言音乐音频分类技术能够基于音乐内容为音乐添... 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型࿰... 查看详情

keras深度学习实战(32)——基于lstm预测股价(代码片段)

Keras深度学习实战(32)——基于LSTM预测股价0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.基于长短时记忆网络LSTM预测股价2.1根据最近五天的股价预测股价2.2考虑最近五天的股价和新闻数据小结系列链接0.前言股价... 查看详情

keras深度学习实战(28)——利用单词向量构建情感分析模型(代码片段)

Keras深度学习实战(28)——利用单词向量构建情感分析模型0.前言1.模型与数据集分析1.1模型分析1.2数据集分析2.情感分析模型2.1使用CBOW模型获取单词向量2.2构建并训练情感分析模型小结系列链接0.前言在获取单词向量的相关博... 查看详情