百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

TensorFlow推荐系统(一)

bigegpt 2024-08-08 12:06 2 浏览

1 前言

我们浏览在各个平台时会发现"为你推荐"功能。比如YouTube推荐爱看的视频,音乐软件为你提供你可能喜欢的音乐等。其实这一功能的背后涉及的原理就是人工智能的推荐系统。今天我们将介绍TensorFlow推荐系统模型的库——TensorFlow Recommenders(TFRS)[1]

对TensorFlow感兴趣的朋友们,还可以回顾我们之前相关的文章:

  • Keras各种Callbacks介绍
  • 使用tf.keras自定义模型
  • 在Apple Silicon Macs上安装TensorFlow
  • 读《30天吃掉那只TensorFlow2》

2 推荐原理

这里我们用电影推荐的例子来讲解推荐系统的原理。

对于现有的四个用户和五部类型不同的电影,首先,我们需要创建用户画像和定义电影类别,这一步是为了区分数据,将现实特征转化为可计算的变量。对于现有的用户数据和电影数据,我们如何给用户D推荐她可能喜欢的电影呢?

如下图所示,这里我们为用户和电影两个变量各自创建两个维度的矩阵。对于用户,我们将定义是否偏爱儿童电影(-1表示很喜欢儿童电影,1则相反)和是否偏爱火爆电影(1表示很喜欢火爆电影,-1相反);对于电影,这里定义是否是儿童电影(-1表示儿童电影,1则表示非儿童电影)和是否是火爆电影(1表示火爆电影,-1则反然)。

可以看出,用户A很喜欢看儿童且火爆的电影,这就是基于两个维度的User Embedding;而《怪物史莱克》在这里被定义为儿童且火爆的电影,这一过程就是Movie Embedding。值得一提的是,在搭建模型时,Embedding的维度不只是二维的,往往是多维的矩阵来表示变量。

接下来,用矩阵分解进行协同过滤计算预测的反馈矩阵。如下图所示,U代表用户矩阵,V代表电影候选条目的矩阵,计算的A值就是预测的反馈值。所以协同过滤就是依据用户和候选条目之间的相似度来进行推荐。

在使用矩阵分解进行协同过滤时,为了减少目标函数的预测误差,官方解释使用随机梯度下降Stochastic Gradient Descent(SGD)或加权交替最小平方算法Weighted Alternating Least Squares(WALS)两种方式。

值得一提的是,WALS是专门解决推荐系统而创建的新算法,与前者不同,WALS每次迭代时,固定U的值来确定V,再固定V的值来确定U。两种方法各有利弊,这里不再详细介绍了,感兴趣的朋友可以学习一下矩阵分解[2]的官方资料.

3 源码解析

现实推荐系统分为两大部分:

  1. 从大量的潜在推荐条目中选择可能性比较大的items,这一过程叫做信息检索(retrieval)。
  2. 对于提取模型的结果,我们还需要排序来缩小选择最有可能被用户选择的items,这一过程叫做rank。

这一部分,我们先介绍第一阶段的信息提取模型。信息提取模型又包含两个子模型,查询模型和候选模型,对应上述的例子就是用户矩阵和候选条目矩阵,通过计算两个子模型的乘积,得到的query-candidate affinity score就是反映查询和候选条目之间的匹配程度,即用户喜欢推荐条目的可能性。

# Dependency install
!pip install -q tensorflow-recommenders
!pip install -q --upgrade tensorflow-datasets

import os
import pprint
import tempfile
from typing import Dict, Text
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
## import tensorflow recommenders API
import tensorflow_recommenders as tfrs

从网上加载MovieLens数据:

# Ratings data.
ratings = tfds.load("movielens/100k-ratings", split="train")
# Features of all the available movies.
movies = tfds.load("movielens/100k-movies", split="train")
## Note: MovieLens 没有事先准备好数据集,所有的数据都在train data中。
# 查看数据rating和movies
for x in ratings.take(2).as_numpy_iterator():
  pprint.pprint(x)
#{'movie_title': b"One Flew Over the Cuckoo's Nest (1975)", 'user_id': b'138'}
#{'movie_title': b'Strictly Ballroom (1992)', 'user_id': b'92'}

for x in movies.take(2).as_numpy_iterator():
  pprint.pprint(x)
#b'You So Crazy (1994)'
#b'Love Is All There Is (1996)'

