K-Means聚类是数据科学中最常用的无监督学习算法之一。它根据数据点之间的相似性自动将数据集分割成簇或组。
在这个简短的教程中,我们将学习K-Means聚类算法的工作原理,并使用scikit-learn将其应用于真实数据。此外,我们将可视化结果以了解数据分布。
什么是K-Means聚类?
K-Means聚类是一种用于解决聚类问题的无监督机器学习算法。该算法的目标是找到数据中的群组或簇,其中簇的数量由变量K表示。
K-Means算法的工作步骤如下:
- 指定希望将数据分组为的簇的数量K。
- 随机初始化K个簇中心或质心。可以通过随机选择K个数据点作为初始质心来完成此操作。
- 根据欧几里德距离将每个数据点分配到最近的簇质心。与给定质心最近的数据点被视为该簇的一部分。
- 通过取分配给该簇的所有数据点的平均值来重新计算簇质心。
- 重复步骤3和4,直到质心停止移动或迭代达到指定的限制。当算法收敛时,这一过程结束。
K-Means的目标是将数据点与其分配的簇质心之间的平方距离之和最小化。通过迭代地将数据点重新分配给最近的质心,并将质心移动到其分配点的中心,从而实现更紧凑和分离的簇。
K-Means聚类的实际应用示例
在这些示例中,我们将使用Kaggle上的Mall Customer Segmentation数据,并应用K-Means算法。我们还将使用Elbow方法找到最佳的K(簇)数量,并可视化这些簇。
数据加载
我们将使用pandas加载一个CSV文件,并将“CustomerID”设置为索引。
import pandas as pd
df_mall = pd.read_csv("Mall_Customers.csv",index_col="CustomerID")
df_mall.head(3)
数据集有4列,我们只对其中三列感兴趣:顾客的年龄、年收入和消费得分。
可视化
为了可视化这四列数据,我们将使用seaborn的`scatterplot`。
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(1 , figsize = (10 , 5) )
sns.scatterplot(
data=df_mall,
x="Spending Score (1-100)",
y="Annual Income (k$)",
hue="Gender",
size="Age",
palette="Set2"
);
即使没有K-Means聚类,我们可以清楚地看到40-60的消费得分和40k到70k的年收入之间的簇。为了找到更多的簇,我们将在下一部分中使用聚类算法。
数据归一化
在应用聚类算法之前,将数据归一化以消除任何离群值或异常值非常重要。我们将删除“Gender”和“Age”列,并使用其余列来找到簇。
from sklearn import preprocessing
X = df_mall.drop(["Gender","Age"],axis=1)
X_norm = preprocessing.normalize(X)
肘部法则
可以使用肘部法则找到K-Means算法中的最佳K值。这涉及到找到从1到10个聚类数的每个K值的惯性值,并进行可视化。
import numpy as np
from sklearn.cluster import KMeans
def elbow_plot(data,clusters):
inertia = []
for n in range(1, clusters):
algorithm = KMeans(
n_clusters=n,
init="k-means++",
random_state=125,
)
algorithm.fit(data)
inertia.append(algorithm.inertia_)
# 绘图
plt.plot(np.arange(1 , clusters) , inertia , 'o')
plt.plot(np.arange(1 , clusters) , inertia , '-' , alpha = 0.5)
plt.xlabel('聚类数') , plt.ylabel('惯性')
plt.show();
elbow_plot(X_norm,10)
<p我们得到了一个最佳值为3。
KMeans聚类
我们将使用scikit-learn中的KMeans算法,并提供K值。然后我们将其拟合到我们的训练数据集上,并获得聚类标签。
algorithm = KMeans(n_clusters=3, init="k-means++", random_state=125)
algorithm.fit(X_norm)
labels = algorithm.labels_
我们可以使用散点图来可视化这三个聚类。
sns.scatterplot(data = X, x = 'Spending Score (1-100)', y = 'Annual Income (k$)', hue = labels, palette="Set2");
- “0”: 高消费者,低年收入。
- “1”: 平均到高消费者,年收入中等到高。
- “2”: 低消费者,高年收入。
这个洞察可以用来创建个性化广告,增加客户忠诚度和提高收入。
使用不同的特征
现在,我们将使用年龄和消费评分作为聚类算法的特征。这将给我们一个完整的客户分布图。我们将重复数据的归一化过程。
X = df_mall.drop(["Gender","Annual Income (k$)"],axis=1)
X_norm = preprocessing.normalize(X)
计算最佳的聚类数。
elbow_plot(X_norm,10)
在K=3个聚类下训练K-Means算法。
algorithm = KMeans(n_clusters=3, init="k-means++", random_state=125)
algorithm.fit(X_norm)
labels = algorithm.labels_
使用散点图来可视化这三个聚类。
sns.scatterplot(data = X, x = 'Age', y = 'Spending Score (1-100)', hue = labels, palette="Set2");
- “0”: 年轻高消费者。
- “1”: 从中年到老年的VoAGI消费者。
- “2”: 低消费者。
结果表明,公司可以通过针对年龄在20-40岁、有可支配收入的个体来增加利润。
我们甚至可以通过可视化花费评分的箱线图来深入了解。它清楚地显示出聚类是基于消费习惯形成的。
sns.boxplot(x = labels, y = X['Spending Score (1-100)']);
结论
在这个K-Means聚类教程中,我们探讨了如何应用K-Means算法进行客户细分以实现有针对性的广告投放。虽然K-Means并不是一个完美的、适用于所有聚类问题的算法,但它为许多实际应用提供了简单有效的方法。
通过Python实现K-Means的工作流程,并通过拐点法找到最佳的聚类数目,以及可视化聚类数据,我们对算法如何将数据分割成不同的聚类有了深入的了解。
虽然scikit-learn提供了许多其他聚类算法,但K-Means因其速度、可扩展性和易于解释性而脱颖而出。Abid Ali Awan(@1abidaliawan)是一位持有数据科学专业认证的专业人士,热衷于构建机器学习模型。目前,他专注于内容创作,并在机器学习和数据科学技术方面撰写技术博客。Abid拥有技术管理硕士学位和电信工程学士学位。他的愿景是利用图神经网络为患有心理疾病的学生构建一个AI产品。