机器学习-聚类kmeans(代码片段)

尤尔小屋的猫 尤尔小屋的猫     2023-01-15     377

关键词:

图解K-Means算法

本文中介绍的是一种常见的无监督学习算法,名字叫做K均值算法:K-Means算法

K-Means算法在无监督学习,尤其是聚类算法中是最为基础和重要的一个算法。它实现起来非常简单。聚类效果也很不错的,因此应用非常广泛。

本文将会从以下8个方面进行详细的讲解:

算法思想

无监督学习

在正式介绍K-Means算法之前,我们先解释一下无监督学习。用一句很通俗的话来解释:

是否有监督(supervised),我们只需要看输入的数据是否有标签

输入的数据如果带有标签,则是有监督学习,比如KNN算法(K近邻)就是监督学习的典型算法;如果没有标签,则认为是无监督学习,比如本文中即将介绍的K-Means算法

我们看看无监督学习聚类算法的应用:

  • 市场分割
  • 社交网络分析
  • 组织计算机集群
  • 星系的形成

算法思想

K-Means聚类算法是一种迭代求解的聚类分析算法。算法思想是:我们需要随机选择K个对象作为初始的聚类中心,然后计算每个对象和各个聚类中心之间的距离,然后将每个对象分配给距离它最近的聚类中心。

聚类中心及分配给它们的对象就代表着一个聚类。每分配一个样本,聚类的中心会根据聚类中现有的对象被重新计算。此过程将不断重复,直至满足设置的终止条件。

算法步骤

K-Means算法的具体步骤如下:

  1. 首先我们需要确定一个k值(随机),即我们希望数据经过聚类得到k个不同的集合
  2. 从给定的数据集中随机选择K个数据点作为质心
  3. 对数据集中的每个点计算其与每一个质心的距离(比如欧式距离);数据点离哪个质心近,就划分到那个质心所属的集合
  4. 第一轮将所有的数据归号集合后,一共有K个集合,然后重新计算每个集合的质心
  5. 如果新计算出来的质心和原来的质心之间的距离小于某一个设置的阈值,则表示重新计算的质心的位置变化不大,数据整体趋于稳定,或者说数据已经收敛。在这样的情况下,我们认为聚类效果已经达到了期望的结果,算法可终止。
  6. 反之,如果新质心和原来质心的距离变化很大,需要重复迭代3-5步骤,直至位置变化不大,达到收敛状态。

图解K-Means

具体步骤

1、给定需要进行聚类划分的数据集

2、随机选择2个聚类中心(K=2)

3、计算每个数据点到质心的距离,并将数据点划分到离它最近的质心的类中

4、计算2个数据集的各自的质心(红点、蓝点的均值),将聚类中心移动到均值处,变成新的聚类中心

5、找到新的聚类中心。如果

完整过程

  1. 在上面的过程中我们假设k=2。在图b中我们随机选择了两个类所对应的质心,也就是图中蓝色和红色质心
  2. 分别求出样本中每个点到这两个质心的距离,并且将每个样本所属的类别归到和该样本距离最小的质心的类别,得到图c,也就是第一轮迭代后的结果
  3. 我们对c图中的当前标记为红色和蓝色的点分别求出其新的质心,得到了图d,此时质心的位置发生了改变
  4. 图e和图f重复了图c和图d的过程,即将所有点的类别标记为距离最近的质心的类别并求新的质心。
  5. 一般的,K-Means算法需要运行多次才能达到图f的效果。

注:以上图形来自吴恩达老师在机器学习视频的讲解截图

k值选择

k值决定了我们将数据划分成多少个簇类。k个初始化的质心的位置选择对最后的聚类结果和整个大代码的运行时间都有非常大的影响。因此需要选择合适的k个质心

一般k值是通过先验知识来选取的。如果没有什么先验知识,我们可以通过交叉验证的方式来选择一个合适的k值。

距离问题

在机器学习中,我们常用的距离有以下几种:

1、两个集合之间的 x i , x j x_i,x_j xi,xj L p L_p Lp距离定义为:

2、当p=1则表示为曼哈顿距离:

3、当p=2则表示为我们常用的欧式距离

