K-means算法

这篇具有很好参考价值的文章主要介绍了K-means算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. K-means算法简介

K-means算法是一种聚类算法,所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。聚类与分类最大的区别在于,聚类过程为无监督过程,即待处理数据对象没有任何先验知识,而分类过程为有监督过程,即存在有先验知识的训练数据集。

2. K-means算法原理

K-means算法解决的问题是,在事先不知道如何分类的情况下(即无监督),让程序根据距离的远近,把N个对象(局部)最优的划分为k个类。它是无监督算法中比较常见的一种算法,原理比较简单易懂。本质是通过循环,不断迭代类中心点,计算各个对象到新的类中心点的距离并根据距离最近的原则重新归类,当类内距离最小、类间距离最大时,即可停止迭代(使用中,常常会限定迭代次数,防止陷入死循环。当达到预先设定得循环次数或类中心点不再发生变化时,最后一次迭代得到的结果,即为最终聚类结果)。

2.1 算法具体步骤

算法具体步骤如下:
第一步:指定聚类类数k(此处涉及k的选择方法);
第二步:选定初始化聚类中心。随机或指定k个对象,作为初始化聚类中心(此处随机选的方法可以升级,以达到更好的聚类效果,比如kmeans++聚类算法);
第三步:得到初始化聚类结果。计算每个对象到k个聚类中心的距离,把每个对象分配给离它最近的聚类中心所代表的类别中,全部分配完毕即得到初始化聚类结果,聚类中心连同分配给它的对象作为一类;
第四步:重新计算聚类中心。得到初始化聚类结果后,重新计算每类的类中心点(计算均值),得到新的聚类中心;
第五步:迭代循环,得到最终聚类结果。重复第三步和第四步,直到满足迭代终止条件。

2.2 k取值方法

结合书本中理论和在实际业务中遇到的情况,总结出以下几点k值的选择方法供参考:
1、如果实际业务中,数据维度不超过三维,可先通过画散点图的方法大致确定聚类数目。
2、工作中,结合业务方需求背景或经验,可敲定聚类数目。如,做用户的RFM模型(k=3)、判断是否为作弊用户(k=2)等。
3、实际业务中做探索性分析时,没有经验等做参考,可使用肘方法(elbow method)确定分类数。此处结合第一部分提到的误差平方和最小来一起理解。要使误差平方和变小,一种方法就是增加类数,这样有助于降低每个类的类内误差平方和,从而降低整体的误差平方和。但若类数太多,一是归类后解释困难,另一个降低类内误差平方和的边际效应可能下降(即增加类数k,误差平方和降低的不显著)。此时,k取误差平方和关于k的曲线的拐点。
4、交叉验证方法。将N个对象分为m个部分,用m-1个部分建立聚类模型,并用剩下的一部分检验聚类质量。
5、轮廓系数法。计算k取不同值时的轮廓系数,选择轮廓系数较接近1的分类数。

下面具体介绍手肘法轮廓系数法

2.2.1 手肘法

核心公式:SSE(sum of the squared errors,误差平方和)

K-means算法

其中,Ci是第i个簇;x是Ci中的样本点;mi是Ci的质心(Ci中所有样本的均值);SSE是所有样本的聚类误差,代表了聚类效果的好坏。

随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小。当k小于真实聚类数时,由于k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大,而当k到达真实聚类数时,再增加k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着k值的继续增大而趋于平缓,也就是说SSE和k的关系图是一个手肘的形状,而这个肘部对应的k值就是数据的真实聚类数。

K-means算法

显然,肘部对于的k值为4,梯度最大,下降最快,故对于这个数据集的聚类而言,最佳聚类数应该选4。

2.2.2 轮廓系数法

具体方法如下:
1)计算样本i到同簇其他样本的平均距离ai。ai越小,说明样本i越应该被聚类到该簇。将ai称为样本i的簇内不相似度。簇C中所有样本的均值称为簇C的簇不相似度。
2)计算样本i到其他某簇Cj的所有样本的平均距离bij,称为样本i与簇Cj的不相似度。定义为样本i的簇间不相似度:K-means算法
,bi越大,说明样本i越不属于其他簇。
3)根据样本i的簇内不相似度ai和簇间不相似度bi,定义样本i的轮廓系数。

K-means算法

轮廓系数范围在[-1,1]之间。该值越大,越合理。si接近1,则说明样本i聚类合理;接近-1,则说明样本i更应该分类到另外的簇;若si近似为0,则说明样本i在两个簇的边界上。

