12.5 推荐系统
经过前面对数据集的预处理和数据分析,已经为推荐系统的开发工作打下基础。在本届 的内容中,将详细讲解分别实现协同过滤推荐系统和基于内容过滤系统的过程。
12.5.1 协同过滤推荐系统
协同过滤是一种可以根据类似用户的反馈来过滤用户可能喜欢的项目的技术,它通过搜索一个庞大的用户群体,找到与特定用户口味相似的较小用户集合来实现。我们将使用余弦相似度,这是一种用于衡量文档相似性的度量标准,不考虑它们的大小。在数学上,它测量了在多维空间中投影的两个向量之间的角度的余弦。余弦相似度的优势在于,即使两个相似的文档在欧氏距离上相距很远(由于文档的大小),它们仍然有可能朝向更接近。角度越小,余弦相似度越高。
下面这段代码实现了基于协同过滤的推荐系统的关键步骤,具体实现代码如下所示。
from scipy.sparse import csr_matrix
from sklearn.neighbors import NearestNeighbors
data_matrix = csr_matrix(data_pivot.values)
model_knn = NearestNeighbors(metric="cosine", algorithm="brute")
model_knn.fit(data_matrix)
query_no = np.random.choice(data_pivot.shape[0]) # 随机选择一个动漫标题并找到推荐
print(f"We will find recommendation for {query_no} no anime which is {data_pivot.index[query_no]}.")
distances, indices = model_knn.kneighbors(data_pivot.iloc[query_no, :].values.reshape(1, -1), n_neighbors=6)
上述代码的实现流程如下:
- 首先,导入了必要的库,包括scipy.sparse中的csr_matrix和sklearn.neighbors中的NearestNeighbors,用于处理稀疏矩阵和构建KNN模型。
- 然后,通过将用户评分数据转换为稀疏矩阵,创建了一个表示用户-物品关系的数据矩阵。
- 接着,使用NearestNeighbors构建了基于余弦相似性的KNN模型。这个模型将根据用户对动漫的评分计算相似性。
- 最后,从数据矩阵中随机选择一个动漫,然后使用KNN模型找到最相似的动漫,返回相似动漫的距离和索引。这可以作为推荐系统的一部分,为用户提供与其喜欢的动漫相似的其他动漫。
我们将为动漫编号为538的作品“Asari-chan: Ai no Marchen Shoujo”寻找推荐。
(2)使用协同过滤技术,基于用户评分数据,为指定动漫生成推荐列表。推荐是通过计算动漫之间的余弦相似度,找到与查询动漫最相似的几部动漫完成的。
no = []
name = []
distance = []
rating = []
for i in range(0, len(distances.flatten())):
if i == 0:
print(f"Recommendations for {data_pivot.index[query_no]} viewers :\n")
else:
no.append(i)
name.append(data_pivot.index[indices.flatten()[i]])
distance.append(distances.flatten()[i])
rating.append(*anime[anime["name"]==data_pivot.index[indices.flatten()[i]]]["rating"].values)
dic = {"No" : no, "Anime Name" : name, "Rating" : rating}
recommendation = pd.DataFrame(data = dic)
recommendation.set_index("No", inplace = True)
recommendation.style.set_properties(**{"background-color": "#2a9d8f","color":"white","border": "1.5px solid black"})
上述代码的实现流程如下:
- 首先,创建了四个空列表:no(编号)、name(动漫名称)、distance(相似度距离)和rating(评分)。接着,我们使用循环遍历相似度和索引数组,将结果添加到相应的列表中。在循环中,我们检查索引是否为0,如果是,则打印查询动漫的推荐标题;否则,我们添加相应的数据到我们的列表中。
- 最后,将这些列表转换为一个DataFrame,其中包含编号、动漫名称和评分,并将编号列设置为索引。最终,我们使用样式设置来美化DataFrame的外观。
上述代码执行后会生成一份推荐列表,列表包含了与查询动漫最相似的几部动漫,以及它们的评分。如图12-23所示。
图12-23 推荐列表