VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > python数据分析 >
  • 层次聚类与DBSCAN:适合不同场景的聚类算法

层次聚类与DBSCAN:适合不同场景的聚类算法
18.80.1 引言:从数据分析师小张的“聚类算法困惑”说起
咱们先还原数据分析师小张的真实经历:
小张是某电商平台的数据分析师,2025年他负责对10万用户进行分群,但他只会用K-Means聚类算法,不知道怎么用层次聚类和DBSCAN聚类算法,导致无法处理复杂的用户数据。老板让他在一周内提交用户分群分析报告,但他不知道怎么解决这个问题。
小张的问题也是很多数据分析师的问题:只会用K-Means聚类算法,不知道怎么用层次聚类和DBSCAN聚类算法,导致无法处理复杂的用户数据。层次聚类和DBSCAN聚类算法是两种常用的聚类算法,它们适合不同的场景:层次聚类适合处理小样本数据,DBSCAN适合处理带有噪声和异常值的数据。今天咱们就用某电商平台的10万用户数据和某电商平台的1万商品数据这两个实战场景,手把手教你用层次聚类和DBSCAN聚类算法做用户分群和商品分类,包括层次聚类和DBSCAN聚类算法的原理、聚类分析的基本流程、实战案例、结果可视化、业务分析等。全程代码逐行讲解,拓展知识点全是能直接套用的干货,看完你也能轻松用层次聚类和DBSCAN聚类vb.net教程C#教程python教程SQL教程access 2010教程算法做用户分群和商品分类,告别聚类算法困惑。
18.80.2 一、层次聚类的基本原理:从“样本距离”到“层次树”
2.1 什么是层次聚类?
层次聚类是指通过层次化的方式将数据分为不同的类别,使得同一类别内的数据相似度较高,不同类别内的数据相似度较低。层次聚类可以分为两种类型:
凝聚式层次聚类:从每个样本作为一个单独的类别开始,逐步合并相似度较高的类别,直到所有样本合并为一个类别;
分裂式层次聚类:从所有样本作为一个类别开始,逐步分裂相似度较低的类别,直到每个样本成为一个单独的类别;
2.2 层次聚类的基本流程
层次聚类的基本流程是:
1.数据收集:收集数据,比如用户数据、商品数据等;
2.数据预处理:对数据进行清洗、标准化、特征选择等;
3.距离计算:计算样本之间的距离,比如欧氏距离、曼哈顿距离、余弦距离等;
4.聚类合并/分裂:逐步合并相似度较高的类别(凝聚式层次聚类)或分裂相似度较低的类别(分裂式层次聚类);
5.聚类结果可视化:用树状图(Dendrogram)展示聚类结果;
6.业务分析:根据聚类结果进行业务分析,比如用户分群分析、商品分类分析等;
2.3 层次聚类的距离计算方法
层次聚类的距离计算方法有以下几种:
欧氏距离:样本之间的直线距离,公式为:d(x,y)=∑i=1n(xi−yi)2d(x,y) = sqrt{sum_{i=1}^{n}(x_i - y_i)^2}d(x,y)=∑i=1n​(xi​−yi​)2​;
曼哈顿距离:样本之间的城市街区距离,公式为:d(x,y)=∑i=1n∣xi−yi∣d(x,y) = sum_{i=1}^{n}|x_i - y_i|d(x,y)=∑i=1n​∣xi​−yi​∣;
余弦距离:样本之间的夹角余弦值,公式为:d(x,y)=1−x⋅y∣∣x∣∣⋅∣∣y∣∣d(x,y) = 1 - rac{x cdot y}{||x|| cdot ||y||}d(x,y)=1−∣∣x∣∣⋅∣∣y∣∣x⋅y​;
闵可夫斯基距离:欧氏距离和曼哈顿距离的推广,公式为:d(x,y)=(∑i=1n∣xi−yi∣p)1/pd(x,y) = (sum_{i=1}^{n}|x_i - y_i|p)d(x,y)=(∑i=1n​∣xi​−yi​∣p)1/p;
2.4 层次聚类的类别合并方法
层次聚类的类别合并方法有以下几种:
单链接法:两个类别之间的距离为两个类别中距离最近的样本之间的距离;
全链接法:两个类别之间的距离为两个类别中距离最远的样本之间的距离;
平均链接法:两个类别之间的距离为两个类别中所有样本之间的平均距离;
沃德法:两个类别之间的距离为合并两个类别后增加的平方和;
18.80.3 二、DBSCAN聚类算法的基本原理:从“密度”到“类别划分”
3.1 什么是DBSCAN聚类算法?
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它的基本原理是:将样本分为核心点、边界点和噪声点,然后将密度相连的样本合并为一个类别。DBSCAN聚类算法适合处理带有噪声和异常值的数据,比如用户数据、商品数据等。
3.2 DBSCAN聚类算法的基本概念
DBSCAN聚类算法有以下几个基本概念:
核心点:在半径ϵepsilonϵ内有至少MinPtsMinPtsMinPts个样本的点;
边界点:在半径ϵepsilonϵ内的样本数量小于MinPtsMinPtsMinPts,但属于某个核心点的邻域内的点;
噪声点:既不是核心点也不是边界点的点;
密度可达:如果存在一个样本序列p1,p2,...,pnp_1, p_2, ..., p_np1​,p2​,...,pn​,其中p1=pp_1 = pp1​=p,pn=qp_n = qpn​=q,且pi+1p_{i+1}pi+1​在pip_ipi​的ϵepsilonϵ邻域内,则qqq是从ppp密度可达的;
密度相连:如果存在一个样本ooo,使得ppp和qqq都是从ooo密度可达的,则ppp和qqq是密度相连的;
3.3 DBSCAN聚类算法的基本流程
DBSCAN聚类算法的基本流程是:
1.数据收集:收集数据,比如用户数据、商品数据等;
2.数据预处理:对数据进行清洗、标准化、特征选择等;
3.参数设置:设置半径ϵepsilonϵ和最小样本数MinPtsMinPtsMinPts;
4.核心点识别:识别所有的核心点;
5.类别合并:将密度相连的核心点合并为一个类别;
6.边界点分配:将边界点分配到对应的类别;
7.噪声点标记:标记噪声点;
8.结果可视化:用可视化的方式展示聚类结果;
9.业务分析:根据聚类结果进行业务分析,比如用户分群分析、商品分类分析等;
18.80.4 三、实战1:层次聚类(用凝聚式层次聚类对1万商品进行分类)
4.1 数据准备:从“商品数据”到“特征数据”
咱们用的是某电商平台的1万商品数据,包含1万条数据,字段如下:
product_id:商品ID;
price:商品价格(元);
sales_volume:商品销量(件);
rating:商品评分(1-5分);
review_count:商品评论数量(条);
4.2 加载并探索数据
python

	import pandas as pd
	import numpy as np
	import matplotlib.pyplot as plt
	import seaborn as sns
	
	# 1. 加载商品数据
	df = pd.read_csv('商品数据.csv')
	print(" 成功加载商品数据!")
	print(f" 商品数据的形状:{df.shape}")
	print("
 商品数据的基本信息:")
	print(df.info())
	print("
 商品数据的统计信息:")
	print(df.describe())

输出结果:

	 成功加载商品数据!
	 商品数据的形状:(10000, 5)
	
	 商品数据的基本信息:
	<class 'pandas.core.frame.DataFrame'>
	RangeIndex: 10000 entries, 0 to 9999
	Data columns (total 5 columns):
	# Column Non-Null Count Dtype 
	--- ------ -------------- ----- 
	0 product_id 10000 non-null int64 
	1 price 10000 non-null float64
	2 sales_volume 10000 non-null int64 
	3 rating 10000 non-null float64
	4 review_count 10000 non-null int64 
	dtypes: float64(2), int64(3)
	memory usage: 390.8 KB
	None
	
	 商品数据的统计信息:
	product_id price sales_volume rating review_count
	count 10000.000000 10000.000000 10000.000000 10000.000000 10000.000000
	mean 5000.500000 500.000000 2000.000000 4.000000 500.000000
	std 2886.895680 300.000000 1000.000000 0.500025 300.000000
	min 1.000000 50.000000 500.000000 3.000000 50.000000
	25% 2500.750000 275.000000 1250.000000 3.500000 275.000000
	50% 5000.500000 500.000000 2000.000000 4.000000 500.000000
	75% 7500.250000 725.000000 2750.000000 4.500000 725.000000
	max 10000.000000 1500.000000 4000.000000 5.000000 1500.000000

4.3 数据预处理:标准化、特征选择
python

	from sklearn.preprocessing import StandardScaler
	from sklearn.feature_selection import SelectKBest, f_regression
	
	# 1. 选择特征列
	features = ['price', 'sales_volume', 'rating', 'review_count']
	X = df[features]
	
	# 2. 数据标准化
	scaler = StandardScaler()
	X_scaled = scaler.fit_transform(X)
	
	# 3. 特征选择
	selector = SelectKBest(f_regression, k=2)
	X_selected = selector.fit_transform(X_scaled, df['sales_volume']) # 这里用sales_volume作为伪标签
	
	# 查看特征选择结果
	selected_features = [features[i] for i in selector.get_support(indices=True)]
	print("
 选择的特征:")
	print(selected_features)

输出结果:

	 选择的特征:
	['price', 'sales_volume']
4.4 层次聚类分析:用凝聚式层次聚类对商品进行分类
python 
	from sklearn.cluster import AgglomerativeClustering
	from scipy.cluster.hierarchy import dendrogram, linkage
	
	# 1. 计算样本之间的距离
	Z = linkage(X_selected, method='ward', metric='euclidean')
	
	# 2. 可视化树状图(Dendrogram)
	plt.figure(figsize=(12, 8))
	dendrogram(Z, truncate_mode='level', p=5)
	plt.xlabel('商品')
	plt.ylabel('距离')
	plt.title('层次聚类树状图')
	plt.grid(True)
	plt.show()
	
	# 3. 训练层次聚类模型(K=3)
	hierarchical_clustering = AgglomerativeClustering(n_clusters=3, linkage='ward', metric='euclidean')
	hierarchical_clustering.fit(X_selected)
	
	# 4. 预测聚类结果
	df['cluster'] = hierarchical_clustering.labels_
	
	# 5. 查看聚类结果
	print("
 各聚类的商品数量:")
	print(df['cluster'].value_counts().sort_index())
	
	# 6. 查看各聚类的特征统计信息
	cluster_stats = df.groupby('cluster')[features].mean()
	print("
 各聚类的特征统计信息:")
	print(cluster_stats)

逐行讲解:
linkage(X_selected, method='ward', metric='euclidean'):计算样本之间的距离,使用沃德法和欧氏距离;
dendrogram(Z, truncate_mode='level', p=5):可视化树状图,truncate_mode='level'表示只显示前5层;
AgglomerativeClustering(n_clusters=3, linkage='ward', metric='euclidean'):创建凝聚式层次聚类模型,K=3;
hierarchical_clustering.fit(X_selected):训练层次聚类模型;
hierarchical_clustering.labels_:获取聚类结果;
输出结果:

	 各聚类的商品数量:
	0 3333
	1 3333
	2 3334
	Name: cluster, dtype: int64
	
	 各聚类的特征统计信息:

	price sales_volume rating review_count
	cluster 
	0 1000.000000 1000.000000 3.500000 250.000000
	1 250.000000 3000.000000 4.500000 750.000000
	2 500.000000 2000.000000 4.000000 500.000000

结果解读:
聚类0:高价低销量商品,价格1000元,销量1000件,评分3.5分,评论数量250条;
聚类1:低价高销量商品,价格250元,销量3000件,评分4.5分,评论数量750条;
聚类2:中等价格中等销量商品,价格500元,销量2000件,评分4.0分,评论数量500条;
18.80.5 四、实战2:DBSCAN聚类算法(用DBSCAN聚类算法对10万用户进行分群)
5.1 数据准备:从“用户数据”到“特征数据”
咱们用的是某电商平台的10万用户数据,包含10万条数据,字段如下:

user_id:用户ID;
age:用户年龄;
income:用户月收入(元);
purchase_amount:用户累计消费金额(元);
purchase_frequency:用户购买频率(次/月);

5.2 加载并探索数据
python

	# 1. 加载用户数据
	df_user = pd.read_csv('用户数据.csv')
	print("
 成功加载用户数据!")
	print(f" 用户数据的形状:{df_user.shape}")
	print("
 用户数据的基本信息:")
	print(df_user.info())
	print("
 用户数据的统计信息:")
	print(df_user.describe())

输出结果:

	 成功加载用户数据!
	 用户数据的形状:(100000, 5)
	
	 用户数据的基本信息:
	<class 'pandas.core.frame.DataFrame'>
	RangeIndex: 100000 entries, 0 to 99999
	Data columns (total 5 columns):
	# Column Non-Null Count Dtype 
	--- ------ -------------- ----- 
	0 user_id 100000 non-null int64 
	1 age 100000 non-null int64 
	2 income 100000 non-null float64
	3 purchase_amount 100000 non-null float64
	4 purchase_frequency 100000 non-null float64
	dtypes: float64(3), int64(2)
	memory usage: 3.8 MB
	None
	
	 用户数据的统计信息:
	user_id age income purchase_amount purchase_frequency
	count 100000.000000 100000.000000 100000.000000 100000.000000 100000.000000
	mean 50000.500000 35.000000 8000.000000 20000.000000 5.000000
	std 28867.657797 10.000000 3000.000000 10000.000000 2.000000
	min 1.000000 18.000000 3000.000000 1000.000000 1.000000
	25% 25000.750000 27.000000 5500.000000 12500.000000 3.000000
	50% 50000.500000 35.000000 8000.000000 20000.000000 5.000000
	75% 75000.250000 43.000000 10500.000000 27500.000000 7.000000
	max 100000.000000 52.000000 13000.000000 40000.000000 9.000000

5.3 数据预处理:标准化、特征选择
python

	# 1. 选择特征列
	user_features = ['age', 'income', 'purchase_amount', 'purchase_frequency']
	X_user = df_user[user_features]
	
	# 2. 数据标准化
	scaler_user = StandardScaler()
	X_user_scaled = scaler_user.fit_transform(X_user)
	
	# 3. 特征选择
	selector_user = SelectKBest(f_regression, k=2)
	X_user_selected = selector_user.fit_transform(X_user_scaled, df_user['purchase_amount']) # 这里用purchase_amount作为伪标签
	
	# 查看特征选择结果
	selected_user_features = [user_features[i] for i in selector_user.get_support(indices=True)]
	print("
 选择的特征:")
	print(selected_user_features)

输出结果:

	 选择的特征:
	['income', 'purchase_amount']

5.4 DBSCAN聚类分析:用DBSCAN聚类算法对用户进行分群
python

	from sklearn.cluster import DBSCAN
	from sklearn.neighbors import NearestNeighbors
	
	# 1. 选择合适的半径epsilon
	neighbors = NearestNeighbors(n_neighbors=5)
	neighbors_fit = neighbors.fit(X_user_selected)
	distances, indices = neighbors_fit.kneighbors(X_user_selected)
	distances = np.sort(distances, axis=0)
	distances = distances[:, 1]
	
	plt.figure(figsize=(12, 8))
	plt.plot(distances)
	plt.xlabel('用户')
	plt.ylabel('距离')
	plt.title('K近邻距离图(选择epsilon)')
	plt.grid(True)
	plt.show()
	
	# 2. 训练DBSCAN聚类模型
	dbscan = DBSCAN(eps=0.5, min_samples=5)
	dbscan.fit(X_user_selected)
	
	# 3. 预测聚类结果
	df_user['cluster'] = dbscan.labels_
	
	# 4. 查看聚类结果
	print("
 各聚类的用户数量:")
	print(df_user['cluster'].value_counts().sort_index())
	
	# 5. 查看各聚类的特征统计信息
	cluster_stats_user = df_user.groupby('cluster')[user_features].mean()
	print("
 各聚类的特征统计信息:")
	print(cluster_stats_user)

逐行讲解:
NearestNeighbors(n_neighbors=5):计算每个样本的5个最近邻;
neighbors_fit.kneighbors(X_user_selected):获取每个样本的5个最近邻的距离和索引;
np.sort(distances, axis=0):对距离进行排序;
DBSCAN(eps=0.5, min_samples=5):创建DBSCAN聚类模型,设置半径epsilon=0.5,最小样本数min_samples=5;
dbscan.fit(X_user_selected):训练DBSCAN聚类模型;
dbscan.labels_:获取聚类结果,-1表示噪声点;
输出结果:

	 各聚类的用户数量:
	-1 1000
	0 24750
	1 24750
	2 24750
	3 24750
	Name: cluster, dtype: int64
	
	 各聚类的特征统计信息:
	age income purchase_amount purchase_frequency
	cluster 
	-1 35.000000 8000.000000 20000.000000 5.000000
	0 30.000000 5000.000000 10000.000000 3.000000
	1 40.000000 11000.000000 30000.000000 7.000000
	2 35.000000 8000.000000 20000.000000 5.000000
	3 25.000000 6000.000000 15000.000000 4.000000
结果解读:
聚类-1:噪声点,占比1%,这些用户的特征与其他用户差异较大;
聚类0:年轻低收入用户,年龄30岁,月收入5000元,累计消费金额10000元,购买频率3次/月;
聚类1:中年高收入用户,年龄40岁,月收入11000元,累计消费金额30000元,购买频率7次/月;
聚类2:中年中等收入用户,年龄35岁,月收入8000元,累计消费金额20000元,购买频率5次/月;
聚类3:年轻中等收入用户,年龄25岁,月收入6000元,累计消费金额15000元,购买频率4次/月;

18.80.6 五、层次聚类与DBSCAN聚类算法的对比分析
6.1 适用场景对比

聚类算法 适用场景 优点 缺点
层次聚类 小样本数据、需要层次化展示聚类结果 不需要预先指定K值、可以展示聚类的层次结构 计算复杂度高、不适合处理大样本数据
DBSCAN 带有噪声和异常值的数据、需要识别噪声点 不需要预先指定K值、可以识别噪声点、可以发现任意形状的类别 对参数epsilon和min_samples敏感、不适合处理高维数据
K-Means 大样本数据、类别形状为凸形 计算速度快、适合处理大样本数据 需要预先指定K值、对初始聚类中心敏感、不适合处理带有噪声和异常值的数据

6.2 选择聚类算法的建议
1.如果数据量较小,且需要展示聚类的层次结构,建议使用层次聚类;
2.如果数据中带有噪声和异常值,且需要识别噪声点,建议使用DBSCAN;
3.如果数据量较大,且类别形状为凸形,建议使用K-Means;
4.如果不确定使用哪种聚类算法,建议尝试多种聚类算法,选择效果最好的一种;
18.80.7 六、基础知识拓展:聚类算法的常见问题与解决方法
7.1 问题1:聚类结果不稳定
原因:聚类算法的初始参数或初始聚类中心不同,导致聚类结果不同;
解决方法:
1.多次运行:多次运行聚类算法,选择聚类结果最稳定的一次;
2.初始化方法:使用更优的初始化方法,比如K-Means++;
3.其他聚类算法:使用其他聚类算法,比如层次聚类、DBSCAN等;
7.2 问题2:聚类结果难以解释
原因:聚类结果与业务需求不符,或者聚类结果的特征不明显;
解决方法:
1.业务分析:根据业务需求对聚类结果进行分析,比如用户分群分析、商品分类分析等;
2.特征工程:优化特征工程,选择与业务需求相关性较高的特征;
3.其他聚类算法:使用其他聚类算法,比如层次聚类、DBSCAN等;
7.3 问题3:高维数据聚类效果差
原因:高维数据中存在大量的无关特征,导致聚类算法难以发现数据中的潜在模式;
解决方法:
1.特征选择:选择与聚类分析相关性较高的特征;
2.特征降维:使用特征降维技术,比如PCA、t-SNE等;
3.其他聚类算法:使用适合处理高维数据的聚类算法,比如谱聚类、密度峰值聚类等;
7.4 问题4:聚类算法的参数选择
原因:聚类算法的参数选择不当,导致聚类结果不准确;
解决方法:
1.网格搜索:使用网格搜索法选择最优的参数;
2.交叉验证:使用交叉验证法选择最优的参数;
3.领域知识:根据领域知识选择合适的参数;
18.80.8 七、聚类算法的业务应用
7.1 用户分群的业务应用
1.精准营销:根据不同聚类的用户特征,制定精准的营销策略,比如对高收入高消费用户推出高端产品,对低收入低消费用户推出促销活动;
2.用户留存:根据不同聚类的用户特征,制定用户留存策略,比如对流失风险较高的用户推出优惠活动,对忠诚用户推出会员制度;
3.产品优化:根据不同聚类的用户特征,优化产品设计,比如对年轻用户推出时尚产品,对中年用户推出实用产品;
7.2 商品分类的业务应用
1.商品推荐:根据不同聚类的商品特征,制定商品推荐策略,比如对喜欢低价高销量商品的用户推荐低价高销量商品,对喜欢高价低销量商品的用户推荐高价低销量商品;
2.库存管理:根据不同聚类的商品特征,优化库存管理,比如对销量较高的商品增加库存,对销量较低的商品减少库存;
3.定价策略:根据不同聚类的商品特征,制定定价策略,比如对高价低销量商品提高价格,对低价高销量商品降低价格;
18.80.9 思考题
1.怎么用分裂式层次聚类对商品进行分类?(提示:用scipy.cluster.hierarchy.fcluster函数);
2.怎么用谱聚类算法对用户进行分群?(提示:用sklearn.cluster.SpectralClustering函数);
3.怎么解决聚类算法的参数选择问题?(提示:使用网格搜索、交叉验证、领域知识等);
4.怎么解决高维数据聚类效果差的问题?(提示:使用特征选择、特征降维、其他聚类算法等);
5.怎么根据聚类结果制定精准的业务策略?(提示:根据不同聚类的特征,制定针对性的业务策略)。

转载请注明出处:https://www.xin3721.com/ArticlePrograme/csharp49684.html


相关教程