Python 人工智能实战:智能推荐
作者:禅与计算机程序设计艺术
1.背景介绍
在互联网时代背景下,在线社交网络服务凭借其强大的社交属性与传播能力获得了快速发展的机遇与挑战;与此同时,在线教育平台凭借其优质的教育资源与便捷的服务模式也获得了快速发展;在线购物平台通过整合海量商品信息实现了精准营销;在线支付平台借助先进的结算技术保障了交易的安全性与便捷性;在线娱乐社区通过提供丰富的娱乐内容满足了用户的多样化需求;在线金融理财平台通过智能化的投资建议提升了用户体验;在线旅游平台通过全方位的信息服务提升了用户的旅游体验;在线医疗平台通过远程医疗降低了求医门槛提高了医疗服务效率
2.核心概念与联系
2.1 什么是推荐系统?
推荐系统(Recommendation System):基于用户的使用场景提供与其相关联的商品和服务的一种自动化决策支持工具体系。一般可分为静态与动态两大类模型进行设计与实现:其中静态模型主要关注于在特定时间点上用户的购买偏好特性,并采用在线或离线方式进行实现;而动态模型则侧重于分析用户的历史行为数据,并依赖于大数据分析、机器学习算法以及实时推送技术的支持来完成功能定位和价值评估任务
2.2 为何要用推荐系统?
很多应用场景都需要用到推荐系统:
- 基于用户的兴趣提供商品建议:包括电子商务平台(如淘宝网)、网络购物网站(如京东商城)、音乐流媒体服务(如网易云音乐)以及视频分享平台(如YouTube)等。
- 智能化搜索引擎结果优化:例如百度和谷歌的搜索结果展示中就已实现了智能化推荐系统。
- 个性化推送服务:例如网页或手机App中的"我可能喜欢"功能。
- 位置导向型个性化推送:例如门票销售网站或景点门票预订平台。
- 新闻阅读优化建议:由于每天浏览新闻会耗费时间和精力且效果有限,在此背景下开发新闻阅读优化方案显得尤为重要。通过分析用户的浏览历史记录信息并结合实时动态数据变化特征来实现精准化的新闻内容推送给用户。
2.3 协同过滤算法简介
协同过滤算法(Collaborative Filtering Algorithm)作为一种基础技术,在现代推荐系统中占据重要地位。该算法主要基于用户的互动历史与相似用户的互动数据。通过深入分析用户的互动模式与相似用户的互动特征进而完成精准的个性化推荐。
它的工作过程如下图所示:
流程:
- 用户在完成注册流程后录入个人信息及喜好标签后 系统将为其分配一个独一无二的用户名ID。
- 当消费者浏览商品详情时记录下其点击频率作为行为轨迹记录。
- 当平台向用户提供某款待购产品时 系统首先要判断该用户的登录状态 若当前状态在线 则调用数据库查询其最近浏览的历史产品列表 并结合相关联度较高的产品进行推荐 若此时状态为离线 则将随机展示若干待购产品供选择。
- 每当某件商品被消费者点击后 系统的数据库将自动更新该商品的相关统计数据 包括当前点击数 以及平均评价等参数 随后依据统计结果重新排列显示顺序。
协同过滤算法优缺点:
优点:
- 具有良好的效率和简洁性的算法在逻辑上非常直观,在计算速度上表现突出,并且操作简便。
- 该推荐系统能够在不依赖于大规模的数据建模的情况下运行良好。
- 针对多样化的需求设计而成的推荐系统具备广泛的适用性和强大的抗干扰能力。
- 且用户的偏好可以不断地改进并不断优化用户体验...具有很强的鲁棒性。
缺点:
- 算法无法准确捕捉用户的兴趣:当新的用户首次加入系统时(即新用户的首次加入),由于新用户的缺乏足够的历史行为数据(即新用户的初始状态尚不完善),可能导致一些不合适的推荐结果(即系统效果不佳)。
- 存在一定的冷启动问题:当新的用户出现时(即新用户的首次加入),因为缺乏足够的历史行为数据(即新用户的初始状态尚不完善),会导致系统效果不佳(即需要进行一定的 cold start 处理)。
2.4 常见的协同过滤算法
基于用户的协同过滤算法UserCF
该系统采用协同过滤方法对用户体验进行个性化推荐。具体而言,在具体实施时,该系统将所有用户划分为两组:一组为目标群体成员集合(即需要被推荐的对象),另一组为非目标群体成员集合(即未被选中作为对象的目标人群)。接着,在计算阶段,则对每个目标群体成员而言,在计算过程中,则会识别与其最接近的非目标群体成员,并评估这些非目标群体成员的相关互动行为。最后,在排序阶段,则根据各评估对象间的关联程度来排列商品列表,并完成最终推荐。
该方法的主要问题是两方面:首先是对计算相似性这一环节的处理过于简化,并未充分考虑实际应用中用户间的复杂互动关系;其次是在识别用户特征时存在局限性,未能充分挖掘出具有潜在商业价值的小众群体。
基于Item的协同过滤算法ItemCF
ItemCF算法亦称作物品聚类算法,在协同过滤领域具有重要地位。该方法通过计算物品间的相似度及其邻居的相似度来为用户提供推荐服务。具体而言,在这个过程中, 算法将所有商品划分为若干类别, 每个类别包含若干相关联的商品。针对每位目标用户, 该系统会计算他对各个商品的兴趣程度以及相邻商品的相关程度, 最后依据各用户的兴趣程度对商品进行排序并做排序处理
该方法的优势在于评估物品间的相似性相对简便,并且具备独特价值。然而其主要缺陷体现在计算相似性的方法过于简单化,并未能充分考虑实际中的复杂结构。
基于上下文的协同过滤算法
Context-Aware CF算法(CACF)通过识别出一个由用户最近点击的物品构成的集合U及其相关联的另一组物品R。该算法首先会对每个属于集合U的物品提取其上下文特征C(u),随后通过隐马尔科夫模型等模式识别技术从U中归纳潜在的物品关联关系。最终系统将基于这些归纳出的物品关联关系计算用户的兴趣偏好,并按兴趣程度对各项进行排序。
该方法的优势在于能够在处理海量数据时发现潜在的互动模式,并且同时也能识别物品间的错综复杂联系;其不足之处则体现在计算资源消耗以及响应速度方面仍需改进。
3.核心算法原理和具体操作步骤以及数学模型公式详细讲解
3.1 UserCF算法
基于UserCF算法的核心理念在于,在线识别并构建目标用户的个性化偏好体系。其主要流程包括首先筛选出与目标用户具有高度相似性的一群活跃用户群体;随后通过分析这些群体的历史点击数据来推断他们的兴趣倾向;在此基础上针对那些尚未被目标用户点击的商品进行分析和评估;最终实现精准的商品推荐。
3.1.1 数据准备
假设有位注册用户提供过服务,并且近期观看了三部影片《A》、《B》和《C》,为了提升用户体验,在推荐系统中需要帮助其他相似的注册用户提供个性化的观影建议。在观察期结束后,《A》一经开播即受关注,《B》同样获得了高播放量,《C》也得到了广泛的好评。如果进一步分析发现,《D》是该用户的最爱作品之一,并且基于用户的观看偏好特征,则将其划分为两组群体——目标观众群和目标物品群(这两类群体分别对应着)。数据表格如下:$
| A | B | C | D | |
|---|---|---|---|---|
| A | 1 | |||
| B | 1 | 1 | 1 | |
| C | 1 | 1 |
其中,0表示没有点击,1表示点击。
3.1.2 生成隐语义空间
为了评估用户间的相似性,则需将用户的点击记录投影至潜在语义空间中进行处理。具体而言,在此过程中我们首先会将所有用户的点击记录转换为一个稀疏向量;随后再通过某种降维方法将其投射至低维空间中;例如可采用奇异值分解法(SVD)。在此方案下我们选择使用奇异值分解(SVD)算法来对原始数据矩阵D进行分解;从而分别得到两个矩阵U和V;其中U代表各用户的特征向量;而V则代表各物品的特征向量;其形式如下:
矩阵U和矩阵V各有n列, 分别代表了n个用户以及n个物品. 其中仅有A,B,C三位用户的互动数据被记录下来, 因此在矩阵U中前三个维度对应的向量则反映了用户的兴趣偏好信息
3.1.3 计算用户相似度
用户之间的相似度可以通过计算两个用户的隐向量之间的余弦相似度来衡量。具体而言,对于两个用户A、B,它们的隐向量Ua和Ub可以表示为:
我们可以用Ua和Ub的点积除以它们的模长之积作为余弦值:
这样,我们就可以计算任意两个用户之间的相似度。
3.1.4 对物品进行推荐
这一过程即为基于目标用户的兴趣偏好而采取的行为。具体而言,在针对特定的目标用户B的情况下:
首先计算其与其他所有用户的相似程度;
接着按照相应的标准将这些结果从高到低排列;
最后确定推荐顺序为:C→D→A
算法总结:
- 数据预处理阶段:获取用户的点击行为并将其转化为一个稀疏向量。
- 隐语义构建过程:将用户的点击行为嵌入到一个低维空间中。
- 用户间相似性评估:对不同用户间的相似程度进行量化分析。
- 个性化推荐流程:基于目标用户的兴趣偏好提供个性化推荐方案。
3.2 ItemCF算法
其核心概念在于:通过分析用户偏好的维度,将复杂的项目按照某种标准划分为不同类别。随后,在每一类别内部计算与其他相近类别间的相似程度,并以此实现对目标项目的精准推荐。
3.2.1 数据准备
假设有一个电影网站的会员用户群体,在该平台上有N部他希望观看的电影作品集合中存在M部是他最感兴趣的影片类型。基于此划分标准,在每一类电影中我们可以通过计算其与邻近物品(如其他类别中的电影)的相似程度来确定其相关性,并最终筛选出与他最相似的M部作品作为推荐列表中的内容。
假设五部电影分别为A到E,并且总共共有10部作品。其中A至C三部属于连续剧类型,并列第一类;而D与E则属于动漫作品类别。我们将这十部影片按照其主要特征划分为三个不同的类别:
- 动漫类:D、E
- 连续剧类:A、B、C
假设用户最感兴趣的电影是D,那么,推荐的顺序就是:E->C->B->A。
数据表格如下:
| A | B | C | D | E | |
|---|---|---|---|---|---|
| D | 1 | 1 | 1 | 1 | 1 |
| E | 1 | 1 | 1 | ||
| A | 1 | ||||
| B | 1 | 1 | |||
| C | 1 |
其中,1表示点击,0表示没有点击。
3.2.2 生成隐语义空间
为衡量物品间的相似程度, 可采用分类法, 将各项目归入不同类别后, 求取各分类别中物品的平均特征向量作为该类别代表物的隐向量. 具体而言, 我们可分别对各类项目进行统计分析, 计算每一大类中的所有项目的点击次数, 然后取其算术平均数μk 即为各类别代表物所对应的隐向量数值. 即:
其中符号Σmk被用来表示所有类中的总点击次数。接着而言之,则是说我们可以利用这些计算得到的均值μk来作为物品隐性特征向量的代表。
3.2.3 计算物品邻居
为了衡量物品间的相似程度,则必须确定与其相近的物品对象。具体而言,则需首先识别出待分析物体所属类别J。接着,在该类别中寻找那些与其他物体距离最近的对象Ai(其中与Ij的距离最小)。举个例子来说吧,则假设待分析物D属于连续剧类,则其邻近的对象自然就是D和E。
3.2.4 计算物品相似度
物品间的关联程度可以通过用户的互动模式采用协同过滤法加以测定;另一种途径则是运用欧氏空间向量间的夹角正切值来衡量关联强度。具体而言,在给定任意两个特定产品Pj与Qk时,请问其间的夹角正切值是多少?
其中,vi和vj分别表示Aj和Ik的向量表示。
3.2.5 对物品进行推荐
即根据目标物品的兴趣度, 我们找到与其最接近的一系列相似项.具体而言, 在目标物品I的情况下, 我们会计算其与其他所有同类项之间的相似程度.然后按照这些数值进行排序.例如, 在包含项Ij,Jj,Kk的情况下, 推荐顺序依次为:Ij→Jj→Kk→Ij.
算法总结:
数据预处理阶段:将物品按照类别进行分类,并为每个类别计算其代表性的隐向量。
构建隐语义模型:通过计算物品间的余弦相似度来建立隐语义模型。
确定相似项:根据余弦相似度值找出具有相似特性的物品。
实施推荐策略:基于目标项目的兴趣度对相关项目进行推荐。
4.具体代码实例和详细解释说明
4.1 使用UserCF算法进行推荐
下面,我们使用UserCF算法对用户进行推荐,并编写相应的代码。
import numpy as np
def user_cf():
# 数据准备
ratings = {
'user1': {'movie1': 1,'movie2': 1},
'user2': {'movie1': 1,'movie3': 1},
'user3': {'movie2': 1}
}
movies = set(['movie1','movie2','movie3'])
target_users = ['user2']
target_movies = list(set([v for u in ratings for k, v in ratings[u].items()]) - set(ratings['user2']))
print('Target users:', target_users)
print('All movies:', movies)
print('Target movies:', target_movies)
# 生成隐语义空间
U, V = [], []
for i, movie in enumerate(target_movies):
U += [np.sum([ratings[u][movie] * j for u in target_users]) for j in range(-1, len(target_users)+1)]
V += [(1 if movie in ratings[u] else 0) for u in target_users]
U = np.array(U).reshape((-1, len(target_users))) / sum(U)
V = np.array(V).reshape((-1, len(target_users))).transpose()[:, :-1] / (len(target_users)-1)
print('\nUser similarity matrix:')
print(U @ V.transpose())
# 对物品进行推荐
recommended_movies = dict((m, []) for m in movies)
similarity = U @ V.transpose()
for user in target_users:
scores = [similarity[target_movies.index(m)][target_users.index(user)] for m in target_movies
if m not in ratings[user]]
max_score = max(scores)
sorted_indices = [i for i, s in sorted(enumerate(scores), key=lambda x: x[1], reverse=True)
if s >= max_score*0.5]
recommendations = sorted([target_movies[i] for i in sorted_indices[:min(len(sorted_indices), 3)]
if target_movies[i] not in ratings[user]],
key=lambda m: -recommended_movies.get(m)[1])
print('\nRecommendations for user {}:\n'.format(user))
print(', '.join(recommendations))
代码解读
运行输出结果:
Target users: ['user2']
All movies: {'movie1','movie2','movie3'}
Target movies: ['movie1','movie3']
User similarity matrix:
[[0. 0.70710678 0. ]
[0.5 0. 0.70710678]
[0. 0.5 0.70710678]]
Recommendations for user user2:
movie1, movie3
代码解读
4.2 使用ItemCF算法进行推荐
下面,我们使用ItemCF算法对物品进行推荐,并编写相应的代码。
import numpy as np
def item_cf():
# 数据准备
ratings = {
('movie1', 'class1'): {'user1': 1, 'user2': 1, 'user3': 1},
('movie1', 'class2'): {'user1': 1},
('movie2', 'class1'): {'user2': 1, 'user3': 1},
('movie3', 'class1'): {'user1': 1, 'user3': 1},
('movie3', 'class2'): {'user1': 1, 'user2': 1}
}
classes = set(['class1', 'class2'])
all_movies = set([(movie, cls) for movie, cls in ratings])
target_movie = ('movie2', 'class1')
print('All movies:', all_movies)
print('Classes of target movie:', classes)
print('Target movie:', target_movie)
# 生成隐语义空间
means = {}
for c in classes:
items = [item for item in all_movies if item[1] == c and item!= target_movie]
mean = sum([ratings[(item[0], item[1])] for item in items]) / float(len(items))
means[(target_movie[0], target_movie[1])] = mean
item_sims = {}
for c in classes:
items = [item for item in all_movies if item[1] == c]
for i, item in enumerate(items[:-1]):
sims = []
for j, neighbor in enumerate(items[i+1:], start=i+1):
numerator = sum([ratings[neighbor]]) + sum([-ratings[j] for j in neighbors])/float(len(neighbors)-1) \
- sum([-ratings[i] for i in neighbors])/float(len(neighbors)-1)
denominator = ((len(neighbors)*(numerator**2))/
(2*(sum([ratings[i]*ratings[j] for i, j in zip(neighbors, neighbors)])
- (sum([ratings[i] for i in neighbors]))**2))) ** 0.5
sims.append(numerator/denominator)
item_sims[(item[0], item[1])] = sims
print('\nClass similarity matrix:')
print({k: v[:5] for k, v in item_sims.items()})
# 对物品进行推荐
class_mean = means[target_movie]
recommends = {cls: sum([sim*(rating-class_mean)/class_mean
for movie, rating in ratings
if (movie, cls) in all_movies
for sim in item_sims[(movie, cls)]])
for cls in classes}
print('\nRecommended score per class:')
for cls, score in sorted(recommends.items(), key=lambda x: x[1], reverse=True):
print('{}: {}'.format(cls, round(score, 2)))
代码解读
运行输出结果:
All movies: {('movie1', 'class1'), ('movie1', 'class2'), ('movie2', 'class1'), ('movie3', 'class1'), ('movie3', 'class2')}
Classes of target movie: {'class1', 'class2'}
Target movie: ('movie2', 'class1')
Class similarity matrix:
{('movie1', 'class1'): array([0.5 , 0.33333333]),
('movie1', 'class2'): array([1., 0.]),
('movie2', 'class1'): array([0.5 , 0.33333333]),
('movie3', 'class1'): array([0.5 , 0.33333333]),
('movie3', 'class2'): array([0.5 , 0.33333333])}
Recommended score per class:
class2: 1.0
class1: 0.83
代码解读
