发布于: Jun 23, 2022

将数据添加至 Personalize:

在本文中,我们将创建一个包含交互数据集与项目数据集(项目元数据)的数据集组。关于创建数据集组的相关说明,请参阅入门教程(控制台)。

要创建一个交互数据集,请使用以下 schema 并导入 bandits-demo-interactions.csv 文件,此文件为综合电影评分数据集:
{
    "type": "record",
    "name": "Interactions",
    "namespace": "com.amazonaws.personalize.schema",
    "fields": [
        {
            "name": "USER_ID",
            "type": "string"
        },
        {
            "name": "ITEM_ID",
            "type": "string"
        },
        {
            "name": "EVENT_TYPE",
            "type": "string"
        },
        {
            "name": "EVENT_VALUE",
            "type": ["null","float"]
        },
        {
            "name": "TIMESTAMP",
            "type": "long"
        },
        {
            "name": "IMPRESSION",
            "type": "string"
        }
    ],
    "version": "1.0"
}

现在,您可以选择将印象(impression)信息添加至 Amazon Personalize 。所谓印象,是指用户与特定项目交互时显示出的项目列表。以下截屏展示了与印象数据进行的部分交互。

印象的表现形式为通过管道进行分隔的项目 ID 的有序列表。以上截屏中的第一行数据显示,当 user_id 1 为项目 item_id 1270 评分时,则用户将在实际展示中看到 1270, 1...9 的项目显示顺序。向用户推荐的项目和用户与之交互的项目之间的对比,能够帮助我们不断改进以生成更好的推荐结果。

Amazon Personalize 提供两种印象信息输入模式:

• 显式印象——由您手动记录并发送至 Personalize 的印象。以上示例中包含的即为显式印象。
• 隐式印象——用户从 Amazon Personalize 处收取到的推荐项目列表。

Amazon Personalize 现在能够在每一组推荐内容返回一条 RecommendationID。如果大家没有在生成用户体验时更改推荐的顺序或内容,即可直接通过 RecommendationID 引用该印象,而无需单独发送 ItemID 列表(显式印象)。如果同时为交互提供显式与隐式印象,则显式印象优先。您还可以通过 putEvents API 发送隐式与显式推荐。关于更多详细信息,请参阅我们的说明文档。

我们可以按照类似的步骤创建项目数据集,并使用包含电影元数据的  bandits-demo-items.csv 文件导入数据。我们为项目数据集中使用一个可选的保留关键字 CREATION_TIMESTAMP,借此帮助 Amazon Personalize 更好地计算各项目的新旧程度并相应地调整建议。在使用自有数据进行建模时,建议大家在此字段中记录首次向用户提供该项目的时间戳。我们将从数据集中最新一次交互时间戳作为参考点,推断特定项目的新旧程度。
如果不提供 CREATION_TIMESTAMP,则该模型会从交互数据集中推理出此信息,并使用当前项目的最早交互时间戳作为相应的发布日期。如果某个项目没有交互,则其发布日期将被设置为训练集中最近一次交互的时间戳,而新旧程度(或称年龄)将被设定为 0 以代表全新项。

本文中使用的数据集涵盖 1931 部电影,其中191部拥有创建时间戳,即交互数据集中最后一次交互的时间戳。这191个新项目亦被称为冷项目,且在数据集内的标签编号大于 1800。这套项目数据集的 schema 如下所示:

{
    "type": "record",
    "name": "Items",
    "namespace": "com.amazonaws.personalize.schema",
    "fields": [
        {
            "name": "ITEM_ID",
            "type": "string"
        },
        {
            "name": "GENRES",
            "type": ["null","string"],
            "categorical": true
        },
        {
            "name": "TITLE",
            "type": "string"
        },
        {
            "name": "CREATION_TIMESTAMP",
            "type": "long"
        }
    ],
    "version": "1.0"}
