聚类算法-----K-means、K-means++

1 篇文章 0 订阅
订阅专栏

1. K-means

K值的选取方法:

值得一提的是关于聚类中心数目(K值)的选取,的确存在一种可行的方法,叫做Elbow Method(肘部法则):

通过绘制K-means代价函数与聚类数目K的关系图,选取直线拐点处的K值作为最佳的聚类中心数目。

上述方法中的拐点在实际情况中是很少出现的。

比较提倡的做法还是从实际问题出发,人工指定比较合理的K值,通过多次随机初始化聚类中心选取比较满意的结果。

肘部法则如下图:类别个数K为X轴,损失函数值为Y轴:

损失函数的定义如下:

x为样本点,\mu是类的中心点。下面公式的意义就是:聚类结束后,统计每个样本点x和其对应的类别的中心点的距离,加起来后求平均就得到损失值。

我们可以看到,上图中明显出现了拐点,就是 K=3的情况,因此可以设定K=3。

但也有情况就是不出现明显拐点的:

这就要从实际出发,人工设定合理的K值。

代码:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

def assignment(df, center, colmap):
    #计算所有样本分别对K个类别中心点的距离
    for i in center.keys():
        df["distance_from_{}".format(i)] = np.sqrt((df["x"]-center[i][0])**2+(df["y"]-center[i][1])**2)

    distance_from_centroid_id = ['distance_from_{}'.format(i) for i in center.keys()]
    df["closest"] = df.loc[:, distance_from_centroid_id].idxmin(axis=1)#"closest"列表示每个样本点离哪个类别的中心点距离最近
    print(df["closest"])
    df["closest"] = df["closest"].map(lambda x: int(x.lstrip('distance_from_')))
    df["color"] = df['closest'].map(lambda x: colmap[x])
    return df

def update(df, centroids):
    #更新K个类别的中心点
    for i in centroids.keys():
        #每个类别的中心点为 属于该类别的点的x、y坐标的平均值
        centroids[i][0] = np.mean(df[df['closest'] == i]['x'])
        centroids[i][1] = np.mean(df[df['closest'] == i]['y'])
    return centroids


def main():
    df = pd.DataFrame({
        'x': [12, 20, 28, 18, 10, 29, 33, 24, 45, 45, 52, 51, 52, 55, 53, 55, 61, 64, 69, 72, 23],
        'y': [39, 36, 30, 52, 54, 20, 46, 55, 59, 63, 70, 66, 63, 58, 23, 14, 8, 19, 7, 24, 77]
    })
    k = 3

    #一开始随机指定 K个类的中心点
    center = {
        i:[np.random.randint(0,80), np.random.randint(0,80)]
        for i in range(k)
    }

    colmap = {0:"r", 1:"g", 2:"b"}
    df = assignment(df, center, colmap)

    for i in range(10): #迭代10次
        closest_center = df['closest'].copy(deep=True)
        center = update(df, center) #更新K个类的中心点
        df = assignment(df, center, colmap) #类别中心点更新后,重新计算所有样本点到K个类别中心点的距离
        if closest_center.equals(df['closest']): #若各个样本点对应的聚类类别不再变化,则结束聚类
            break

    plt.scatter(df['x'], df['y'], color=df['color'], alpha=0.5, edgecolor='b')
    for j in center.keys():
        plt.scatter(*center[j], color=colmap[j], linewidths=6)
    plt.xlim(0, 80)
    plt.ylim(0, 80)
    plt.show()


if __name__=='__main__':
    main()

效果:

K-means的缺陷:

1. 聚类种类数K需要提前指定

2.不同初始化的聚类中心可能导致完全不同的聚类结果(针对这点,提出了K-means++,K-means++定义初始聚类中心的规则是初始的聚类中心之间的相互距离要尽可能的远)

 

2. K-means++

K-means++和K-means的区别就是初始K个类别中心点确定方法不同,K-means是直接随机指定的。而K-means++只随机指定一个类的中心点,然后其余的都按照下面的规则指定。确定后初始的K个类别中心点后,K-means++的后续操作和K-means是一样的。

其实 K-means++和K-means就是选择一开始的k个聚类中心点的方法有差别而已。K-means生成初始聚类中心点的详细过程如下:

1. 定义一个center列表,用来装初始化的聚类中心点。第一个聚类中心点(设为A)也是随机生成的。此时center=[A]