所有样本的si的均值称为聚类结果的轮廓系数,是该聚类是否合理、有效的度量。使用轮廓系数(silhouette coefficient)来确定,选择使系数较大所对应的k值。

2.3 K-means++

我们知道初始值的选取对结果的影响很大,对初始值选择的改进是很重要的一部分。在所有的改进算法中,K-means++最有名。K-means++算法步骤如下所示:(1)随机选取一个中心点a1
(2)计算数据到之前n个聚类中心最远的距离D(x),并以一定概率K-means算法
选择新中心点ai
(3)重复第二步。

简单的来说,K-means++就是选择离已选中心点最远的点。这也比较符合常理,聚类中心当然是互相离得越远越好。但是这个算法的缺点在于,难以并行化。所以k-meansII改变取样策略,并非按照k-means++那样每次遍历只取样一个样本,而是每次遍历取样k个,重复该取样过程log(n)次,则得到klog(n)个样本点组成的集合,然后从这些点中选取k个。当然一般也不需要log(n)次取样,5次即可。

2.4 算法终止条件

终止条件一般为以下几类:
a、达到预先设定的迭代次数,如20次。
b、类中心点不再发生变化或没有对象被分配给新的类。
c、误差平方和最小,误差平方和公式:K-means算法
,其中Xi代表被分到第i类的对象集合,μc(i)代表第i个聚类的均值(即类中心),c可以理解为迭代这个步骤,因为c随着迭代而发生变化,所以也是个变量。

在实际编程实现算法时,a常配合着c(误差平方和最小化)一起使用,由于使误差平方和最小有时会陷入死循环或迭代多步类中心变化不大,因此常会限制迭代次数。

3. K-means算法特点

优点:
1)容易理解,聚类效果不错,虽然是局部最优,但往往局部最优就够了。
2)处理大数据集的时候,该算法可以保证较好的伸缩性。
3)当簇近似高斯分布的时候,效果非常不错。
4)算法复杂度低。
5)主要需要调参的参数仅仅是簇数k。

缺点:
1)K值的选取不好把握。
2)结果的好坏依赖于初始类中心的选择。
3)算法常陷入局部最优,更换初始聚类中心后,新的聚类结果可能效果更优。
4)对孤立点敏感,如数据集存在异常突出点,会影响聚类效果。
5)不适合太离散的分类、样本类别不平衡的分类、非凸形状的分类。

4. K-means算法应用场景

1、隐含类别的数据较为平衡的情况,如隐含类别的数据量差别较大,则聚类的效果就较差。
2、数据最好是凸数据,即隐含类别间的差异越大,则聚类效果越好,因为中心点不再变化所需要的迭代次数较少,比较容易收敛。
3、一般作为数据预处理,或者用于辅助分类贴标签使用,因为在已经经过分类的数据上再进行聚类,准确度会非常高。

5. K-means算法的Python应用

5.1 K-means算法的Python实现

以一系列二维点作为原始数据,通过K-means算法来预测新的点属于哪一类。测试代码如下:

# -*- coding:utf-8 -*-
import random

import numpy as np
from matplotlib import pyplot


class K_Means(object):
    # k是分组数;tolerance'中心点误差';max_iter是迭代次数
    def __init__(self, k=2, tolerance=0.0001, max_iter=300):
        self.k_ = k
        self.tolerance_ = tolerance
        self.max_iter_ = max_iter

    def fit(self, data):
        self.centers_ = {}
        for i in range(self.k_):
            self.centers_[i] = data[random.randint(0,len(data))]
        # print('center', self.centers_)
        for i in range(self.max_iter_):
            self.clf_ = {} #用于装归属到每个类中的点[k,len(data)]
            for i in range(self.k_):
                self.clf_[i] = []
            # print("质点:",self.centers_)
            for feature in data:
                distances = [] #装中心点到每个点的距离[k]
                for center in self.centers_:
                    # 欧拉距离
                    distances.append(np.linalg.norm(feature - self.centers_[center]))
                classification = distances.index(min(distances))
                self.clf_[classification].append(feature)

            # print("分组情况:",self.clf_)
            prev_centers = dict(self.centers_)

            for c in self.clf_:
                self.centers_[c] = np.average(self.clf_[c], axis=0)

            # '中心点'是否在误差范围
            optimized = True
            for center in self.centers_:
                org_centers = prev_centers[center]
                cur_centers = self.centers_[center]
                if np.sum((cur_centers - org_centers) / org_centers * 100.0) > self.tolerance_:
                    optimized = False
            if optimized:
                break

    def predict(self, p_data):
        distances = [np.linalg.norm(p_data - self.centers_[center]) for center in self.centers_]
        index = distances.index(min(distances))
        return index


