Python 人工智能实战:推荐算法
1.背景介绍
推荐算法(Recommender System),是一种基于用户过往行为数据、偏好信息等信息,借助数据分析技术推导出用户可能感兴趣的商品和服务的技术。简而言之,它就是通过数据分析帮助用户迅速识别可能感兴趣的内容或物品。推荐算法主要可分为基于用户和基于物品的两大类协同过滤算法。在本文中,我将从推荐算法的基本概念入手,深入解析推荐算法的本质和应用场景,并提供相应的代码实现和推荐系统架构设计。
2.核心概念与联系
用户-物品矩阵(User-Item Matrix)
推荐算法通常需要对用户的行为主及与其相关的物品进行建模。这种方法首先需要构建一个用户与物品之间的矩阵,其中矩阵中的元素代表了用户对各项物品的评分。例如,在电影推荐系统中,这样的矩阵可能如下所示:
| 电影1 | 电影2 | … | 电影N | |
|---|---|---|---|---|
| 用户A | 3.5 (7) | 2.9 (6) | … | 4.2 (5) |
| 用户B | 2.5 (8) | 3.8 (3) | … | 3.9 (4) |
| … | … | … | … | … |
| 用户M | 3.2 (9) | 3.5 (1) | … | 4.0 (6) |
在本表中,每一行代表一个用户,每一列代表一种物品。每个单元格中的第一个数字表示该用户对某部电影的评分,第二个数字表示该用户对该电影的观看次数,第三个数字表示该用户购买的该电影种类数量。这些具体含义各不相同,但通常情况下会包含:
具体含义各不相同,但通常情况下会包含:评分、观看频率和购买种类等信息。这些指标能够反映用户对电影的偏好和行为模式。具体说明可参考附录部分。
- 用户对物品的满意度程度
- 用户对物品的偏好程度
- 用户购买或不购买该物品的频率
- 用户在点击购买按钮时所支付的金额
基本假设
推荐系统的核心在于在建立用户-物品关系矩阵之后,对用户与物品之间的关系进行建模。
推荐系统的主要功能是向用户推荐那些能够满足其个人兴趣或需求的物品。因此,推荐系统的核心假设是:不同用户对同一物品的评价存在显著差异。具体而言,用户倾向于喜欢的物品往往不被其他用户所接受,而他们不喜欢的物品却可能得到他人的高度评价。
基于用户的协同过滤(User-based Collaborative Filtering)
以用户行为为基础的协同过滤算法主要关注用户之间的交互信息。其核心思想在于识别出与目标用户评分具有相似性的用户群体,并通过分析这些用户的评分信息,进一步推断出目标用户对其他物品的兴趣。具体而言,该算法首先会对用户的历史评分数据进行收集和整理,然后利用数学模型计算出用户间的相似度评分,最后根据这些计算结果筛选出与目标用户具有最高相似度的用户,并基于这些用户的评分信息,进一步推断出目标用户对其他物品的兴趣。
从用户-物品矩阵中随机选取一行,作为目标用户。
计算所有用户间的余弦相似度,以衡量用户间的相似程度。
基于相似度对训练集中的用户进行排序。
选取排序靠前的一定数量的用户,这些用户被称为邻居。
通过分析目标用户邻居的评分信息,推断其对其他物品的兴趣。
求余弦相似性
如果两个用户对同一物品有相同的评分,则认为它们的喜好相似。由于不同物品的相似性差异较大,因此需要对评分进行标准化处理,计算每个用户的总分,最后计算两个用户的余弦相似性。
假设两个用户 u 和 v 的评分向量分别为 r_u=(r_{u1}, r_{u2},..., r_{un}) 和 r_v=(r_{v1}, r_{v2},..., r_{vn}) ,则:
\text{similarity} = \frac{\sum_{i=1}^{n}{r_ur_v}}{\sqrt{\sum_{i=1}^{n}{(r_{ui})^2}\cdot(\sum_{j=1}^{n}{(r_{vj})^2}}}
其中,公式1和公式2分别表示用户u对物品i的评分平方和与用户v对物品j的评分平方和。具体来说,公式1即\sum_{i=1}^{n}{(r_{ui})^2},用于衡量用户u的评分行为;公式2即\sum_{j=1}^{n}{(r_{vj})^2},用于衡量用户v的评分行为。这两个公式共同构成了衡量用户u和v之间相似程度的计算方法。
推荐算法
在推荐过程中,为了帮助目标用户发现可能感兴趣的物品,系统会基于相似度对其他用户的评分进行综合考量,并通过计算用户的平均评分来预测目标用户的兴趣。例如,系统会根据用户的历史评分和行为模式,推荐相似的音乐或视频内容。
\hat{r}_{uj}=\frac{\sum_{k\in N_u}{\text{sim}(u, k)\cdot r_{uk}}}{|\mathcal{K}|+\alpha}
其中,\text{sim}(u, k) 表示用户u与用户k之间的相似度,r_{uk} 表示用户k对物品j的评分。N_u 表示用户u的邻居集合,\mathcal{K} 是所有用户的集合。\alpha 是超参数,用于调节新用户的加入对计算结果的影响程度。
当用户 A 寻求展示用户 B 不感兴趣的商品 C 时,系统会通过相似性识别出 B 在某些领域与 A 有“关联”的商品——C 的邻居。然后,系统会综合 B 的其他商品评分信息,来估算商品 C 对用户 A 的兴趣程度。
基于物品的协同过滤(Item-based Collaborative Filtering)
该算法主要利用物品间的交互信息进行处理。该算法的核心目标是识别出与目标物品高度相关的物品,并为该目标用户进行个性化推荐。
求皮尔逊相关系数
如果两个物品的人气水平相当,且均在人气排行榜中获得过席位,那么它们很可能具有较高的相似性。具体而言,计算两个物品之间皮尔逊相关系数的步骤如下:
该相关系数\rho_{ij}等于两个变量间协方差的平方根与各自标准差乘积的比值,其中协方差的计算范围限定于较小的样本数量。具体而言,分子部分为\sum_{l=1}^{\min\{n_i, n_j\}}\left((r_{il}-\bar{r}_i)(r_{jl}-\bar{r}_j)\right),而分母部分则为\sqrt{\sum_{l=1}^{n_i}(r_{il}-\bar{r}_i)^2\cdot\sum_{l=1}^{n_j}(r_{jl}-\bar{r}_j)^2}。
其中,n_i 为用户 i 对物品 i 的评分次数,\bar{r}_i 为用户 i 对物品 i 的平均评分值,r_{il} 则表示用户 i 对物品 l 的评分次数。
推荐算法
推荐算法类似于基于用户的协同过滤方法,具体流程如下:该算法通过计算物品之间的相似性来衡量两个物品之间的相似性。
从用户-物品矩阵中随机选择一列,将其定义为目标物品,并将其作为测试集。接下来,计算每对物品间的皮尔逊相关系数,以评估它们的相似程度。基于相似度对训练集中的所有物品进行排序,选取相似度排序中位于前K位的物品。最后,将这些选定的物品推荐给目标用户。
改进型算法
现有的主流推荐算法主要基于用户的协同过滤以及基于物品的协同过滤方法。然而,这两种算法存在一些局限性,例如:计算复杂度过高,难以满足大规模数据处理的需求。
- 冷启动问题:新的用户或物品无法获得完整的相似度数据,可能导致新的推荐问题出现。
- 负反馈问题:用户的喜好往往不稳定,会随着时间推移而变化。因此,系统需要具备一定的容忍度,以应对部分用户的失望情绪。
除了提到的一些问题之外,还有改进型算法显著提升了推荐系统的精度和实时性。
- ItemCF与UserCF结合:通过融合用户相似度与物品相似度特征,构建协同过滤模型。
- 基于社交网络的SocialCF:通过分析社交网络的拓扑结构,构建多维用户关系图,同时融合物品间的上下文信息。
- 基于内容的协同过滤(Content-Based CF):通过分析物品的文本特征进行个性化推荐,而非仅依赖用户-物品矩阵的交互数据。
- FunkSVD算法:通过奇异值分解技术对用户-物品矩阵进行降维处理,有效降低协同过滤的计算复杂度。
3.核心算法原理和具体操作步骤以及数学模型公式详细讲解
数据准备阶段
- 将原始数据按照用户-物品关系进行矩阵形式的转换,具体包括用户、物品及其对应的评分。
- 对原始数据进行划分,按照一定比例将其分为训练集、验证集和测试集。
基于用户的协同过滤算法
求余弦相似性
数学模型公式
余弦相似性算法的数学模型描述如下:
\text{similarity} = \frac{\sum_{i=1}^{n}{r_ur_v}}{\sqrt{\sum_{i=1}^{n}{(r_{ui})^2}\cdot(\sum_{j=1}^{n}{(r_{vj})^2}}}
其中,用户 u 的评分向量 r_u 包括其对所有物品的评分,用户 v 的评分向量 r_v 包括其对所有物品的评分,矩阵的大小为 n。
操作步骤
遍历测试集中的每个用户,计算其与其他所有用户的相似性,并将计算出的相似性结果存储在一个字典中。
当用户发起物品推荐请求时,在预处理阶段,生成了用户相似性字典,并在此基础上获取与目标用户评分最为接近的 K 个邻居。
通过邻居的评分,计算出目标用户对每个物品的评分,并进行平均取整。
\hat{r}_{uj}=\frac{\sum_{k\in N_u}{\text{sim}(u, k)\cdot r_{uk}}}{|\mathcal{K}|+\alpha}
其中,\text{sim}(u, k) 表示用户u与用户k之间的相似度,r_{uk} 表示用户k对物品j的评分。N_u 表示用户u的邻居集合,\mathcal{K} 是所有用户。\alpha 是超参数,用于调节新用户的加入对结果的影响程度。
这样,基于用户的协同过滤算法就可以完成对用户的推荐。
基于物品的协同过滤算法
求皮尔逊相关系数
数学模型公式
皮尔逊相关系数算法的数学模型描述如下:
该公式用于评估变量间的关系,其中分子部分为\sum_{l=1}^{\min\{n_i, n_j\}}\left((r_{il}-\bar{r}_i)(r_{jl}-\bar{r}_j)\right),分母部分为\sqrt{\sum_{l=1}^{n_i}(r_{il}-\bar{r}_i)^2\cdot\sum_{m=1}^{n_j}(r_{jm}-\bar{r}_j)^2},整体等于\rho_{ij}。
其中,n_i 表示用户 i 对物品 i 的评分次数,\bar{r}_i 表示用户 i 对物品 i 的平均评分,r_{il} 表示用户 i 对物品 l 的评分。
操作步骤
确定测试集中的每个物品与其所有物品的相关性,并将计算结果存储在一个字典中。
当用户发起物品推荐请求时,系统基于预处理得到的相关性字典,获取与目标物品最相关的 K 个相关物品。
返回这些相关物品。
这样,基于物品的协同过滤算法就可以完成对物品的推荐。
模型评估阶段
模型的准确性和效率可以通过以下三种方式衡量:
Root Mean Square Error (RMSE: 均方根误差)是一种用于评估推荐系统输出与真实用户反馈之间差异程度的指标。较小的RMSE值意味着推荐系统具有更高的准确性。
Precision@K被用作评估推荐系统准确性的重要指标,其中K值具体表示系统在推荐列表中输出的条目数量。
Recall@K 用于评估推荐系统中推荐结果的质量,其中 K 表示系统返回的前 K 项建议。
可以通过对模型效果的评估,确定推荐算法是否达到了预期的效果。
4.具体代码实例和详细解释说明
我们采用一个简单的电影推荐系统案例来阐述基于协同过滤的推荐算法。基于一个电影评分数据表,该表记录了每个用户对每部电影的评分,共有 M 部电影和 N 个用户。
import pandas as pd
from collections import defaultdict
ratings = pd.read_csv('movie_ratings.csv') # Load movie ratings data from csv file.
# Convert the dataframe to user-item matrix format
user_item_matrix = ratings.pivot(index='userId', columns='movieId', values='rating').fillna(0)
train_set = {} # train set containing user-items pairs with rating >= 4.0
for row in range(len(user_item_matrix)):
for col in range(len(user_item_matrix[row])):
if user_item_matrix.values[row][col] >= 4.0:
train_set[(row + 1, col + 1)] = user_item_matrix.values[row][col]
test_set = {(row + 1, col + 1): user_item_matrix.values[row][col] for row in [0] for col in range(len(user_item_matrix))} # test set containing only one user's items
class UserCF():
def __init__(self, K=50, alpha=0.1):
self.K = K
self.alpha = alpha
def fit(self, train_set):
# create similarity dictionary
self.sim_dict = self._create_sim_dict(train_set)
# calculate all items' average ratings and users' bias terms
self.all_item_avg, self.users_bias = self._calculate_bias(train_set)
def predict(self, target_user, target_item):
# find similar users to the target user
neighors = sorted([user for user, sim in self.sim_dict[target_user].items() if sim > 0][:self.K], key=lambda x: -self.sim_dict[x][target_user])
if len(neighors) == 0: return None
# calculate weighted sum of ratings by similar users
prediction = sum([(self.sim_dict[neighbor][target_user] / max(list(self.sim_dict[neighbor].values()))) * self.all_item_avg[target_item]
+ self.users_bias[neighbor] for neighbor in neighors]) / (self.K + self.alpha)
return round(prediction, 2)
def _create_sim_dict(self, train_set):
# initialize similarity dictionary
sim_dict = defaultdict(dict)
for item in train_set:
sims = {}
for other_item in train_set:
if item!= other_item:
cosine_sim = self._cosine_similarity(train_set[item], train_set[other_item])
if cosine_sim > 0:
sims[other_item] = cosine_sim
sim_dict[item[0]][item[1]] = sims
return sim_dict
def _cosine_similarity(self, vec1, vec2):
dot_product = sum(p * q for p, q in zip(vec1, vec2))
magnitude1 = sum(abs(p) ** 2 for p in vec1)
magnitude2 = sum(abs(q) ** 2 for q in vec2)
try:
return dot_product / ((magnitude1 * magnitude2) ** 0.5)
except ZeroDivisionError:
return 0
def _calculate_bias(self, train_set):
# calculate each item's average rating
all_item_avg = {key: sum(value)/float(len(value)) for key, value in dict(train_set).items()}
# calculate each user's bias term
users_bias = {user: self._calculate_single_bias(user, train_set) for user in list({item[0] for item in train_set})}
return all_item_avg, users_bias
def _calculate_single_bias(self, user, train_set):
items_rated_by_user = [(item[1], value) for item, value in train_set.items() if item[0] == user]
numerator = sum(map(lambda x: abs(x[0]-x[1]), items_rated_by_user))
denominator = float(max([x[1] for x in items_rated_by_user]))
if denominator == 0 or numerator/denominator < 0.2:
return 0
else:
return numerator/denominator
model = UserCF(K=10, alpha=0.1)
model.fit(train_set)
pred_ratings = []
for item in test_set:
pred_rating = model.predict(item[0], item[1])
if pred_rating is not None:
pred_ratings.append((item[0], item[1], pred_rating))
recommendations = pd.DataFrame(pred_ratings, columns=['userId','movieId', 'predictedRating'])
print(recommendations)
代码解读
5.未来发展趋势与挑战
就目前而言,基于协同过滤的推荐算法仍处于理论研发阶段,尚未在实际应用中进行测试。然而,其显著优势在于能够在短时间内提供精确的推荐结果。此外,由于推荐算法并非旨在替代专业判断,因此它能够帮助用户迅速定位自己的兴趣领域。因此,基于协同过滤的推荐算法在互联网产品设计、电子商务网站设计以及视频网站的推荐系统等领域具有广泛的应用潜力。
6.附录常见问题与解答
什么是推荐系统?
推荐系统是以用户偏好为基础的信息技术系统,该系统通过数据分析技术为用户推荐可能感兴趣的商品或服务。其主要功能体现在两个方面:首先,它在提升在线零售业个性化体验方面发挥了重要作用;其次,它在优化网络搜索引擎的推荐效果方面也表现出显著优势。推荐系统主要由信息收集模块和推荐引擎两部分构成。其中,信息收集模块负责收集用户数据并分析其购买习惯,进而构建用户与商品之间的关系矩阵。而推荐引擎则利用该矩阵的统计分析功能,为用户提供精准的推荐服务。
为何要推荐系统?
推荐系统的核心目标是为个人用户迅速获取大量相关资讯。在当今社会,所需信息呈现出海量增长的趋势,而传统的信息检索手段由于低效难以满足需求。通过推荐系统,用户可以精准推送感兴趣的内容,轻松获取所需信息。在网页浏览、在线购物和游戏中,推荐系统能够有效缓解信息过载,不仅能够帮助用户快速找到所需内容,还能为企业带来显著的经济效益。推荐系统不仅能够帮助用户快速找到所需内容,还能为企业带来显著的经济效益。
推荐系统的类型有哪几种?
推荐系统大致可以分为以下几种类型:
1.
基于内容的推荐:过去已有不少推荐系统技术都是以内容为基础的。该推荐系统通过分析用户的阅读历史、收藏偏好等数据来,从而实现具有用户兴趣特征的物品推荐。
2.
基于用户行为的协同过滤推荐系统是一种推荐算法,它通过分析用户之间的交互记录,为用户推荐与目标用户兴趣高度相似的物品。
3.
基于知识的推荐:基于知识的推荐系统利用机器学习算法对用户行为进行建模,系统能够识别用户的兴趣偏好,为用户提供更精准的推荐服务。
4.
分类推荐是一种基于直觉的推荐机制。该系统通过将用户搜索的内容按照特定的分类规则进行整理,并向用户推荐相关类别中的内容。
什么是协同过滤推荐算法?
协同过滤推荐算法属于推荐算法的一种,其通过分析用户的历史行为、偏好等数据,为用户推荐与其兴趣高度相似的物品。协同过滤推荐算法主要分为基于用户和基于物品的两种类型。基于用户的协同过滤算法通过将用户划分为若干群体,为每个群体推荐与其兴趣相似的物品。基于物品的协同过滤算法首先按照物品间的相似度进行排序,随后为特定目标物品推荐相关产品。
基于用户的协同过滤算法为什么工作?
基于用户的协同过滤算法的工作原理是首先通过计算用户间的相似性,构建用户-物品矩阵,然后确定每个用户的兴趣偏好,最终将推荐结果精准地分配给用户具有相似兴趣的用户。该算法的主要步骤包括:首先计算用户间的相似性,然后构建用户-物品的评分矩阵,接着确定每个用户的兴趣偏好,最后基于相似性推荐相关物品。
- 计算用户间的相似程度:在计算两个用户之间的相似程度时,若两个用户对同一物品的评分越接近,则可认为这两个用户具有相似性。
- 构建用户与物品之间的关系矩阵:在构建用户与物品之间的关系矩阵时,矩阵中的每个元素代表用户对相应物品的评分。
- 基于用户的评分信息,为用户推荐其感兴趣的物品:通过分析用户的评分信息,可以为用户推荐其感兴趣的物品。
该协同过滤算法基于用户的特性,能够构建出用户之间的相似关系网络,从而为用户提供具有独特性的推荐结果。然而,该算法可能无法完全满足用户的真实需求,从而引发焦虑情绪。
基于物品的协同过滤算法为什么工作?
基于物品的协同过滤算法的工作原理是首先构建物品-用户矩阵,通过计算得出各物品间的相似度,接着筛选出与目标物品高度相关的物品,最后向用户推荐。基于物品的协同过滤算法包括构建相似度矩阵、计算相关性排序和生成推荐列表等主要步骤。
计算物品间的相似性:评估两个物品之间的相似性,当两个物品的人气越接近,就认为这两件物品具有相似性。构建物品-用户矩阵:构建一个物品与用户之间的关系矩阵,矩阵中的元素代表用户对相应物品的评分。推荐与目标物品最相关的物品:通过计算物品间的相似性进行排序,推荐与目标物品最相关的物品。
主要基于物品的协同过滤算法的主要优点是可以较为准确地为用户提供相似的物品。然而,该算法的缺点是无法捕捉到用户的行为习惯,这导致算法无法反映用户对物品的真正喜好。
基于用户的协同过滤算法与基于物品的协同过滤算法的区别是什么?
基于用户的协同过滤算法与基于物品的协同过滤算法的主要区别在于如何计算用户间的相似度和物品间的相似程度。基于用户的协同过滤算法通过计算用户间的相似度来评估用户间的相似程度,这种方法要求明确的物品标签,无法反映用户的使用历史。基于物品的协同过滤算法通过计算物品间的相似程度来评估物品间的相似程度,这种方法能够反映用户的使用历史。由此可见,基于用户的协同过滤算法更适合具有广泛用户基础的大众化内容,如电影和音乐,而基于物品的协同过滤算法则更适合具有特定用户群体的个性化内容,如新闻和科技类信息。