在数据集导入作业完成之后,接下来就是对模型进行训练。
1. 在 Solutions 选项卡上,选择 Create solution 创建解决方案。
2. 选择新的 amazon-user-personalization recipe。
新的 recipe 有效地将深度学习模型(RNN)与老虎机(bandits)结合起来,为您提供更加准确的用户建模(高相关性)与良好的探索效率。
1. 直接保留 Solution configuration 部分所有内容的默认值,而后点击 Next。
2.  在Create solution version页面,选择 Finish 以启动训练。

在训练结束之后,大家可以导航至 Solution Version Overview 页面以查看离线指标。在某些情况下,与在 HRNN-Metadata recipe 上训练出的模型相比,示例模型的准确率指标(例如 mrr 或 precision@k)以及 coverage 可能会略有下降。这是因为新的 amazon-user-personalization recipe 给出的推荐不仅仅是基于先前经验的利用(exploitation),还可能会选择牺牲短期利益以获得长期回报。离线指标的计算使用各参数默认值(explorationWeight, explorationItemAgeCutoff),这些参数会影响项目的探索。大家可以在下面的小节中,了解与此相关的更多详细信息。

经过几轮再训练之后,准确率指标与项目覆盖率都将有所增加,这时全新的 amazon-user-personalization recipe 的性能应该优于单纯基于历史记录的 HRNN-Metadata recipe。

在 Amazon Personalize 中,我们使用 campaign 向用户提供推荐信息。在本节中,我们将通过上一节中创建完成的解决方案构建两项 campaign,并演示不同程度的探索带来的影响。
要创建新的 campaign,请完成以下操作步骤:
1. 在 Campaigns 选项卡上, 选择 Create Campaign。
2. 在 Campaign name 部分,输入一项名称。
3. 在 Solution 部分, 选择 user-personalization-solution。
4. 在 Solution version ID 部分, 选择使用 amazon-user-personalization recipe 的解决方案版本。

现在,您可以为 campaign设定其他配置,借此调整 Amazon Personalize 对项目推荐的探索方式,进而修改推荐结果。请注意,这些设置选项仅适用于指定 user-personalization recipe 作为解决方案版本的 campaign。具体配置选项如下:
 
• explorationWeight – explorationWeight 的值越高,则代表探索度越高;展示更少的新项目被推荐的几率更大。值为 0 代表不进行探索,结果按照相关性进行排名。您可以在[0,1]范围内设置此项参数,其默认值为 0.3。
• explorationItemAgeCutoff – 相对于训练数据内最新交互(事件)时间戳的最大持续时长(单位为天)。例如,如果您将 explorationItemAgeCutoff 设置为 7,则超过或等于 7 天的项目将不再被视为冷项目,系统不再对这些项目进行探索。当然,在推荐列表中仍会出现部分超过或等于 7 天的项目,这是因为其与用户的喜好相关,即使没有探索的帮助,推荐质量也很好。此参数的默认值为 30,您可以将其设置为大于 0 的任何值。
 
为了演示探索效果,我们在这里创建两项campaign。
 
1. 在首个 campaign 中,将 Exploration weight 设置为 0。
2. 将 Exploration item age cut off 保留为默认值,即 30.0。
3. 选择 Create campaign。

重复以上步骤以创建第二项 campaign,但请注意为其指定不同的名称,并将探索权重更改为1。

在创建或更新您的 campaign之后,接下来即可获取面向用户的推荐项目,为项目获得相似的推荐,或者对用户的输入项目列表进行重新排序。
1. 在 Campaigns 详情页面,为您的用户个性化 campaign 输入用户 ID。

以下截屏为带有 GetRecommendations 调用结果的 campaign 详情页面,其中包括推荐项目与推荐 ID。您可以将其作为隐式印象使用。Amazon Personalize 服务会在训练过程中对推荐 ID 进行解释。