在提取模型中,我们先处理rating数据集,并选择user_idmovie_title来定义用户画像。

ratings = ratings.map(lambda x: {
    "movie_title": x["movie_title"],
    "user_id": x["user_id"],
})
movies = movies.map(lambda x: x["movie_title"])

设定训练集和测试数据集:

tf.random.set_seed(42)
shuffled = ratings.shuffle(100_000, seed=42, reshuffle_each_iteration=False)

train = shuffled.take(80_000)
test = shuffled.skip(80_000).take(20_000)
# 为变量数值做mapping
movie_titles = movies.batch(1_000)
user_ids = ratings.batch(1_000_000).map(lambda x: x["user_id"])

unique_movie_titles = np.unique(np.concatenate(list(movie_titles)))
unique_user_ids = np.unique(np.concatenate(list(user_ids)))

unique_movie_titles[:10]

#array([b"'Til There Was You (1997)", b'1-900 (1994)',
       #b'101 Dalmatians (1996)', b'12 Angry Men (1957)', b'187 (1997)',
       #b'2 Days in the Valley (1996)',
       #b'20,000 Leagues Under the Sea (1954)',
       #b'2001: A Space Odyssey (1968)',
       #b'3 Ninjas: High Noon At Mega Mountain (1998)',
       #b'39 Steps, The (1935)'], dtype=object)

定义用户模型和电影模型:

#设定embedding维度
embedding_dimension = 32
#设定用户模型
user_model = tf.keras.Sequential([
  tf.keras.layers.StringLookup(
      vocabulary=unique_user_ids, mask_token=None),
  # We add an additional embedding to account for unknown tokens.
  tf.keras.layers.Embedding(len(unique_user_ids) + 1, embedding_dimension)
])
#设定电影模型
movie_model = tf.keras.Sequential([
  tf.keras.layers.StringLookup(
      vocabulary=unique_movie_titles, mask_token=None),
  tf.keras.layers.Embedding(len(unique_movie_titles) + 1, embedding_dimension)
])

关于评估标准,TensorFlow使用的是FactorizedTopK去衡量预测能力,

metrics = tfrs.metrics.FactorizedTopK(
  candidates=movies.batch(128).map(movie_model)
)

task = tfrs.tasks.Retrieval(
  metrics=metrics
)

将模型函数和损失函数封装起来:

class MovielensModel(tfrs.Model):

  def __init__(self, user_model, movie_model):
    super().__init__()
    self.movie_model: tf.keras.Model = movie_model
    self.user_model: tf.keras.Model = user_model
    self.task: tf.keras.layers.Layer = task

  def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:
    # We pick out the user features and pass them into the user model.
    user_embeddings = self.user_model(features["user_id"])
    # And pick out the movie features and pass them into the movie model,
    # getting embeddings back.
    positive_movie_embeddings = self.movie_model(features["movie_title"])

    # The task computes the loss and the metrics.
    return self.task(user_embeddings, positive_movie_embeddings) 

训练并评估模型结果:

model = MovielensModel(user_model, movie_model)
model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.1))
#shuffle data and get samples
cached_train = train.shuffle(100_000).batch(8192).cache()
cached_test = test.batch(4096).cache()

model.fit(cached_train, epochs=3)
#使用test data evaluate
model.evaluate(cached_test, return_dict=True)
{'factorized_top_k/top_1_categorical_accuracy': 0.00044999999227002263,
 'factorized_top_k/top_5_categorical_accuracy': 0.004100000020116568,
 'factorized_top_k/top_10_categorical_accuracy': 0.01145000010728836,
 'factorized_top_k/top_50_categorical_accuracy': 0.09040000289678574,
 'factorized_top_k/top_100_categorical_accuracy': 0.19300000369548798,
 'loss': 28535.75390625,
 'regularization_loss': 0,
 'total_loss': 28535.75390625}

使用训练好的模型为user_id=9的用户推荐电影的预测:

# Create a model that takes in raw query features, and
index = tfrs.layers.factorized_top_k.BruteForce(model.user_model)
# recommends movies out of the entire movies dataset.
index.index_from_dataset(
  tf.data.Dataset.zip((movies.batch(100), movies.batch(100).map(model.movie_model)))
)
# Get recommendations.
_, titles = index(tf.constant(["9"]))
print(f"Recommendations for user 9: {titles[0, :3]}")

4 总结

