使用 AWS Sagemaker 系列文章:
第一篇:使用 AWS Sagemaker 训练因子分解机模型并应用于推荐系统(本博文)
第二篇:使用 AWS Sagemaker 部署的终端节点进行推荐预测的常用场景
————
在线服务和应用中,经常遇到需要对用户历史行为进行分析并预测,典型的案例如页面点击预测及推荐系统。这些案例的特点是历史数据集非常庞大,而且大多数情况,数据集是稀疏的。让我们以电影点评网站为例来理解稀疏数据集。在电影点评网站中,拥有大量的用户以及大量的电影,然而几乎不可能实现每个用户对每个电影都进行点评或打分。因此如果我们以用户为行,以电影为列,构建一个表格,对该用户点评过的电影单元格置 1,未点评过的置 0,我们可以发现,该表格中绝大部分数据都将是 0。这就是稀疏数据集的典型例子。
针对稀疏数据集,因子分解机(Factorization Machines,FM)是比较有效的算法模型。
直观来说因子分解机可以考虑为由用户(User)为行、电影(Movie)为列构成的矩阵 R 可以表示为一个用户(User)为行、K 列特征构成的矩阵 P 与电影(Movie)为行、K 列特征构成的矩阵 Q 的转置的乘积。其中的 K 即潜藏特征值,可以将他理解为用户与电影之间的关系。在因子分解机中,这一值是可以自行设定的。算法的主要目的就是计算出 P 和 Q 矩阵,并使 P 与 QT 的乘积尽可能与 R 一致。
本次实验采用国内用户对大量国内外电影的评论作为训练数据集,利用 AWS SageMaker 自带的因子分解机算法构建模型,通过 SageMaker 的超参调优服务观察参数调整对模型表现的影响。最后,以实际应用中经常会遇到的用法演示模型的预测结果。本次实验全部使用 Python3.6 完成,在 SageMaker 中选用 conda_python3 的 Kernel。
数据准备阶段
本次数据总量大约为 396 万条,用户数 49 万,电影数 3 万多。考虑到演示的目的和运算的效率,训练模型时使用其中 10 万条数据的采样。
In [3]:
(3963891, 3)
490790
33345
首先我们对数据进行基本的观察。可以看到这 10 万条数据包含 53902 个用户和 26004 部电影。随后我们对数据集进行训练集和测试集的拆分,这里采用训练数据:测试数据 = 4:1 的比例进行拆分。
In [4]:
53902
26004
(85623, 3) (21406, 3)
MovieID Rate UserId
63287 1296827 10 BloodzBoi
73804 3564327 6 LadyHoney
76527 6874441 8 49886917
71411 3152563 8 feathercat
64499 2004250 6 jingtianwst83
42130 3230459 6 funni
88502 3313801 6 chrisocean
79349 3072140 0 lala1123
21431 2053746 6 145992805
39240 1464338 8 HeroineDaode
MovieID Rate UserId
44496 26304167 8 152833029
11855 1299900 8 leonah
13955 26085750 2 49298107
27112 4202982 8 Kylin-2015
28103 4739952 10 likong
53598 3443393 4 3832465
65338 2052363 6 1926472
1116 6129707 8 vero_nicat
38854 26841337 2 158039357
78721 1307026 8 TowaErio
为用户和电影分别建立字典(Python Dictionary)
数据集中的用户 ID 和电影 ID 均为随机字符串,为了方便我们后续建立有序矩阵以及模型训练后预测结果的数据对应,我们首先为用户和电影分别建立由 0 开始的 index 序列,并使其与 ID 字符串对应。
In [5]:
建立稀疏矩阵(Sparse Matrix)和标签向量(Label Vector)
因子分解机的训练是针对稀疏矩阵的,因此我们要将数据集中电影、评分、用户的序列转为稀疏矩阵,并根据用户评分的结果生成标签向量。我们使用 Python Scipy 模块中的 lil_matrix 来构建。
生成的矩阵应当是每一个用户 ID 作为单独一列、每一部电影在所有用户列之后也作为单独一列,针对原数据集中每行的数据,在对应的用户列和电影列置 1。标签向量以用户评分为基准,我们设定用户评分大于等于 6 的为“喜爱”,并在对应的标签向量位置置 1,反之为“不喜爱”,标签向量相应位置置 0。
训练集和测试集均进行同样的操作。
In [222]:
(85623, 79906)
(85623,)
(21406, 79906)
(21406,)
(85623, 79906) (21406, 79906)
(85623,) (21406,)
我们获得了训练集为 85623✖️79906 的矩阵,训练标签向量为 85263 元素;测试集为 21406✖️79906 矩阵,其标签向量为 21406 元素。
转换稀疏矩阵为 protobuf 格式,并保存到 S3
稀疏矩阵中绝大多数元素均为 0,如果直接保存稀疏矩阵,会占用大量的存储空间,因此我们将其转为 protobuf 格式的数据,并保存到 S3。
In [224]:
程序输出中 Output 的内容是模型训练完成后,保存模型代码的位置。
FM 模型训练
FM 是 SageMaker 自带的算法之一,因此通过 SageMaker 训练模型非常容易。首先我们需要引入 SageMaker 的 SDK,并建立 SageMaker 的 session、定义位于该 Region 的因子分解机算法 Container 以及获取 SageMaker 的运行角色。
In [225]:
随后我们定义 FM 训练需要的一些参数。首先是环境参数,包括之前定义好的 Container、角色、输出位置和 session、还包括训练使用的 EC2 实例,本例中采用“ml.c4.xlarge”来训练。
之后,我们需要定义 FM 算法的超参(Hyperparameters)。在本例中特征列为用户数与电影数的总和 79906、预测方式为二分类(即结果为判断“喜爱”或是“不喜爱”)、最小批量为 1000、epoch 时期为 50 次。其中 num_factors 即为在算法介绍中提到的潜藏特征 K 的数量,根据 SageMaker 官方文档的说明,建议在 2-1000 之间,通常 64 为最优值,因此,我们也设为 64。
最后为模型提供训练集和测试集在 S3 中的位置,训练就开始了。
In [226]:
INFO:sagemaker:Creating training-job with name: factorization-machines-2018-12-18-03-18-50-388
2018-12-18 03:18:50 Starting – Starting the training job…
2018-12-18 03:18:56 Starting – Launching requested ML instances……
2018-12-18 03:19:58 Starting – Preparing the instances for training…
2018-12-18 03:20:45 Downloading – Downloading input data…
2018-12-18 03:20:55 Training – Downloading the training image…
Docker entrypoint called with argument(s): train
[12/18/2018 03:22:09 INFO 139830159329088] #quality_metric: host=algo-1, test binary_classification_accuracy=0.736288890965
[12/18/2018 03:22:09 INFO 139830159329088] #quality_metric: host=algo-1, test binary_classification_cross_entropy=0.548373071499
[12/18/2018 03:22:09 INFO 139830159329088] #quality_metric: host=algo-1, test binary_f_1.000=0.84806072188
[2018-12-18 03:22:09.767] [tensorio] [info] data_pipeline_stats={“name”: “/opt/ml/input/data/test”, “epoch”: 1, “duration”: 366, “num_examples”: 22}
[2018-12-18 03:22:09.767] [tensorio] [info] data_pipeline_stats={“name”: “/opt/ml/input/data/test”, “duration”: 40228, “num_epochs”: 2, “num_examples”: 23}
[2018-12-18 03:22:09.784] [tensorio] [info] data_pipeline_stats={“name”: “/opt/ml/input/data/train”, “epoch”: 50, “duration”: 1287, “num_examples”: 86}
[2018-12-18 03:22:09.784] [tensorio] [info] data_pipeline_stats={“name”: “/opt/ml/input/data/train”, “duration”: 39923, “num_epochs”: 51, “num_examples”: 4301}
Billable seconds: 92
模型训练完成了。在模型训练结束后的总结中,我们可以看到几个重要的指标:
模型训练计费时间 92 秒,所以并不会花很多钱;
模型的二分准确度为 73.62%
接下来,我们考虑一下应用 SageMaker 的超参调优(Hyperparameters Tuning)来尝试其他的超参设置是否可以获得更好的二分准确度。SageMaker 的超参调优可以通过 SageMaker 的 Console 直接配置完成。简单来讲,就是首先设定目标,本例中我们希望最大化(Maximize)模型二分准确度。之后给予可调参数的变动范围,本例中我们希望测试 mini batch size 和 epochs 的设置是否可以提升结果表现。最后定义训练集、测试集、算法的相应位置,以及优化任务运行的次数(最大为 100),即可开始。
当优化任务全部运行完成后,我们可以获得表现最好的模型的数据,如图
在这一参数配置下,模型的二分准确度提升为 76.2%。应用这一超参配置训练模型,并部署为 Endpoint。Endpoint 可以理解为模型基于 http 访问的 API 接口,有了 Endpoint 就可以进行预测服务了。
In [227]:
我们的模型部署完成,Endpoint 名称为“factorization-machines-2018-12-18-05-47-26-108”。之后我们可以通过这个名称来调用 Endpoint 完成预测任务。
后续我们会继续利用已部署的终端节点 Endpoint 对常见的应用场景进行预测。
使用 AWS Sagemaker 系列文章:
第一篇:使用AWS Sagemaker训练因子分解机模型并应用于推荐系统(本博文)
第二篇:使用AWS Sagemaker部署的终端节点进行推荐预测的常用场景
————
作者介绍:
崔辰
AWS 大中华区创新中心技术业务拓展经理。加入 AWS 之前,崔辰在中国惠普、IBM、微软以及海航科技等公司担任过售前技术顾问、市场经理和战略合作经理等职务。在 10 多年的科技领域工作经历中,崔辰服务过众多企业级客户。
本文转载自 AWS 技术博客。
原文链接:
https://amazonaws-china.com/cn/blogs/china/aws-sagemaker-system-recommend-use/
评论