机器学习之KMeans聚类算法原理(附案例实战)

机器学习之KMeans聚类算法原理(附案例实战) felix 2023-07-24 14:55:28 321

KMeans聚类

什么是聚类任务

  • 1 无监督机器学习的一种
  • 2 目标将已有数据根据相似度划分到不同的簇
  • 3 簇内样本彼此之间越相似,不同簇的样本之间越不相似,就越好

为什么叫KMeans聚类

  • 1 也可以叫K均值聚类
  • 2 K是最终簇数量,它是超参数,需要预先设定
  • 3 在算法计算中会涉及到求均值

    KMeans流程

  • 1 随机选择K个簇中心点

  • 2 样本被分配到离其最近的中心点
  • 3 K个簇中心点根据所在簇样本,以求平均值的方式重新计算
  • 4 重复第2步和第3步直到所有样本的分配不再改变

    如何计算样本到中心点的距离

1.欧氏距离测度 Euclidean Distance Measure

欧氏距离越大,相似度越低

2.余弦距离测度 Cosine Similarity Measure

夹角越大,余弦值越小,相似度越低

因为是cosine,所以取值范围是-1到1之间,它判断的是向量之间的 方向而不是大小;两个向量有同样的方向那么cosine相似度为1,两 个向量方向相对成90°那么cosine相似度为0,两个向量正相反那么 cosine相似度为-1,和它们的大小无关。

选择Cosine相似度还是欧氏距离

总体来说,欧氏距离体现数值上的绝对差异,而余弦距离体现方向 上的相对差异。

例如,统计两部剧的用户观看行为,用户A的观看向量为(0, 1),用户B为(1,0);此时二者的余弦距离很大,而欧氏距离很 小;我们分析两个用户对于不同视频的偏好,更关注相对差异,显 然应当使用余弦距离。 而当我们分析用户活跃度,以登陆次数(单位:次)和平均观看时长 (单位:分钟)作为特征时,余弦距离会认为(1,10)、(10, 100)两个用户距离很近;但显然这两个用户活跃度是有着极大差 异的,此时我们更关注数值绝对差异,应当使用欧氏距离。

KMeans算法目标函数

上面的公式既是要去最小化的目标函数,同时也可以作为评价 KMeans聚类效果好坏的评估指标。

KMeans算法不保证找到最好的解

事实上,我们随机初始化选择了不同的初始中心点,我们或许会获 得不同的结果,就是所谓的收敛到不同的局部最优;这其实也就从 事实上说明了目标函数是非凸函数。

一个通常的做法就是运行KMeans很多次,每次随机初始化不同的 初始中心点,然后从多次运行结果中选择最好的局部最优解。

KMeans算法K的选择

没有所谓最好的选择聚类数的方法,通常是需要根据不同的问题, 人工进行选择的。

肘部法则(Elbow method)

改变聚类数K,然后进行聚类,计算损失函数,拐点处即为推荐的聚 类数 (即通过此点后,聚类数的增大也不会对损失函数的下降带来很 大的影响,所以会选择拐点)。

目标法则

如果聚类本身是为了有监督任务服务的(例如聚类产生features 【譬如KMeans用于某个或某些个数据特征的离散化】然后将 KMeans离散化后的特征用于下游任务),则可以直接根据下游任 务的metrics进行评估更好。

KMeans实战案例-NBA球队实力聚类分析

导包

  1. from sklearn.cluster import KMeans
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import pandas as pd
  5. from sklearn.preprocessing import MinMaxScaler

导入数据

  1. data = pd.read_csv('nba.csv')
  2. data.head()

处理数据

  1. minmax_scaler = MinMaxScaler()
  2. # 标准化数据
  3. X = minmax_scaler.fit_transform(data.iloc[:,1:])

使用肘部法则确定聚类的K值

  1. # 肘部法则
  2. loss = []
  3. for i in range(2,10):
  4. model = KMeans(n_clusters=i).fit(X)
  5. loss.append(model.inertia_)
  6. plt.plot(range(2,10),loss)
  7. plt.xlabel('k')
  8. plt.ylabel('loss')
  9. plt.show()

使用肘部法则,我们一般选取的是曲线平缓的时候,这里我们选取4作为K值

  1. k = 4
  2. model = KMeans(n_clusters=k).fit(X)
  3. # 将标签整合到原始数据上
  4. data['clusters'] = model.labels_
  5. data.head()

查看聚类统计结果

  1. for i in range(k):
  2. print('clusters:',i)
  3. label_data = data[data['clusters'] == i].iloc[:,0]
  4. print(label_data.values)

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
felix
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
felix
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区