1. 输入在交互数据集内存在交互的用户 ID。在本文示例中,我们为用户 ID 1 获取推荐内容。
2. 找到探索权重为 0 的 campaign,在其 campaign 详情页面中选择 Detail。
3. 在 User ID 部分,输入 1。
4. 选择 Get recommendations。

以下截屏为探索权重为 0 的 campaign;可以看到其中的推荐项目属于旧项目,即用户已经观看或评价过这些电影。
以下截屏为同一用户并且探索权重设置为 1 的 campaign 推荐结果。可以看到,推荐内容中新近添加的、用户较少评分的电影占比更高。此外,相关性(即利用)与探索之间的权衡,将根据新项目冷的程度自动调整,并结合用户的最新反馈。
针对已探索项目进行的新一轮交互,将带来关于项目质量的重要反馈,您可以使用此反馈来更新对该项目的探索。在这里,我们建议每小时更新一次模型,借此调整后续项目的探索。
 
要对模型(solutionVersion)进行更新,您可以调用 createSolutionVersion API 并将 trainingMode 设置为 UPDATE。这项操作将使用最新项目信息更新模型,并根据来自用户的隐式反馈调整探索。这种方法与将 trainingMode 设定为 FULL 的全量模型训练有所不同。本文建议大家尽量减少对模型的全量训练,一般每 1~5 天进行一次即可。在创建新的 solutionVersion 更新后,您可以同步更新 campaign 以获取新的推荐结果。
 
以下代码将引导您完成这些步骤:
#Updating the solutionVersion (model) and Campaign
import time
def wait_for_solution_version(solution_version_arn):
    status = None
    max_time = time.time() + 60*60 # 1 hour
    while time.time() < max_time:
        describe_solution_version_response = personalize.describe_solution_version(
            solutionVersionArn = solution_version_arn
        )
        status = describe_solution_version_response["solutionVersion"]["status"]
        print("SolutionVersion: {}".format(status))

        if status == "ACTIVE" or status == "CREATE FAILED":
            break
        time.sleep(60) 
        def update_campaign(solution_arn, campaign_arn):
    create_solution_version_response = personalize.create_solution_version(
        solutionArn = solution_arn, 
        trainingMode='UPDATE')
    new_solution_version_arn = create_solution_version_response['solutionVersionArn']
    print("Creating solution version: {}".format(new_solution_version_arn))
    wait_for_solution_version(new_solution_version_arn)
    personalize.update_campaign(campaignArn=campaign_arn, solutionVersionArn=new_solution_version_arn)
    print("Updating campaign...")
# Update the campaign every hourwhile True:
    dt = time.time() + 60*60
    try:
        solution_arn = <your solution arn>
        campaign_arn = <your campaign arn>
        update_campaign(solution_arn, campaign_arn)
    except Exception as e:
        print("Not able to update the campaign: {}".format(str(e)))
    while time.time() < dt:
        time.sleep(1)

我们将以最佳实践为本文作结。在使用新的‘amazon-user-personalization’ recipe时,请务必关注以下几项最佳实践。

1. 别忘了进行重新训练。通过“UPDATE”模式进行重新训练,将帮助您的模型充分了解“冷”项目并在推荐结果中加以体现。在推理期间,模型会向用户推荐“冷”项目并收集用户反馈,重新训练则会引导模型利用这些反馈结果探索“冷”项目的具体属性。如果不进行重新训练,那么模型将永远无法在项目元数据之外,了解关于各“冷”项目的更多细节信息,深入探索自然也就无从谈起。
2. 提供良好的项目元数据。即使进行探索,项目元数据在冷项目的推荐当中仍然至关重要。模型将从交互与项目元数据这两种资源中学习项目属性;由于“冷”项目没有任何交互记录,因此模型只能探索相应的元数据以完成初步学习。
3. 通过项目数据集中的“CREATION_TIMESTAMP”提供准确的项目发布日期。此信息用于对项目的时间影响进行建模,保证我们不会对旧项目进行探索。

相关文章