if __name__ == '__main__':
    x = np.array([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]])
    k_means = K_Means(k=2)
    k_means.fit(x)
    for center in k_means.centers_:
        pyplot.scatter(k_means.centers_[center][0], k_means.centers_[center][1], marker='*', s=150)

    for cat in k_means.clf_:
        for point in k_means.clf_[cat]:
            pyplot.scatter(point[0], point[1], c=('r' if cat == 0 else 'b'))

    predict = [[2, 1], [6, 9]]
    for feature in predict:
        cat = k_means.predict(feature)
        pyplot.scatter(feature[0], feature[1], c=('r' if cat == 0 else 'b'), marker='x')

    pyplot.show()
 

效果如下:

K-means算法

上图可见,所有点被分成了两类(圆点):红色和蓝色,预测的点(×)被正确分到了所属类别。

5.2 sklearn.cluster.Kmeans函数的应用

sklearn库使用sklearn.cluster.KMeans函数来实现K-Means算法,其函数原型如下:

sklearn.cluster.KMeans(n_clusters=8,*,init='k-means++', n_init=10,max_iter=300,tol=0.0001,precompute_distances='deprecated',verbose=0,random_state=None,copy_x=True,n_jobs='deprecated',algorithm='auto')

参数说明:

n_clusters:int, default=8,簇的个数,即你想聚成几类。

init:{‘k-means++’, ‘random’, ndarray, callable}, default=’k-means++’,初始簇中心的获取方法,‘k-means ++’:以一种聪明的方式为k-mean聚类选择初始聚类中心,以加快收敛速度。有关更多详细信息,请参见k_init中的注释部分。‘random’:n_clusters从初始质心的数据中随机选择观察(行)。如果传递了ndarray,则其形状应为(n_clusters,n_features),并给出初始中心。如果传递了callable,则应使用参数X,n_clusters和随机状态并返回初始化。

n_init:int, default=10,获取初始簇中心的更迭次数,k均值算法将在不同质心种子下运行的次数。

max_iter:int, default=300,最大迭代次数(因为kmeans算法的实现需要迭代),单次运行的k均值算法的最大迭代次数。

tol:float, default=1e-4,容忍度,即kmeans运行准则收敛的条件,关于Frobenius范数的相对容差,该范数表示两个连续迭代的聚类中心的差异,以声明收敛。

precompute_distances:{‘auto’, True, False}, default=‘auto’,是否需要提前计算距离,这个参数会在空间和时间之间做权衡,如果是True 会把整个距离矩阵都放到内存中,auto 会默认在数据样本大于featurs*samples 的数量大于12e6 的时候False,False 时核心实现的方法是利用Cpython 来实现的。

verbose:int, default=0,冗长模式(不太懂是啥意思,反正一般不去改默认值)。

random_state:int, RandomState instance, default=None,确定质心初始化的随机数生成。使用整数使随机性具有确定性。

copy_x:bool, default=True, 对是否修改数据的一个标记,如果True,即复制了就不会修改数据。bool 在scikit-learn 很多接口中都会有这个参数的,就是是否对输入数据继续copy 操作,以便不修改用户的输入数据。这个要理解Python 的内存机制才会比较清楚。

n_job:sint, default=None,并行设置。

algorithm:{‘auto’, ‘full’, ‘elkan’}, default=‘auto’,kmeans的实现算法,经典的EM风格算法是’full’的。通过使用三角形不等式,‘elkan’变异对于定义良好的聚类的数据更有效。但是,由于分配了额外的形状数组(n_samples,n_clusters),因此需要更多的内存。目前,‘auto’(保持向后兼容性)选择’elkan’,但为了更好的启发式,将来可能会更改。

测试代码如下:

# 导入可视化工具包
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import numpy as np
import pandas as pd

X=load_iris().data
clf = KMeans(n_clusters=3,random_state=0)
clf.fit(X)
label = clf.predict(X)

# 颜色和标签列表
colors_list = ['red', 'blue', 'green']
labels_list = ['1','2','3']
x=X
for i in range(3):
    plt.scatter(x[label==i,0], x[label== i,1], s=100,c=colors_list[i],label=labels_list[i])
    
