无监督学习算法:聚类技术在书籍推荐系统中的应用

无监督学习算法以其强大的功能和广泛的应用领域而著称。聚类算法,作为无监督学习中最著名的算法之一,近年来也取得了一些新的发展。随着HDBSCAN(层次密度基空间聚类应用噪声)的发展,一直在思考为什么需要开发一个层次和密度基的算法,层次聚类与平面聚类相比有哪些优势,以及哪种更适合机器学习项目,如推荐系统。

接下来,将展示一个比较平面和层次聚类算法的图书推荐系统的Python实现。

什么是聚类?

聚类是一种无监督的机器学习技术,它通过发现数据点之间的相似性并将它们分组到聚类中。它用于绘制参考并确定数据中的潜在结构。有多种聚类算法可供选择,它们主要分为两组:

基于质心/参数化的算法和基于密度的算法。基于质心的算法通过它们各自的中心(质心)来识别聚类。它们对聚类的形状做出了隐含和显式的假设。通常,基于质心的算法假设聚类是多维球体。这些算法适用于数据量较小的情况。

基于密度的算法确定数据点密度高的聚类。与基于质心的方法不同,这些不会给每个点分配一个聚类;相反,密度较低区域的点被归为噪声。

此外,这些算法被分为:

  • 平面聚类:平面聚类为提供单一的数据分组或分区。这些需要事先了解聚类,因为必须设置分辨率参数。平面聚类算法的例子是K-Means(分辨率参数k)、DBSCAN(分辨率参数eps)。
  • 层次聚类:层次聚类为提供数据之间的嵌套关系。它不需要事先了解聚类,因为它在聚类上创建了一种自然层次结构。这些算法假设每个点都是一个聚类,将每个点组合成一个单一的聚类。通常用树状图来表示这种层次结构。

构建这种层次结构有两种方法:

  • 聚合(自下而上)
  • 分裂(自上而下)

聚类的应用

聚类在不同的应用领域都有应用。以下是一些常见的应用平台,可以用来实现聚类:

  • 客户和市场细分
  • 社交网络分析
  • 推荐系统

在这里,将构建一个图书推荐引擎,并比较K-Means(平面)和聚合聚类(层次)聚类的应用。

图书推荐系统

将构建一个协同过滤推荐系统,其中将根据对书籍的喜好相似性对用户进行聚类。以下是逐步实现的步骤。

import pandas as pd import numpy as np from IPython.display import Image,display from IPython.core.display import HTML from sklearn.cluster import KMeans from sklearn.decomposition import PCA from sklearn.metrics import silhouette_score ,silhouette_samples import matplotlib.pyplot as plt import seaborn as sns import matplotlib.cm as cm from mpl_toolkits.mplot3d import Axes3D from sklearn.preprocessing import StandardScaler from scipy.cluster.hierarchy import linkage, dendrogram, cut_tree

有三个数据框,包含与书籍、用户和评分相关的信息。

Books = pd.read_csv('Books.csv',low_memory=False) Users = pd.read_csv('Users.csv',low_memory=False) Ratings = pd.read_csv('Ratings.csv')

在检查一些特征后,发现出版年份和用户年龄有一些无效值,因此需要修剪这些值。

Books = Books[(Books['Year-Of-Publication']>=1950) & (Books['Year-Of-Publication']<=2016)] Users = Users[(Users.Age>=15) & (Users.Age<=100)]

现在,只保留所有数据框中共同的书籍。

Ratings = Ratings[Ratings['ISBN'].isin(list(Books['ISBN'].unique()))] Ratings = Ratings[Ratings['User-ID'].isin(list(Users['User-ID'].unique()))]

必须定义一个人是否喜欢或不喜欢一本书,以便过滤。标准是:如果一个人给一本书的评分高于他们的平均评分,那么他们就喜欢这本书。这样做是因为基于评分对用户进行聚类可能会有问题,因为不能指望用户保持评分的一致性。

User_rating_mean = Ratings.groupby('User-ID')['Book-Rating'].mean() user_rating = Ratings.set_index('User-ID') user_rating['mean_rating'] = User_rating_mean user_rating.reset_index(inplace=True) user_rating = user_rating[user_rating['Book-Rating'] > user_rating['mean_rating']] user_rating['is_fav'] = 1

现在创建一个交叉表,以便每个用户最终成为一行,书籍成为列。

df = pd.pivot_table(user_rating,index='User-ID',columns='ISBN',values='is_fav') df.fillna(value=0,inplace=True)

找到正确的k值。将使用肘部方法来找到正确的k(聚类数量)。为此,将制作一个k与来自相应中心的总平方误差之和的折线图,看到肘部形成的地方被选为k的最优值。

TSS = [] for i in range(2,26): km = KMeans(n_clusters=i,random_state=0) km.fit(pca_fit) TSS.append(km.inertia_) plt.plot(range(2,26),TSS,'-') for n in [3,4,5,6,7,8]: km = KMeans(n_clusters=n,random_state=0) clusters = km.fit_predict(pca_fit) silhouette_avg = silhouette_score(pca_fit, clusters) print("For n_clusters =", n, "The average silhouette_score is :", silhouette_avg) mergings = linkage(pca_fit,method='ward') dendrogram(mergings) labels = cut_tree(mergings,n_clusters=4) d = df.copy() d['cluster'] = Kmeans_final.labels_ silhouette_avg = silhouette_score(pca_fit, labels) print("For n_clusters =", 4, "The average silhouette_score is :", silhouette_avg)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485