2.然后把所有样本点x(设样本点个数为N)和center里面的中心点算一个距离,若center里有一个点,那么就有1*N个距离,center里有K个点,就有K*N个距离。然后每个样本点都选K个距离中最小的一个,简单地说,就是选最靠近自己的一个。因此N个样本点就会有N个距离,用D(x)表示。

3.我们得到N个样本点对应它最近的聚类中心点的距离D(x)后,就要计算每个样本点可能成为下一个聚类中心点的几率了哦。概率公式在 step2有给出,就是:

这个公式给出的意义就是,离聚类中心点越远的点,越有可能成为下一个聚类中心点。通过这个公式,就可以算出每个样本点x成为下一个聚类中心点的概率P(x)。

4. 有同学可能会说,那么既然概率P都出来了,那么直接拿P最大的点作为聚类中心点不就可以啦?为了撇除噪音的影响,我们不能简单地取最大,而要取较大(当然也是有可能取最大的),所以我们用轮盘法来决定下一个聚类中心点,过程如下:

例如我们现在有三个样本点:x1、x2、x3,他们能作为聚类中心点的概率分别如下:

可以看到:x1的区间是0~0.4,x2的区间是0.4~0.9,x3的区间是0.9~1

接下来,我们随机生成一个0~1的数,看看选中的是哪个区间,然后对应区间的点,就是新的聚类中心。

 什么用这样的方式呢?我们换一种比较好理解的方式来说明。把D(x)想象为一根线L(x),线的长度就是元素的值。将这些线依次按照L(1),L(2),⋯,L(n)的顺序连接起来,组成长线L。L(1),L(2),⋯,L(n)称为L的子线。 根据概率的相关知识,如果我们在L上随机选择一个点,那么这个点所在的子线很有可能是比较长的子线,而这个子线对应的数据点就可以作为初始聚类中心。
 

代码:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import random
def select_center(first_center, df, k,colmap):
    center = {}
    center[0]=first_center

    for i in range(1, k):
        df = assignment(df,center,colmap)
        sum_closest_d = df.loc[:,'cd'].sum()   #cd = 最近中心点的距离。把所有样本点对应最近中心点的距离都加在一起
        df["p"] = df.loc[:,'cd']/sum_closest_d
        sum_p = df["p"].cumsum()

        #下面是轮盘法取新的聚类中心点
        next_center = random.random()
        for index, j in enumerate(sum_p):
            if j > next_center:
                break
        center[i] = list(df.iloc[index].values)[0:2]

    return center

def assignment(df, center, colmap):
    #计算所有样本分别对K个类别中心点的距离
    for i in center.keys():
        df["distance_from_{}".format(i)] = np.sqrt((df["x"]-center[i][0])**2+(df["y"]-center[i][1])**2)

    distance_from_centroid_id = ['distance_from_{}'.format(i) for i in center.keys()]
    df["closest"] = df.loc[:, distance_from_centroid_id].idxmin(axis=1)#"closest"列表示每个样本点离哪个类别的中心点距离最近
    df["cd"] = df.loc[:,distance_from_centroid_id].min(axis=1)
    df["closest"] = df["closest"].map(lambda x: int(x.lstrip('distance_from_')))
    df["color"] = df['closest'].map(lambda x: colmap[x])
    return df

def update(df, centroids):
    #更新K个类别的中心点
    for i in centroids.keys():
        #每个类别的中心点为 属于该类别的点的x、y坐标的平均值
        centroids[i][0] = np.mean(df[df['closest'] == i]['x'])
        centroids[i][1] = np.mean(df[df['closest'] == i]['y'])
    return centroids


def main():
    df = pd.DataFrame({
        'x': [12, 20, 28, 18, 10, 29, 33, 24, 45, 45, 52, 51, 52, 55, 53, 55, 61, 64, 69, 72, 23],
        'y': [39, 36, 30, 52, 54, 20, 46, 55, 59, 63, 70, 66, 63, 58, 23, 14, 8, 19, 7, 24, 77]
    })
    k = 3
    colomap = {0: "r", 1: "g", 2: "b"}
    first_center_index = random.randint(0,len(df)-1)
    first_center = [df['x'][first_center_index], df['y'][first_center_index]]
    center = select_center(first_center, df, k,colomap)

    df = assignment(df, center, colomap)

    for i in range(10): #迭代10次
        closest_center = df['closest'].copy(deep=True)
        center = update(df, center) #更新K个类的中心点
        df = assignment(df, center, colomap) #类别中心点更新后,重新计算所有样本点到K个类别中心点的距离
        if closest_center.equals(df['closest']): #若各个样本点对应的聚类类别不再变化,则结束聚类
            break

    plt.scatter(df['x'], df['y'], color=df['color'], alpha=0.5, edgecolor='b')
    for j in center.keys():
        plt.scatter(*center[j], color=colomap[j], linewidths=6)
    plt.xlim(0, 80)
    plt.ylim(0, 80)
    plt.show()