4、当p趋于无穷时,表示为切比雪夫距离,它是各个坐标距离的最大值:

K-Means算法中一般采用的是欧式距离

算法优缺点

优点

  1. 原理很简单,实现起来也是非常容易,算法收敛速度也很快
  2. 聚类效果优,可解释性强。当数据最终收敛之后,我们最终能够很清晰的看到聚类的效果
  3. 约束条件少。算法中需要控制的参数只有簇数k。通过对k的不断调节才能得到最好的聚类效果

缺点

  1. k值的选取不好把握,很多情况下K值的估计是非常困难的,有时候通过交叉验证来获取。
  2. 迭代的方法得到的结果只能是局部最优解,而不能得到全局最优解。
  3. 对噪音和异常点很敏感。异常点对质心的确定影响很大的。可以用来检测异常值。

Python实现K-Means

下面讲解一种利用Python实现k-means算法的代码:

import numpy as np
import pandas as pd
import random  # 随机模块
import re
import matplotlib.pyplot as plt


# 导入数据
def loadDataSet():
  dataset = np.loadtext("user/skl/cluster/dataset.csv")  # 个人文件路径
  return dataset   # 返回数据集

# 绘图函数
def show_fig():
  dataset = loadDataSet()   # 导入数据
  fig = plt.figure()  # 确定画布
  ax = fig.add_subplot(111)   # 一个子图
  ax.scatter(dataset[:,0], dataset[:,1])  # 传入绘图数据
  plt.show()
  
# 定义欧式距离公式
# 两个向量间的欧式距离公式:[(x_1 - x_2)^2 + (y_1 - y_2)^2 + (x_n - y_n)^2]
def calcudistance(vec1,vec2):  # 传入两个向量
  return np.sqrt(np.sum(np.square(vec1 - vec2)))  # 向量相减在平方,最后再求和
  
# 初始化质心
def initCentroids(dataset, k):
  # 初始化执行;dataset是传入的数据
  # k:选择分类簇的个数
  dataset = list(dataset)  # 数据列表化
  return random.sample(dataset,k)   # 随机选取k的模块

# 计算每个数据点和质心的距离,并归属到距离最小的类别中
def minDisctance(dataset, centroidList):  # 传入数据集和选取的质心列表
  clusterDict = dict()  # 保存簇类结果
  k = len(centroidList)  # 质心列表的长度:总共多少个质心表示分成多少类
  for item in dataset:  # 原始数据中的每个元素
    vec1 = item  # 数据中的向量
    flag = -1  # 标志位
    minDis = float("inf")   # 初始化为无穷大值
    for i in range(k):
      vec2 = centroidList[i]   # 取出第i个质心
      distcance = calcudistance(vec1, vec2)   # 计算欧式距离
      if distance < minDis:   
        minDis = distance  # 如果算出来的实际距离小于最小值的初始值,则将真实值distance赋值给最小值(更新最小值)
        flag = i  # 循环结束时,flag保存与当前item最近的簇标记
    if flag not in clusterDict.keys():
      clusterDict.setdefault(flag,[])
    clusterDict[flag].append(item)  # 加入到相应的簇类中
  return clusterDict  # 不同的类别

# 重新计算质心
def getcentroids(clusterDict):
  # 重新计算k个质心
  centroidList = []   # 质心空列表
  for key in clusterDict.keys():  # 
    centroid = np.mean(clusterDict[key], axis=0)  # 现有数据点的平均值
    centroidList.append(centroid)
  return centroidList  # 得到新的质心
    
# 计算均方误差
def getVar(centroidList, clusterDict):
  # 将簇类中各个向量和质心的距离累加求和
  sum = 0.0  # 初始值
  for key in clusterDict.keys():   # 簇类中的键
    vec1 = centroidList[key]   # 取出某个质心
    distance = 0.0  # 距离初始化值
    for item in clusterDict[key]:  # 簇类的键
      vec2 = item
      distance += calcudistance(vec1, vec2)  # 求距离
    sum += distance  # 累加
  return sum

