一.聚类算法简介
1.聚类的概念
聚类算法是一类无监督学习方法,旨在将数据划分为若干组(簇),使得同一簇内的样本相似度高,而不同簇间的样本差异大,根据样本之间的相似性,将样本划分到不同的类别中。
· 常用的计算相似度的方法有欧式距离法
不同的相似度计算方法,会得到不同的聚类结果:
2.聚类算法在生活中的应用
3.聚类算法的分类
①根据颗粒度分类:粗聚类,细聚类
②根据实现方法划分
基于划分的聚类:K-means算法->按照质心(一个簇的中心位置,通过均值计算)分类
基于层次的聚类:DIANA(自顶向下)AGNES(自底向上)
基于密度的聚类: DBSCAN算法
基于图的聚类: 谱聚类(Spectral Clustering)等等。
二.聚类算法API
sklearn.cluster.KMeans(n_clusters=8)
calinski_harabasz_score(x, y_pred) 用来评估聚类效果,数值越大越好
代码实现:
代码中用到了三个评估方法,寻找最优的k值,三个折线图放在一起有更直观的对比
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score,calinski_harabasz_score
# 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 准备散点数据
x, y = make_blobs(n_samples=1000, n_features=2, random_state=666,
centers=[[-1, -1],[0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.3, 0.2])
sse_list = []
sc_list = []
ch_list = []
# TODO sc,ch都需要多个簇才能计算,所以k值至少从2开始
for k in range(2, 11):
# 传入k聚类个数
km = KMeans(n_clusters=k)
pre = km.fit_predict(x)
# 获取sse结果
value = km.inertia_
# 把sse结果添加到列表中
sse_list.append(km.inertia_)
# TODO 获取sc结果
sc_value = silhouette_score(x, pre)
sc_list.append(sc_value)
# TODO 获取ch结果
ch_value = calinski_harabasz_score(x, pre)
ch_list.append(ch_value)
fig = plt.figure(figsize=(20, 25))
fig.add_subplot(311)
plt.plot(range(2, 11), sse_list,'or-')
plt.title("sse折线图")
plt.xlabel("k")
plt.ylabel("sse结果")
fig.add_subplot(312)
plt.plot(range(2, 11), sc_list, 'or-')
plt.title("sc折线图")
plt.xlabel("k")
plt.ylabel("sc结果")
fig.add_subplot(313)
plt.plot(range(2, 11), ch_list, 'or-')
plt.title("ch折线图")
plt.xlabel("k")
plt.ylabel("ch结果")
plt.show()
K在4时有最优值
三.KMeans算法的步骤
用下面两张图表示一下聚类中心的变化:(×代表聚类中心,圆点代表不同样本)
四.模型评估的方法
1.误差平方和SSE (The sum of squares due to error)
SSE 越小,表示数据点越接近它们的中心,聚类效果越好
“肘”方法确定最优k值
2.SC轮廓系数法(Silhouette Coefficient)
3. CH轮廓系数法(Calinski-Harabasz Index)
分数s高聚类效果好
CH达到目的:用尽量少的类别聚类尽量多的样本,同时获得较好的聚类效果
五.客户案例分析
# 导包
import pandas as pd
# 导入自定义模块中所有内容
from search_best_k import *
def get_data():
# 加载数据
data = pd.read_csv("data/customers.csv")
# 了解数据
# print(data.head())
# print(data.info())
# 获取数据(年收入和消费列)
X = data[["Annual Income (k$)", "Spending Score (1-100)"]]
return X
def draw_scatter(k, X):
# 创建模型
kmeans = KMeans(n_clusters=k)
# 训练并获取预测结果
pre = kmeans.fit_predict(X)
# 绘制散点图 分成5类
# 画0类散点图,分别用两个特征0,1作为横纵轴,s指定散点大小,c指定颜色,label标签名
plt.scatter(X.values[pre == 0, 0], X.values[pre == 0, 1], s=50, c='red', label='0类')
# 画1类散点图,分别用两个特征0,1作为横纵轴,s指定散点大小,c指定颜色,label标签名
plt.scatter(X.values[pre == 1, 0], X.values[pre == 1, 1], s=50, c='blue', label='1类')
# 画2类散点图,分别用两个特征0,1作为横纵轴,s指定散点大小,c指定颜色,label标签名
plt.scatter(X.values[pre == 2, 0], X.values[pre == 2, 1], s=50, c='green', label='2类')
# 画3类散点图,分别用两个特征0,1作为横纵轴,s指定散点大小,c指定颜色,label标签名
plt.scatter(X.values[pre == 3, 0], X.values[pre == 3, 1], s=50, c='yellow', label='3类')
# 画4类散点图,分别用两个特征0,1作为横纵轴,s指定散点大小,c指定颜色,label标签名
plt.scatter(X.values[pre == 4, 0], X.values[pre == 4, 1], s=50, c='orange', label='4类')
# 最后确定聚类中心
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=200, c='black', label='质心')
# TODO 设置标题,轴标签
plt.title('客户分类')
plt.xlabel('年收入')
plt.ylabel('消费能力')
plt.legend()
plt.show()
if __name__ == '__main__':
# TODO 需求:已知客户数据customers.csv,要求根据客户数据寻找黄金客户
# TODO 步骤0: 获取数据
X = get_data()
# TODO 步骤1: 调用自定的search模块寻找最优k值
# 根据数据通过sse,sc,ch确定最优的聚类个数
search_best_k(X)
k = 5
# TODO 步骤2: 传入上面获取的聚类个数训练并画出聚类散点图
# 定义一个画散点图函数
draw_scatter(k, X)
图中数据的链接:
链接: https://pan.baidu.com/s/1xmJJpOIcp5iTcmkGsjFXJw?pwd=qb87 提取码: qb87 复制这段内容后打开百度网盘手机App,操作更方便哦