TensorFlow 为机器学习提供了非常丰富且强大的资源,感兴趣的朋友可以将这些模型运用到现有的数据中,去探究一些有趣的惊喜吧!

希望这篇分享可以对你有所帮助,也欢迎各位留言讨论。

参考资料

[1]

TensorFlow Recommenders: https://www.tensorflow.org/recommenders?hl=en

[2]

Matrix Factorization: https://developers.google.com/machine-learning/recommendation/collaborative/matrix

相关推荐

【Docker 新手入门指南】第十章:Dockerfile

Dockerfile是Docker镜像构建的核心配置文件,通过预定义的指令集实现镜像的自动化构建。以下从核心概念、指令详解、最佳实践三方面展开说明,帮助你系统掌握Dockerfile的使用逻...

Windows下最简单的ESP8266_ROTS_ESP-IDF环境搭建与腾讯云SDK编译

前言其实也没啥可说的,只是我感觉ESP-IDF对新手来说很不友好,很容易踩坑,尤其是对业余DIY爱好者搭建环境非常困难,即使有官方文档,或者网上的其他文档,但是还是很容易踩坑,多研究,记住两点就行了,...

python虚拟环境迁移(python虚拟环境conda)

主机A的虚拟环境向主机B迁移。前提条件:主机A和主机B已经安装了virtualenv1.主机A操作如下虚拟环境目录:venv进入虚拟环境:sourcevenv/bin/active(1)记录虚拟环...

Python爬虫进阶教程(二):线程、协程

简介线程线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能...

基于网络安全的Docker逃逸(docker)

如何判断当前机器是否为Docker容器环境Metasploit中的checkcontainer模块、(判断是否为虚拟机,checkvm模块)搭配学习教程1.检查根目录下是否存在.dockerenv文...

Python编程语言被纳入浙江高考,小学生都开始学了

今年9月份开始的新学期,浙江省三到九年级信息技术课将同步替换新教材。其中,新初二将新增Python编程课程内容。新高一信息技术编程语言由VB替换为Python,大数据、人工智能、程序设计与算法按照教材...

CentOS 7下安装Python 3.10的完整过程

1.安装相应的编译工具yum-ygroupinstall"Developmenttools"yum-yinstallzlib-develbzip2-develope...

如何在Ubuntu 20.04上部署Odoo 14

Odoo是世界上最受欢迎的多合一商务软件。它提供了一系列业务应用程序,包括CRM,网站,电子商务,计费,会计,制造,仓库,项目管理,库存等等,所有这些都无缝集成在一起。Odoo可以通过几种不同的方式进...

Ubuntu 系统安装 PyTorch 全流程指南

当前环境:Ubuntu22.04,显卡为GeForceRTX3080Ti1、下载显卡驱动驱动网站:https://www.nvidia.com/en-us/drivers/根据自己的显卡型号和...

spark+python环境搭建(python 环境搭建)

最近项目需要用到spark大数据相关技术,周末有空spark环境搭起来...目标spark,python运行环境部署在linux服务器个人通过vscode开发通过远程python解释器执行代码准备...

centos7.9安装最新python-3.11.1(centos安装python环境)

centos7.9安装最新python-3.11.1centos7.9默认安装的是python-2.7.5版本,安全扫描时会有很多漏洞,比如:Python命令注入漏洞(CVE-2015-2010...

Linux系统下,五大步骤安装Python

一、下载Python包网上教程大多是通过官方地址进行下载Python的,但由于国内网络环境问题,会导致下载很慢,所以这里建议通过国内镜像进行下载例如:淘宝镜像http://npm.taobao.or...

centos7上安装python3(centos7安装python3.7.2一键脚本)

centos7上默认安装的是python2,要使用python3则需要自行下载源码编译安装。1.安装依赖yum-ygroupinstall"Developmenttools"...

利用本地数据通过微调方式训练 本地DeepSeek-R1 蒸馏模型

网络上相应的教程基本都基于LLaMA-Factory进行,本文章主要顺着相应的教程一步步实现大模型的微调和训练。训练环境:可自行定义,mac、linux或者window之类的均可以,本文以ma...

【法器篇】天啦噜,库崩了没备份(天啦噜是什么意思?)

背景数据库没有做备份,一天突然由于断电或其他原因导致无法启动了,且设置了innodb_force_recovery=6都无法启动,里面的数据怎么才能恢复出来?本例采用解析建表语句+表空间传输的方式进行...