# 显示簇类
def showCluster(centroidList, clusterDict):
  # 显示簇类结果
  color_mark = ["or","ob","og","ok","oy","ow"]
  centroid_mark = ["dr","db","dg","dk","dy","dw"]
  
  for key in clusterDict.keys():
    plt.plot(centroidList[key][0], centroidList[key][1], centroidMark[key],markersize=12)  # 质心点
    for item in clusterDict[key]:
      plt.plot(item[0],item[1],colorMark[key])
  plt.show()
  
# 主函数
def main():
  dataset = loadDataSet()  # 导入数据
  centroidList = initCentroids(dataset,4)   # 质心列表
  clusterDict = minDistance(dataset, centroidList)   # 簇类的字典数据
  newVar = getVar(centroidList, clusterDict)   # 质心和簇类中数据得到新的误差
  oldVar = 1  # 当两次聚类的误差小于某个值时,说明质心基本稳定
  
  times = 2
  while abs(newVar - oldVar) >= 0.00001:   # 当新旧误差的绝对值小于某个很小的值
    centroidList = getCentroids(clusterDict)   # 得到质心列表
    oldVar = newVar  # 将新的误差赋值给旧误差
    newVar = getVar(centroidList, clusterDict)   # 新误差
    times += 1
    showCluster(centroidList, clusterDict)  # 显示聚类结果
    
    
if __name__ == "__main__":
  show_fig()
  main()

延伸学习

传统的K-Means算法存在一些缺陷,比如K值的选取不是很好把握、对异常数据敏感等,于是提出了很多在其基础上改进的聚类算法:

1、K-Means++(初始化优化)

针对K-Means算法中随机初始化质心的方法进行了优化

2、elkan K-Means(距离优化)

在传统的K-Means算法中,在每轮迭代中我们都需要计算所有的样本点到质心的距离,这样是非常耗时的。

elkan K-Means算法利用:两边之和大于等于第三边,以及两边之差小于第三边的三角形性质,来减少距离的计算。

3、Mini Batch K-Means算法(大样本优化)

在传统的K-Means算法中,要计算所有的样本点到所有的质心的距离。现在大数据时代,如果样本量非常大,传统的算法将会非常耗时。

Mini Batch K-Means就是从原始的样本集中随机选择一部分样本做传统的K-Means。这样可以避免样本量太大的计算难题,同时也加速算法的收敛。当然,此时的代价就是我们最终聚类的精度会降低一些。

为了增加算法的准确性,我们一般会多跑几次Mini Batch K-Means算法,用得到不同的随机样本集来得到聚类簇,选择其中最优的聚类簇。

参考资料

1、李航老师—《统计学习方法》一书

2、吴恩达老师—《机器学习》视频

3、刘建平老师—博客:https://www.cnblogs.com/pinard/

机器学习笔记之kmeans算法(代码片段)

Kmeans算法:优点:容易实现缺点:可能收敛到局部最小值,在大规模数据集上的收敛速度较慢。适用数据类型:数值型数据算法原理:k-means算法接受参数k;然后将事先输入的n个数据对象划分为k个聚类... 查看详情

机器学习-kmeans算法(图解算法原理)(代码片段)

文章目录简介算法原理sklearn库调用K的取值前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。简介k均值聚类算法(k-meansclusteringalgorithm)是一种迭代... 查看详情

转:机器学习sklearn19.0聚类算法——kmeans算法

https://blog.csdn.net/loveliuzz/article/details/78783773机器学习sklearn19.0聚类算法——Kmeans算法  查看详情

机器学习sklearn19.0聚类算法——kmeans算法