# 聚类中心点
plt.scatter(clf.cluster_centers_[:,0],clf.cluster_centers_[:,1], s=300,c='black',label='Centroids')

plt.legend()
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.show()
 

效果如下:

K-means算法

6. 源码仓库地址

🌼 图像处理、机器学习的常用算法汇总文章来源地址https://www.toymoban.com/news/detail-493730.html

到了这里,关于K-means算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【机器学习】十大算法之一 “K-means”

      作者主页: 爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主 爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域. https://blog.csdn.net/Code_and516?type=blog 个人简介:打工人。 持续分

    2024年02月10日
    浏览(35)
  • K-means算法(知识点梳理)

    目录 一.K-means算法的原理和工作流程 1.算法原理 2.工作流程 二.K-means中常用的距离度量方法 1.欧几里得距离(欧氏距离) 2.曼哈顿距离 3.切比雪夫距离 三.K-means算法中K值的选择 1.手肘法 2. 轮廓系数         手肘法和轮廓系数的实现 四.初始点的选择 1.随机选择 2.最远距离 

    2024年02月16日
    浏览(35)
  • 无涯教程-聚类算法 - K-Means

    K-均值聚类算法计算质心并进行迭代,直到找到最佳质心为止,它假定群集的数目是已知的,它也称为扁平聚类算法。通过算法从数据中识别出的簇数以K均值中的\\\" K\\\"表示。 在该算法中,将数据点分配给群集,以使数据点和质心之间的平方距离之和最小。应当理解,簇内的较

    2024年02月10日
    浏览(33)
  • K-means++聚类算法(matlab实现)

    K-means++算法:K-means++算法是K-means算法的改进版,其在选择初始质心时采用了一种更加聪明的方法,能够有效地避免局部最优解。具体来说,K-means++算法的初始质心是根据距离数据点最远的原则来选择的,这样可以保证初始质心的分布更加广泛,从而使得算法更容易找到全局最

    2024年02月07日
    浏览(83)
  • 机器学习之K-means聚类算法

    目录 K-means聚类算法 算法流程 优点 缺点 随机点聚类 人脸聚类 旋转物体聚类 K-means聚类算法是一种无监督的学习方法,通过对样本数据进行分组来发现数据内在的结构。K-means的基本思想是将n个实例分成k个簇,使得同一簇内数据相似度高而不同簇之间数据相似度低。 K-means的

    2024年02月11日
    浏览(33)
  • K-means聚类算法原理及实现

    1.1概念 聚类分析,也称为分割分析或分类分析,可将样本数据分成一个个组(即簇)。同一簇中的对象是相似的,不同簇中的对象则明显不同。 Statistics and Machine Learning Toolbox™ 提供了几种聚类方法和相似性度量(也称为距离度量)来创建簇。此外,簇计算可以按照不同的计

    2024年03月18日
    浏览(33)
  • 机器学习——K-Means算法优化(一)代价函数

    在K-Means算法中,对K个质心的选择,容易陷入局部最小值,从而每次聚类得到不同的结果。 使用多次的随机初始化,并计算每一次建模得到的代价函数值,选取最小的代价函数值作为聚类结果,代价函数公式如下 J ( c ( 1 ) , … , c ( m ) , μ 1 , … , μ K ) = 1 m ∑ i = 1 m ∣ ∣ x (

    2024年02月02日
    浏览(48)
  • 机器学习之K-Means(k均值)算法

    K-Means算法又称K均值算法,属于聚类(clustering)算法的一种,是应用最广泛的聚类算法之一。所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。聚类与分类最大的区别在于,聚类过程为无监督过程,

    2024年02月03日
    浏览(34)
  • K-means聚类算法(附Python实现代码)

    本文的代码与数据地址已上传至github:https://github.com/helloWorldchn/MachineLearning 1、基于划分的聚类 划分算法的思想是,将给定待挖掘数据集中的数据对象划分成K组(k≤N,N代表数据集中对象数目),每一组表示一个聚类的簇。并且要满足任何一个数据对象仅可以属于一个聚类,

    2024年02月07日
    浏览(29)
  • K-means聚类算法及Python代码实现

    K-means聚类算法(事先数据并没有类别之分!所有的数据都是一样的) 1、概述 K-means算法是集简单和经典于一身的 基于距离的聚类算法 采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。 该算法认为类簇是由距离靠近的对象组成的,因此把得到

    2023年04月24日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包