协同过滤在推荐系统中的应用详解大数据
前面的博客介绍过如何构建一个推荐系统,以及简要的介绍了协同过滤的实现。本篇博客,笔者将介绍协同过滤在推荐系统的应用。推荐系统是大数据和机器学习中最常见、最容易理解的应用之一。其实,在日常的生活当中,我们会频繁的遇到推荐的场景 ,比如你在电商网站购买商品、使用视频App观看视频、在手机上下载各种游戏等,这些都是使用了推荐技术来个性化你想要的内容和物品。
本篇博客将通过以下方式来介绍,通过建立协同过滤模型,利用订单数据来想用户推荐预期的物品。步骤如下:
转换和规范化数据 评估模型性能 选择最佳模型 2.1 技术选型完成本篇博客所需要的技术使用Python和机器学习Turicreate来实现。Python所需要的依赖库如下:
pandas和numpy:用于操作数据 turicreate:用于进行模型选择与评估 sklearn:用于对数据进行封装,包括回归、降维、分类、聚类等。 2.2 加载数据本次演示的数据源,包含如下:
customer_id.csv:列出1000个客户ID作为输出推荐; customer_data.csv:物品数据源集。加载Python依赖库,实现代码如下:
import pandas as pd import numpy as np import time import turicreate as tc from sklearn.model_selection import train_test_split
查看数据集,实现代码如下:
customers = pd.read_csv(customer_id.csv) transactions = pd.read_csv(customer_data.csv) print(customers.head()) print(transactions.head())
预览结果如下:
将上述csv中的数据集中,将products列中的每个物品列表分解成行,并计算用户购买的产品数量。
2.3.1 使用用户、物品和目标字段创建数据 此表将作为稍后建模的输入 在本次案例中,使用customerId、productId和purchase_count字段实现代码如下:
transactions[products] = transactions[products].apply(lambda x: [int(i) for i in x.split(|)]) data = pd.melt(transactions.set_index(customerId)[products].apply(pd.Series).reset_index(), id_vars=[customerId], value_name=products) / .dropna().drop([variable], axis=1) / .groupby([customerId, products]) / .agg({products: count}) / .rename(columns={products: purchase_count}) / .reset_index() / .rename(columns={products: productId}) data[productId] = data[productId].astype(np.int64) print(data.shape) print(data.head())
预览截图如下:
实现代码如下:
def create_data_dummy(data): data_dummy = data.copy() data_dummy[purchase_dummy] = 1 return data_dummy data_dummy = create_data_dummy(data) print(data_dummy.head())
预览结果如下:
实现代码如下:
df_matrix = pd.pivot_table(data, values=purchase_count, index=customerId, columns=productId) print(df_matrix.head())
预览结果如下:
矩阵规范化实现代码如下:
df_matrix_norm = (df_matrix-df_matrix.min())/(df_matrix.max()-df_matrix.min()) print(df_matrix_norm.head())
预览结果如下:
创建一个表作为模型的输入,实现代码如下:
d = df_matrix_norm.reset_index() d.index.names = [scaled_purchase_freq] data_norm = pd.melt(d, id_vars=[customerId], value_name=scaled_purchase_freq).dropna() print(data_norm.shape) print(data_norm.head())
预览结果如下:
上述步骤可以组合成下面定义的函数,实现代码如下 :
def normalize_data(data): df_matrix = pd.pivot_table(data, values=purchase_count, index=customerId, columns=productId) df_matrix_norm = (df_matrix-df_matrix.min())/(df_matrix.max()-df_matrix.min()) d = df_matrix_norm.reset_index() d.index.names = [scaled_purchase_freq] return pd.melt(d, id_vars=[customerId], value_name=scaled_purchase_freq).dropna()
上面,我们规范化了用户的购买历史记录,从0到1(1是一个物品的最多购买次数,0是该物品的0个购买计数)。
2.4 拆分用于训练用的数据集 将数据分割成训练集和测试集是评估预测建模的一个重要部分,在这种情况下使一个协作过滤模型。通过,我们使用较大部分的数据用于训练,而较小的部分用于测试; 我们将训练集和测试集占比拆分为80% : 20%; 训练部分将用于开发预测模型,而另外一部分用于评估模型的性能。拆分函数实现如下:
def split_data(data): Splits dataset into training and test set. Args: data (pandas.DataFrame) Returns train_data (tc.SFrame) test_data (tc.SFrame) train, test = train_test_split(data, test_size = .2) train_data = tc.SFrame(train) test_data = tc.SFrame(test) return train_data, test_data
现在我们有了是三个数据集,分别是购买计数、购买虚拟数据和按比例的购买计数,这里我们将每个数据集分开进行建模,实现代码如下:
train_data, test_data = split_data(data) train_data_dummy, test_data_dummy = split_data(data_dummy) train_data_norm, test_data_norm = split_data(data_norm)
print(train_data)
这里打印训练结果数据,预览结果如下:
在运行更加复杂的方法(比如协同过滤)之前,我们应该运行一个基线模型来比较和评估模型。由于基线通常使用一种非常简单的方法,因此如果在这种方法之外使用的技术显示出相对较好的准确性和复杂性,则应该选择这些技术。
Baseline Model是机器学习领域的一个术语,简而言之,就是使用最普遍的情况来做结果预测。比如,猜硬币游戏,最简单的策略就是一直选择正面或者反面,这样从预测的模型结果来看,你是有50%的准确率的。
一种更复杂但是更常见的预测购买商品的方法就是协同过滤。下面,我们首先定义要在模型中使用的变量,代码如下:
# constant variables to define field names include: user_id = customerId item_id = productId users_to_recommend = list(customers[user_id]) n_rec = 10 # number of items to recommend n_display = 30 # to display the first few rows in an output dataset
Turicreate使我们非常容易去调用建模技术,因此,定义所有模型的函数如下:
def model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display): if name == popularity: model = tc.popularity_recommender.create(train_data, user_id=user_id, item_id=item_id, target=target) elif name == cosine: model = tc.item_similarity_recommender.create(train_data, user_id=user_id, item_id=item_id, target=target, similarity_type=cosine) elif name == pearson: model = tc.item_similarity_recommender.create(train_data, user_id=user_id, item_id=item_id, target=target, similarity_type=pearson) recom = model.recommend(users=users_to_recommend, k=n_rec) recom.print_rows(n_display) return model2.5.1 使用Popularity Model作为Baseline Popularity Model采用最受欢迎的物品进行推荐,这些物品在用户中销量是最高的; 训练数据用于模型选择。
购买计数实现代码如下:
name = popularity target = purchase_count popularity = model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(popularity)
截图如下:
购买虚拟人代码如下:
name = popularity target = purchase_dummy pop_dummy = model(train_data_dummy, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(pop_dummy)
截图如下:
按比例购买计数实现代码如下:
name = popularity target = scaled_purchase_freq pop_norm = model(train_data_norm, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(pop_norm)
截图如下:
根据用户如何在协作购买物品的基础上推荐相似的物品。例如,如果用户1和用户2购买了类似的物品,比如用户1购买的X、Y、Z,用户2购买了X、Y、Y,那么我们可以向用户2推荐物品Z。
2.6.1 原理 创建一个用户-物品矩阵,其中索引值表示唯一的用户ID,列值表示唯一的物品ID; 创建相似矩阵,这个作用是用于计算一个物品和另外一个物品的相似度,这里我们使用余弦相似度或者皮尔森相似度。要计算物品X和物品Y之间的相似性,需要查看对这两个物品进行评级的所有用户,例如,用户1和用户2都对物品X和Y进行了评级 然后,我们在(用户1,用户2)的用户空间中创建两个物品向量,V1表示物品X,V2表示物品Y,然后找出这些向量之间的余弦值。余弦值为1的零角度或者重叠向量表示完全相似(或者每个用户,所有物品都有相同的评级),90度的角度意味着余弦为0或者没有相似性。 2.6.2 余弦相似度
公式如下:
购买计数代码如下:
name = cosine target = purchase_count cos = model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(cos)
截图如下:
购买虚拟人代码如下:
name = cosine target = purchase_dummy cos_dummy = model(train_data_dummy, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(cos_dummy)
截图如下:
按比例购买计数,实现代码如下:
name = cosine target = scaled_purchase_freq cos_norm = model(train_data_norm, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(cos_norm)
截图如下:
购买计数实现代码:
name = pearson target = purchase_count pear = model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(pear)
截图如下:
购买虚拟人实现代码:
name = pearson target = purchase_dummy pear_dummy = model(train_data_dummy, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(pear_dummy)
截图如下:
按比例购买计数:
name = pearson target = scaled_purchase_freq pear_norm = model(train_data_norm, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) print(pear_norm)
截图如下:
在评价推荐引擎时,我们可以使用RMSE和精准召回的概念。
RMSE(Root Mean Squared Errors)用户购买的物品中实际推荐的比例是多少; 如果一个用户购买了5种物品,而推荐列表决定展示其中的3种,那么召回率为60%。
在所有推荐的物品中,有多少用户真正喜欢; 如果向用户推荐了5种物品,而用户购买了其中的4种,那么准确率为80%。
为何召回和准确度如此重要呢?
考虑一个案例,我们推荐所有的物品。这样我们的用户一定会涵盖他们喜欢和购买的物品。这种情况下,我们的召回率为100%,这样是否意味着我们的模型是最好的呢? 我们必须考虑准确率,如果我们推荐300件物品,但用户喜欢,而且购买了3件,那么准确率是1%,这个非常低的准确率表明,尽管他们的召回率很高,但是这个模型并不是很好。 因此,我们最终的目标是优化召回率和准确率,让他们尽可能的接近1。下面,我们为模型求值创建初识可调用变量,实现代码如下:
models_w_counts = [popularity, cos, pear] models_w_dummy = [pop_dummy, cos_dummy, pear_dummy] models_w_norm = [pop_norm, cos_norm, pear_norm] names_w_counts = [Popularity Model on Purchase Counts, Cosine Similarity on Purchase Counts, Pearson Similarity on Purchase Counts] names_w_dummy = [Popularity Model on Purchase Dummy, Cosine Similarity on Purchase Dummy, Pearson Similarity on Purchase Dummy] names_w_norm = [Popularity Model on Scaled Purchase Counts, Cosine Similarity on Scaled Purchase Counts, Pearson Similarity on Scaled Purchase Counts]
然后,让我们比较一下我们基于RMSE和精准召回特性构建的所有模型,代码如下:
eval_counts = tc.recommender.util.compare_models(test_data, models_w_counts, model_names=names_w_counts) eval_dummy = tc.recommender.util.compare_models(test_data_dummy, models_w_dummy, model_names=names_w_dummy) eval_norm = tc.recommender.util.compare_models(test_data_norm, models_w_norm, model_names=names_w_norm)
评估结果输出如下:
完成实例代码如下:
customers = pd.read_csv(customer_id.csv) transactions = pd.read_csv(customer_data.csv) # print(customers.head()) # print(transactions.head()) transactions[products] = transactions[products].apply(lambda x: [int(i) for i in x.split(|)]) data = pd.melt(transactions.set_index(customerId)[products].apply(pd.Series).reset_index(), id_vars=[customerId], value_name=products) / .dropna().drop([variable], axis=1) / .groupby([customerId, products]) / .agg({products: count}) / .rename(columns={products: purchase_count}) / .reset_index() / .rename(columns={products: productId}) data[productId] = data[productId].astype(np.int64) # print(data.shape) # print(data.head()) def create_data_dummy(data): data_dummy = data.copy() data_dummy[purchase_dummy] = 1 return data_dummy data_dummy = create_data_dummy(data) # print(data_dummy.head()) df_matrix = pd.pivot_table(data, values=purchase_count, index=customerId, columns=productId) # print(df_matrix.head()) df_matrix_norm = (df_matrix-df_matrix.min())/(df_matrix.max()-df_matrix.min()) # print(df_matrix_norm.head()) # create a table for input to the modeling d = df_matrix_norm.reset_index() d.index.names = [scaled_purchase_freq] data_norm = pd.melt(d, id_vars=[customerId], value_name=scaled_purchase_freq).dropna() # print(data_norm.shape) # print(data_norm.head()) def normalize_data(data): df_matrix = pd.pivot_table(data, values=purchase_count, index=customerId, columns=productId) df_matrix_norm = (df_matrix-df_matrix.min())/(df_matrix.max()-df_matrix.min()) d = df_matrix_norm.reset_index() d.index.names = [scaled_purchase_freq] return pd.melt(d, id_vars=[customerId], value_name=scaled_purchase_freq).dropna() def split_data(data): Splits dataset into training and test set. Args: data (pandas.DataFrame) Returns train_data (tc.SFrame) test_data (tc.SFrame) train, test = train_test_split(data, test_size = .2) train_data = tc.SFrame(train) test_data = tc.SFrame(test) return train_data, test_data train_data, test_data = split_data(data) train_data_dummy, test_data_dummy = split_data(data_dummy) train_data_norm, test_data_norm = split_data(data_norm) # print(train_data) # constant variables to define field names include: user_id = customerId item_id = productId users_to_recommend = list(customers[user_id]) n_rec = 10 # number of items to recommend n_display = 30 # to display the first few rows in an output dataset def model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display): if name == popularity: model = tc.popularity_recommender.create(train_data, user_id=user_id, item_id=item_id, target=target) elif name == cosine: model = tc.item_similarity_recommender.create(train_data, user_id=user_id, item_id=item_id, target=target, similarity_type=cosine) elif name == pearson: model = tc.item_similarity_recommender.create(train_data, user_id=user_id, item_id=item_id, target=target, similarity_type=pearson) recom = model.recommend(users=users_to_recommend, k=n_rec) recom.print_rows(n_display) return model name = popularity target = purchase_count popularity = model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(popularity) name = popularity target = purchase_dummy pop_dummy = model(train_data_dummy, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(pop_dummy) name = popularity target = scaled_purchase_freq pop_norm = model(train_data_norm, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(pop_norm) name = cosine target = purchase_count cos = model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(cos) name = cosine target = purchase_dummy cos_dummy = model(train_data_dummy, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(cos_dummy) name = cosine target = scaled_purchase_freq cos_norm = model(train_data_norm, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(cos_norm) name = pearson target = purchase_count pear = model(train_data, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(pear) name = pearson target = purchase_dummy pear_dummy = model(train_data_dummy, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(pear_dummy) name = pearson target = scaled_purchase_freq pear_norm = model(train_data_norm, name, user_id, item_id, target, users_to_recommend, n_rec, n_display) # print(pear_norm) models_w_counts = [popularity, cos, pear] models_w_dummy = [pop_dummy, cos_dummy, pear_dummy] models_w_norm = [pop_norm, cos_norm, pear_norm] names_w_counts = [Popularity Model on Purchase Counts, Cosine Similarity on Purchase Counts, Pearson Similarity on Purchase Counts] names_w_dummy = [Popularity Model on Purchase Dummy, Cosine Similarity on Purchase Dummy, Pearson Similarity on Purchase Dummy] names_w_norm = [Popularity Model on Scaled Purchase Counts, Cosine Similarity on Scaled Purchase Counts, Pearson Similarity on Scaled Purchase Counts] eval_counts = tc.recommender.util.compare_models(test_data, models_w_counts, model_names=names_w_counts) eval_dummy = tc.recommender.util.compare_models(test_data_dummy, models_w_dummy, model_names=names_w_dummy) eval_norm = tc.recommender.util.compare_models(test_data_norm, models_w_norm, model_names=names_w_norm) # Final Output Result # final_model = tc.item_similarity_recommender.create(tc.SFrame(data_dummy), user_id=user_id, item_id=item_id, target=purchase_dummy, similarity_type=cosine) # recom = final_model.recommend(users=users_to_recommend, k=n_rec) # recom.print_rows(n_display) # df_rec = recom.to_dataframe() # print(df_rec.shape) # print(df_rec.head())
View Code4.结束语
这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!
另外,博主出书了《Kafka并不难学》和《Hadoop大数据挖掘从入门到进阶实战》,喜欢的朋友或同学, 可以在公告栏那里点击购买链接购买博主的书进行学习,在此感谢大家的支持。关注下面公众号,根据提示,可免费获取书籍的教学视频。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/9852.html
分布式文件系统,分布式数据库区块链并行处理(MPP)数据库,数据挖掘开源大数据平台数据中台数据分析数据开发数据治理数据湖数据采集相关文章
- 脑机接口(BCI)系统概述及应用
- 使用ADB卸载MIUI系统应用
- springcloud实战:详解应用系统发布上线
- web3.0区块链技术与系统开发应用方案
- 【函数指针的高级应用】嵌入式系统如何从boot程序运行kernel程序?
- 【解决方案】智慧工地中安全帽识别原理和系统应用
- SAP UI5 Fiori 应用在启动时向 ABAP 后台发起的 OData 请求序列的顺序和作用分析
- 谈谈域渗透中常见的可滥用权限及其应用场景(二)
- 下(应用篇)| 量子计算与开源软件
- Elastic Stack 实战教程 4:使用 Fleet 管理 Elastic Agent 监控应用
- Linux系统中C语言函数的应用(linux的c函数)
- 系统i2c驱动在Linux系统上的应用(i2c驱动linux)
- 运用Linux桌面应用让工作更高效(linux桌面应用)
- Oracle ODAC:提升应用性能的有效解决方案(oracleodac)
- 快速安装Linux:体验无缝应用体验(linux系统安装软件)
- ISO软件在Linux上的应用(iso软件linux)
- 在Linux系统上开发安卓应用(开发安卓用linux系统)
- Linux应用开发利器:Qt XCB的使用(linuxqtxcb)
- 思源黑体在Linux系统下的应用(思源黑体linux)
- Linux系统下挖矿程序的应用与原理简述(linux挖矿程序)
- 探讨Oracle高并发处理技术与应用(oracle高并发)
- Linux软件排行榜:最佳应用抢先看!(linux排行榜)
- LCD命令在Linux系统下的应用(lcdlinux命令)
- 阿里云平台上Linux系统的应用(aliyun linux)
- Linux系统中ICMP协议的应用(linux icmp)
- 跨平台开发工具Ionic在Linux系统中的应用(ioniclinux)
- Oracle中日期类型的应用与使用(date在oracle中)
- 用户灵活管理应用将数据存放Redis中(用户对应应用放redis)
- Oracle应用多元化的主要用途(oracle主要用途)
- 首个应用微软AI的自主系统,能让机器蛇自主爬楼、避障