一、关于聚类及相似度、距离的知识点 二、k-means算法思想与流程三、sklearn中对于kmeans算法的参数四、代码示例以及应用的知识点简介(1)make_blobs:聚类数据生成器 sklearn.datasets.make_blobs(n_samples=100,n_features=2,centers=3,cluste... 查看详情

机器学习笔记之kmeans算法(代码片段)

Kmeans算法:优点:容易实现缺点:可能收敛到局部最小值,在大规模数据集上的收敛速度较慢。适用数据类型:数值型数据算法原理:k-means算法接受参数k;然后将事先输入的n个数据对象划分为k个聚类... 查看详情

聚类kmeans|机器学习(代码片段)

聚类刘建平1、算法原理:是一种无监督学习算法,其主要目的是将数据点分为k个簇,距离近的样本具有更高的相似度,距离近的划分为一个簇,一共划分k个簇,**让簇内距离小,簇间距离大。**距离是... 查看详情

机器学习入门-文本数据-使用聚类增加文本的标签属性(代码片段)

通过对特征做一个kmeans聚类,将聚类的结果做为文本的标签值,可以使得样本的特征更多我们从sklearn.cluster中导入Kmeans建立模型进行聚类代码:   第一步:使用Dataframe格式化数据和使用数据格式化数据   第... 查看详情

机器学习-kmeans算法

学习彭亮《深度学习基础介绍:机器学习》课程归类聚类(clustering)属于非监督学习(unsupervisedlearning),无类别标记(classlabel)K-means算法Clustering中的经典算法,数据挖掘十大经典算法之一算法接受参数k;然后将事先输... 查看详情

机器学习--kmeans聚类算法

1.1概述K-means算法是集简单和经典于一身的基于距离的聚类算法采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为类簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终... 查看详情

机器学习4kmeans实际运用(代码片段)

(1)图片压缩以下为使用k-means代码进行图片压缩fromsklearn.datasetsimportload_sample_imagefromsklearn.clusterimportKMeansimportmatplotlib.pyplotaspltimportsysimportnumpyasnpfrompylabimportmpl#指定默认字体mpl.rcParams[‘font.sans-serif‘]=[‘FangSong‘]#解决保存图像... 查看详情

无监督学习——kmeans使用(代码片段)

在当我们获得的数据没有标签时,我们依然希望通过算法学习找到这些数据的特点,这时就用到了KMeans(k均值聚类)把数据点聚类成K个簇文档地址:http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html class sklearn.cl... 查看详情

机器学习sklearn----初识kmeans(代码片段)

文章目录概述KMeans中几个概念KMeans工作过程KMeans使用示例导入相关模块生成原始数据通过KMeans分类KMeans常用属性分类结果展示KMeans中的predict方法总结概述KMeans是一种无监督学习的方法。他是一种分类算法。用于探索原始数据ÿ... 查看详情

kmeans算法分析以及实现(代码片段)

KMeansKMeans是一种无监督学习聚类方法,目的是发现数据中数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好。无监督学习,也就是没有对应的标签,只有数据记录.通过KMeans聚类,可以将数... 查看详情

机器学习sklearn----kmeans评估指标(代码片段)

引言前面介绍了KMeans的基础知识。了解了KMeans的基础用法。但是具体需要怎么来评估我们的模型还是一个未知数。今天这节我们会介绍再不考虑实际需求的情况下来评估我们的KMeans模型。实际的应用中是按照我们的需求来评估模... 查看详情

机器学习sklearn----kmeans评估指标(代码片段)

引言前面介绍了KMeans的基础知识。了解了KMeans的基础用法。但是具体需要怎么来评估我们的模型还是一个未知数。今天这节我们会介绍再不考虑实际需求的情况下来评估我们的KMeans模型。实际的应用中是按照我们的需求来评估模... 查看详情

机器学习-kmeans聚类k值以及初始类簇中心点的选取

【转】http://www.cnblogs.com/kemaswill/archive/2013/01/26/2877434.html本文主要基于AnandRajaraman和JeffreyDavidUllman合著,王斌翻译的《大数据-互联网大规模数据挖掘与分布式处理》一书。 KMeans算法是最常用的聚类算法,主要思想是:在给定K值... 查看详情

机器学习sklearn----kmeans实例(图片数据矢量量化的应用)(代码片段)

文章目录矢量量化理解KMeans聚类法导入数据采用KMeans矢量化随机质心法矢量量化理解矢量量化可以理解为数据的压缩,可以看作是一种降维的过程,只是和我们之前知道的降维算法的理论完全不一样。举例来说,我们... 查看详情

机器学习sklearn----kmeans实例(图片数据矢量量化的应用)(代码片段)

文章目录矢量量化理解KMeans聚类法导入数据采用KMeans矢量化随机质心法矢量量化理解矢量量化可以理解为数据的压缩,可以看作是一种降维的过程,只是和我们之前知道的降维算法的理论完全不一样。举例来说,我们... 查看详情