if __name__=='__main__':
    main()

效果:

KmeansKmeans++和KNN算法比较
chlele0105的专栏
10-24 3万+
K-Means介绍        K-means算法是聚类分析中使用最广泛的算法之一。它把n个对象根据他们的属性分为k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。其聚类过程可以用下图表示:         如图所示,数据样本用圆点表示,每个簇的中心点用叉叉表示。(a)刚开始时是原始数据,杂乱无章,没有label,看起来都一样,都是绿色的
K-MeansK-Means++
qq_20962187的博客
08-01 3854
K-Means介绍 K-means算法是聚类分析中使用最广泛的算法之一。它把n个对象根据他们的属性分为k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。其聚类过程可以用下图表示: 如图所示,数据样本用圆点表示,每个簇的中心点用叉叉表示。(a)刚开始时是原始数据,杂乱无章,没有label,看起来都一样,都是绿色的。(b)假设数据集可以分...
k-means聚类算法&k-means++聚类算法
最新发布
m0_47498690的博客
08-14 943
是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得。也就是说,聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。
K-meansK-means++
qq_31510519的博客
03-11 2061
一、概述 在本篇文章中将对聚类算法(K-means,K-means++)进行详细介绍,并利用数据集来真实地反映这算法之间的区别。 首先需要明确的是上述算法都属于"硬聚类”算法,即数据集中每一个样本都是被100%确定得分到某一个类别中。与之相对的"软聚类”可以理解为每个样本是以一定的概率被分到某一个类别中。 K-meansK-means++:原始K-means算法最开...
机器学习—k-meansk-means++以及k-means||算法分析
柳成荫
08-20 3329
一、k-means 1、简述 K-Means是一种无监督学习算法。算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。 2、K-means算法基本思路是: 首先选择好将数据分成k类,然后随机初始化k个点作为中心点。 对于每一个数据点,选取与之距离最近的中心点作为自己的类别。 当所有数据点都归类完毕后,调...
K-means算法与K-means++算法的异同
kuwola的博客
05-03 6757
KmeansKmeans++
kmeanskmeans++
yy2050645的博客
02-18 8258
kmeanskmeans为一种简单的聚类算法,是一种无监督学习算法,主要作用是将众多无标签样本聚为指定的几个类。接下来简单介绍一下kmeans。首先,我们假设聚类中心为,每个聚类中心有一个簇,每个簇的样本个数依次为。则我们认为k-means的损失函数为,则,令可以得到。因此,最优的聚类中心应当在每个簇的均值点处。从另一个角度来看,我们假设每个簇均服从正太分布,且方差都相等,但均值不等,其均值...
聚类算法K-means聚类图像分割
12-22
K-Means聚类是最常用的聚类算法,最初起源于信号处理,其目标是将数据点划分为K个类簇,找到每个簇的中心并使其度量最小化。该算法的最大优点是简单、便于理解,运算速度较快,缺点是只能应用于连续型数据,并且要在...
k-means++:使用 k-means++ 算法对多元数据进行聚类。-matlab开发
06-01
k-means++ 是一种优化的 k-means 聚类算法,主要用于处理多元数据集。在传统的 k-means 算法中,初始质心的选择往往是随机的,这可能导致算法收敛到局部最优解而非全局最优解。k-means++ 算法通过精心设计的初始化...
详解Java实现的k-means聚类算法
08-28
Java实现的k-means聚类算法详解 k-means聚类算法是一种常用的无监督学习算法,用于对数据进行聚类分析。该算法的主要思想是将相似的数据点聚类到一起,形成不同的簇。Java语言是实现k-means聚类算法的不二之选。 ...
k-means聚类算法k-means聚类算法k-means聚类算法k-means聚类算法.txt
05-30
k-means聚类算法k-means聚类算法k-means聚类算法k-means聚类算法
java实现k-means算法
01-13
java语言实现对mysql数据库表中某个字段实现k-means算法,并将处理后的数据写入新表
k-means聚类算法-mai笔记
05-31
- **K-means++**:改进了初始质心的选择策略,降低了对初始值的敏感性。 - **DBSCAN**:基于密度的聚类算法,能发现任意形状的簇,且不需要预先指定k值。 - **谱聚类**:利用数据的相似度矩阵进行聚类,适用于...
K-Means ++ 算法
weixin_30784141的博客
06-25 141
Kmeans算法的缺陷 • 聚类中心的个数K 需要事先给定,但在实际中这个 K 值的选定是非常难以估计的,很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适• Kmeans需要人为地确定初始聚类中心,不同的初始聚类中心可能导致完全不同的聚类结果。(可以使用Kmeans++算法来解决) K-Means ++ 算法 k-means++算法选择初始seeds的基本思想就是:初...
聚类算法kmeanskmeans++讲解
rosefun96的博客
12-03 1万+
1、kmeanskmeans,就是在一堆数据中,随机找几个种子,计算其他点到那个种子的距离近; 然后,更新种子(把前一步划分好的类的中心点作为新的种子); 迭代到种子的不改变为止。2、kmeans++因为,kmeans的初始种子的随机找的,这样,算法的收敛快慢与初始值关系非常大,于是,kmeans++ 主要针对初始值的选取进行改进。 初始值选取,如下:1、也是随机选取一个种子; 2、计算其他点到这
聚类算法之——K-Means++聚类算法
Amy9_Miss的博客
03-10 5984
聚类算法之——K-Means++聚类算法 轮盘法 基本思想:各个个体被选中的概率与其适应度大小成正比; 步骤 计算出群体中 每个个体的适应度f(i=1,2,…,m),mf(i=1,2,\dots,m),mf(i=1,2,…,m),m为群体大小; 计算出每个个体被遗传到下一代群体中的概率 P(xi)=f(xi)∑j=1Mf(xj) P(x_i)=\frac{f(x_i)}{\sum_{j=1...
K-Means算法的代码实现(Java)
daguocai的专栏
04-05 2174
K-Means算法的代码实现(Java)   2013-03-02 20:28:41|  分类: 数据挖掘 |  标签: |举报 |字号大中小 订阅 //package cn.edu.pku.ss.dm.cluster; import java.io.BufferedReader; import java.io.BufferedWriter; import jav
聚类算法K-Means++介绍与实例
qq_45402214的博客
07-16 2483
K-Means++算法介绍 K-Means++主要解决初始化种子点的问题,其选择初始种子的基本思想是:初始聚类中心之间相互距离要在K-Means算法基础上引入了更智能的初始化步骤,该步骤倾向于选择彼此相距较远的中心点,这一改进使得K-means算法收敛到次优解的可能性很小。K-Means++算法表明,更智能的初始化步骤所需计算量是值得的,因为他可以大大减少寻找最优解所需运行算法的次数。 K-Means算法实现步骤 1.取一个中心点C1,从数据集中随机选择一个中心点。 2.取一个新中心点Ci,选择一个概率为
Python实现K-Means++聚类算法
热门推荐
象在舞的技术专栏
03-10 1万+
声明:代码的运行环境为Python3。Python3与Python2在一些细节上会有所不同,希望广大读者注意。本博客以代码为主,代码中会有详细的注释。相关文章将会发布在我的个人博客专栏《Python从入门到深度学习》,欢迎大家关注~ 之前我写过一篇文章叫《Python实现K-Means聚类算法》,这篇文章主要是在之前的基础上介绍K-Means算法的改进版——K-Mea...
分层聚类k-means:优势与挑战
"基于分层聚类的k-means算法是一种用于数据聚类的有效方法,其核心思想是通过迭代过程将数据集划分为多个簇,每个簇内的数据点与其对应的质心(中心点)的距离最小。该算法的特点如下: 1. **层次性**:与普通的k-...
写文章

热门文章

  • 利用KEIL生成hex文件 135146
  • Java遍历目录下的所有文件 116014
  • pandas之 read_table函数读取txt文件 86964
  • (C51学习五)单片机与PC通过串口通信 85088
  • MYSQL的创建用户,授权用户,删除用户,查看用户 78226

分类专栏

  • 安卓开发 9篇
  • Java 高并发 14篇
  • Nginx
  • redis 3篇
  • MQ 1篇
  • 开发策略 1篇
  • 图像处理 8篇
  • 机器学习 14篇
  • 损失函数 1篇
  • 聚类 1篇
  • DeepLearning 2篇
  • 指标 2篇
  • mmdetection 3篇
  • yolo
  • 语义分割 9篇
  • pytorch源码解读 3篇
  • keras 1篇
  • pytorch框架 10篇
  • Tensorflow 7篇
  • 行人重识别 1篇
  • 神经网络 20篇
  • ssd源码解读 5篇
  • ocr 1篇
  • Linux
  • inux命令 3篇
  • linux配置文件 1篇
  • 算法 11篇
  • 设计模式 4篇
  • leetcode算法题 15篇
  • 数据结构 14篇
  • python3 32篇
  • Numpy包 2篇
  • mongodb 2篇
  • 爬虫 2篇
  • PyQt 1篇
  • C++ 13篇
  • STL 3篇
  • qt 11篇
  • C++练手小项目 1篇
  • 嵌入式
  • C51单片机 7篇
  • ARM开发 4篇
  • 工具 5篇
  • pycharm 1篇
  • C语言 5篇
  • Linux C网络编程 9篇
  • linux C 6篇
  • java 39篇
  • JAVA网络编程 1篇
  • JVM 5篇
  • java小程序 4篇
  • Spring Boot 6篇
  • JDBC 6篇
  • JAVA与C++点点滴滴的不同 3篇
  • SpringMVC 6篇
  • servlet 5篇
  • Spring 7篇
  • JSP 12篇
  • mybatis3 3篇
  • hadoop 2篇
  • Java GUI 4篇
  • 数学
  • 概率统计 1篇
  • 线性代数 3篇
  • 前端
  • node.js 2篇
  • html/css 1篇
  • JavaScript 3篇
  • 学术
  • 论文翻译 1篇
  • 试验 1篇
  • 论文代码评测 1篇
  • 计算机基础 1篇
  • 计算机协议 6篇
  • 操作系统 6篇
  • 密码学 1篇
  • opencv 2篇
  • Mysql 25篇
  • 语义/实例/全景分割 7篇

最新评论

  • 矩阵基础知识------秩+线性相关和线性无关

    Endlesslov_: 我也感觉给错了,第二个里的x4应该消掉了

  • [pytorch]医学图像语义分割UNET和UNET变体代码(包含多个数据集)

    YPB儿: 您好,请问您有解决方法吗

  • python3+opencv 利用灰度直方图来判断图片的亮暗情况

    qq_42011523: 我运行这个代码,怎么总是出错呀

  • Redis 的五种数据类型及其底层原理

    你我皆凡人: 写的很容易看懂,真好

  • Batch Normalization (BN层)-----批归一化

    今天不努力: 请问一下,测试的时候怎么去进行归一化层的操作呢,输出最后训练的参数的结果作为均值和方差吗

最新文章

  • 安卓学习笔记之--------ViewPager控件
  • 安卓开发之-------RecyclerView
  • 安卓学习笔记------ListView与适配器
2021年40篇
2020年76篇
2019年44篇
2018年82篇
2017年124篇
2016年16篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家朔州玻璃钢卡通雕塑价格范围商场美陈有什么好处甘肃园林玻璃钢雕塑安装上海特色商场美陈销售公司北京定制玻璃钢雕塑方法玻璃钢雕塑多少钱设计精美玻璃钢雕塑行业施工标准江苏玻璃钢海豚雕塑日照玻璃钢雕塑河南石雕雕塑玻璃钢武汉玻璃钢鹿雕塑厂家巴彦淖尔玻璃钢广场雕塑黑龙江玻璃钢雕塑供应商连云港玻璃钢雕塑厂家电话苏州商场新年美陈余姚玻璃钢雕塑深圳玻璃钢造型雕塑天筑玻璃钢雕塑价格表现代玻璃钢雕塑有哪些玻璃钢网红雕塑商丘房地产玻璃钢彩绘雕塑九江市玻璃钢雕塑石景山玻璃钢卡通雕塑玻璃钢雕塑展览怎么样运城广场不锈钢玻璃钢卡通雕塑艺术商场美陈制造玻璃钢斑马雕塑效果图湖州人物玻璃钢雕塑定制商场美陈更新推文宣传哈密玻璃钢雕塑厂家香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化