k-means聚类算法总结

2023-11-12

聚类概念

聚类分析是在对象数据中发现对象之间关系。一般来说,组内相似性越高,组间相似性越大,则聚类的效果越好。

k-means概念

k-means是一种无监督学习,它会将相似的对象归到同一类中。

k-means聚类的优缺点

优点:容易实现。

缺点:可能会收敛到局部最小值, 当应用到大规模数据集时会收敛较慢。

适用于:数值型数据。

k-means聚类的算法思想

1.随机计算k个类中心作为起始点。

2. 将数据点分配到理其最近的类中心。

3.移动类中心。

4.重复2,3直至类中心不再改变或者达到限定迭代次数。

具体的伪代码实现:

创建k个点作为起始质心(多是随机选择)
repeat
    对数据集中的每个数据点
        repeat
            对每个质心
                计算质心与数据点之间的距离
        将数据点分配到距离其最近的类(或簇)
    对每一个类(簇),计算类(簇)中所有点的均值并将其作为质心。

k-means算法实现 参照《机器学习实战》

from numpy import *

# k-均值支持函数

def loadDataSet(fileName):
    # 用于读取文本数据
	dataMat = []
	fr = open(fileName)
	for line in fr.readlines():
		curLine = line.strip().split('\t')   # 清除文本格式 转换成数组
		fltLine = map(float, curLine)   # map知识
        # map(function, data) 将函数function作用于数据data (类似用法:reduce) 
		dataMat.append(fltLine)     # 收集数据
	return dataMat

def  distEclud(vecA, vecB):
    # 用于计算两个向量之间的欧氏距离 
	return sqrt(sum(power(vecA - vecB, 2 )))

def randCent(dataSet, k):
    # 构建类(簇)质心 
    # n 获取dataSet的列数 也可以写作 dataSet.shape[1]
	n = shape(dataSet)[1]
    # 然后构建一个(k,n)初始0矩阵 用于后续保存质心
	centroids = mat(zeros((k, n)))
    # 开始初始类质心 需要注意的是 要保证初始质心是在所允许的范围内 
	for j in range(n):
		minJ = min(dataSet[:,j])   # 找到数据集所有列的最小值
		rangeJ = float(max(dataSet[:,j]) - minJ)  # 列最大值-列最小值 得出取值范围
        # 需要注意的是 这是从第一列开始 对每列进行确定取值范围 然后进行在该取值范围内随机取值
		centroids[:, j] = minJ + rangeJ * random.rand(k, 1)  
        # 以最小值为下限 随机在(0,1)内进行取值 通过取值范围rangeJ和最小值minJ进行
        # 随机点都落在 数据边界之内
	return centroids

需要注意的是:

             在随机构建类质心时确保所有数据点都落在范围边界内。

关于欧式距离:

             D_center = \sqrt{(x_1-x_2)^2+(y_1-y_2)^2}   

此处求各数据点到类质心的距离使用欧式距离公式完成距离计算。其他距离计算公式暂不讨论。

k-means聚类算法

# 随机构建完成类中心后 开始应用下面k-means算法 
# dataSet:数据集   k:k个类中心 distMeas:欧氏距离公式求距离 createCent:随机初始化类中心


def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
    # m: 获取 数据集行数 用于 后边初始化全0矩阵 clusterAssment 
    m = shape(dataSet)[0]
    # clusterAssment:用于保存结果矩阵
    # 其中第一列保存 索引值  第二列保存 误差
    clusterAssment = mat(zeros((m,2)))#create mat to assign data points 
                                      #to a centroid, also holds SE of each point
    # 初始创建类中心
    centroids = createCent(dataSet, k)
    # 默认类中心不再改变 退出算法
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False
        for i in range(m):#for each data point assign it to the closest centroid
        # 开始 循环 为每一个数据点 分配到距离其最近的类中心
            minDist = inf; minIndex = -1     # 初始化最小距离为inf(无穷大) 索引为负
            # 开始针对当前数据点 计算其到每个类质心最短的距离 保存最小的距离
            for j in range(k):
                # 注意以行为开头 即 行向量 即对每个数据点计算其到每个类中心点的欧氏距离 
                distJI = distMeas(centroids[j,:],dataSet[i,:])
                # 每次进行判断是否比上次距离更小 进行存储更小的距离
                # 直至比较到最后取到最小距离 【不保存所有距离,只保存最小距离】
                if distJI < minDist:
                    minDist = distJI; minIndex = j
            # 如果索引即 该数据点的归属类(簇)发生了改变 就继续进行循环
            if clusterAssment[i,0] != minIndex: clusterChanged = True
            # 此时再进行更新该数据点的(索引)归属类,和距离该归属类质(或中)心最小距离。
            clusterAssment[i,:] = minIndex,minDist**2
        print centroids
        # 最后重新移动类质心 (如果需要)
        for cent in range(k):  # recalculate centroids
            # 下面用于找到 当前类质心 下的所有数据点
            ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#get all the point in this cluster
            # 利用numpy.mean 求得每列的平均值 得到一个数据点 即是该类的新的类质心
            centroids[cent,:] = mean(ptsInClust, axis=0) #assign centroid to mean 
    return centroids, clusterAssment

需要注意的点:

一些函数的使用:

    nonzero(dataSet) : 返回数据集中非零(false)的数据。

    dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]     

                 clusterAssment[:,0].A==cent : 比较第一列索引 也即是数据集中数据点的归属类,进行比较看哪些属于当前类质心。                   

matrix.A

         Return self as an ndarray object.

         Equivalent to np.asarray(self).           # 以ndarray对象返回

另外只去[0]第一列进行判断。

mean(daMmat, axis=0)  

axis = 0 对每一列进行求平均值         

datMat=numpy.array([

[1,2,3],

[4,5,6]

])

mean(datMat, axis=0)

>>>> array([2.5, 3.5, 4.5])

axis=1 是对每一行进行求平均值

mean(datMat, axis=1)

>>>>array([2., 5.])

 

数据可视化

数据可视化能够让我们更直观的看到算法的效果

可视化程序只是针对4分类的可视化 可以自己更改成自己需要的。

# -*- coding:utf-8 -*-
from numpy import *
import matplotlib.pyplot as plt
import kMeans

def make_result(fileName='testSet.txt',k=4):
	datMat = mat(kMeans.loadDataSet(fileName))
	myCentroids, clustAssing = kMeans.kMeans(datMat,k)       # k = 4
	# 将matrix 数据转换成 array
	datMatA = array(datMat)
	# 获取的聚类结果
	clustAssingA = array(clustAssing)
	clustAssingy = clustAssingA[:,0]  # 只要第一列的分到各簇的结果


	plt.scatter(datMatA[clustAssingy==0, 0],
	datMatA[clustAssingy==0, 1],
	c='red',
	marker ='s',
	label = 'cluster 1')


	plt.scatter(datMatA[clustAssingy==1, 0],
	datMatA[clustAssingy==1, 1],
	c='green',
	marker ='o',
	label = 'cluster 2')

	plt.scatter(datMatA[clustAssingy==2, 0],
	datMatA[clustAssingy==2, 1],
	c='orange',
	marker ='v',
	label = 'cluster 3')

	plt.scatter(datMatA[clustAssingy==3, 0],
	datMatA[clustAssingy==3, 1],
	c='blue',
	marker ='x',
	label = 'cluster 4')

	'''
	myCenteroids
	matrix([[ 2.80293085, -2.7315146 ],
		[ 2.6265299 ,  3.10868015],
		[-2.46154315,  2.78737555],
		[-3.38237045, -2.9473363 ]])
	>>> centerA = array(myCenteroids)
	'''
    # 根据结果集 勾绘类中心 
	centerA = array(myCentroids)
	plt.scatter(centerA[:,0],
	centerA[:,1],
	marker='*',
	c = 'purple',
	label = 'centroids')
	
	plt.legend(loc='upper left')  # 将指示label放到左上角
	plt.grid(True)
	plt.show()

 

  下面多次随机化初始化类中心 可以观察到结果也会有很大的差异:

 

                                        

 

                                       

                                    

                                       

直观上很容易观察到 第二幅图 聚类分析效果并不好。

也可以通过观察clustAssing第二列数据值来验证效果,误差在1.8左右时效果最好。

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

k-means聚类算法总结 的相关文章

随机推荐

  • 用Compose shape把外框做成封闭图形

    Compose shape之后为何会成这个样子 以下并板框的实际图样 只论述方法 解决办法 compose shape 时不要把整个outline框起来 用tempgroup一段一段的选择 选完后complete 特别要注意的是要选中相应的
  • mysql数据库商业版与社区版的区别

    1 商业版本组织管理与测试环节控制更严格 稳定性方面 会比社区版本更稳定 2 mysql是成熟产品 商业版与社区版之间性能方面相差不大 3 商业版不遵守GPL协议 社区版遵守GPL协议可以免费使用 4 使用商业版后可以购买相关的服务 享受7
  • DVWA全级别详细通关教程

    目录 暴力破解 Brute Force low Medium High Impossible 命令注入 Command Injection low Medium High Impossible CSRF 跨站请求伪造 low Medium
  • 哈工大团队开源医学智能问诊大模型

    原文 CVHub 门头沟学院AI视觉实验室御用公众号 学术 科研 就业 185篇原创内容 公众号 Title HuaTuo Tuning LLaMA Model with Chinese Medical KnowledgePDF https
  • 【MySQL】MySQL索引详解

    Mysql索引 0 写在前面 1 为什么要使用索引 2 常见的索引模型 3 索引维护 4 回表 举例子 0 写在前面 文章中包含了 1 什么是索引 2 索引的数据结构 以及各自的使用场景 3 为什么要设置主键自增 4 基于主键索引和普通索引
  • 如何修改tomcat默认端口号8080的方法

    1 背景 在默认情况下 tomcat的端口是8080 使用了两个tomcat 那么就需要修改其中的一个的端口号才能使得两个同时工作 2 方法 2 1改动一 那么 如何修改tomcat的端口号呢 首先到安装目录 或者解压目录 下找到conf文
  • 理解c++中左值与右值的一篇文章

    C 中的左值与右值 说明 这一部分内容只是帮助理解 C 11 中左值与右值的概念 在编程实践中 因为编译器优化的存在 特别是其中的返回值优化 Return Value Optimization RVO 使你不需要额外关注左值与右值的区别 像
  • Idea新建项目名后出现中括号别名

    Idea新建项目名后出现中括号别名 1 修改pom xml文件的 artifactId标签 和项目名一致 2 项目名出现中括号是因为iml文件名和项目文件名不一样 需要更改iml文件名即可
  • 开关稳压DC—DC降压电路简介

    在做数字压力开关项目时 电源输入要求是12V 24V 10 系统内需要5V和3 3V的电源 这时提供了三个方案从中选择 方案一 使用24V 5V和5V 3 3V的LDO线性稳压芯片 方案二 使用24V 12V 12V 5V 5V 3 3V种
  • SIP Using SDP with Offer/Answer Model

    根据RFC3261 13 2 1所述 SIP使用的Offer Answer模型是建立在对话环境下的 RFC中还特意对Offer Answer交互有限制 1 初始Offer必须在INVITE消息或者第一个可靠的非失败型响应中 注 当时RFC3
  • arima 公式_小白快速上手数据分析1

    ARIMA时间序列分析 作用 ARIMA时间序列分析通常用于对单列具有时间序列的数据进行预测 例如销售量预测 股票收盘价预测等等 输入 单列数据序列的数据 例如每个月销售额 每天股票的价格 通常数据量为15 50 条 输出 对未来5 15
  • python3 asyncio 爬虫_爬虫高性能asyncio+ahttpio

    async实现协程 异步编程 我们都知道 现在的服务器开发对于IO调度的优先级控制权已经不再依靠系统 都希望采用协程的方式实现高效的并发任务 如js lua等在异步协程方面都做的很强大 python在3 4版本也加入了协程的概念 并在3 5
  • centos8 免登陆 免密码 多用户命令行 启动 ,以及 界面免密

    文章目录 修改 启动 service 临时切换 运行模式 永久 切换 运行模式 由于界面 不同 os 实现 不一样 所以 方法 估计 也都 不太通用 博主 还是 建议 大家 学习 linux 使用 命令行 进行学习 centos8 界面免密
  • 没什么用的代码-批量提取主目录下所有文件夹中pdf里面的图片

    一 提前安装 pip install pymupdf 二 实现的功能 读取一个文件夹及所有子文件夹中的pdf中的图片 判断图片存储条件 存储图片 三 代码 批量提取pdf文件中的图片 author Administrator import
  • Linux基础知识:认识一下内存

    1 什么是内存泄漏 对内存来说 如果之分配内存给程序 而程序使用完不进行释放 就会造成内存泄漏 甚至耗尽系统内存 需要调用free 或unmap 来释放这些内存 2 内存紧张 系统的处理机制 2 1 回收缓存 比如使用 LRU Least
  • 链表和数组的归并排序和快速排序

    链表的归并排序和快速排序 归并排序 Definition for ListNode public class ListNode int val ListNode next ListNode int x val x next null pub
  • 【Arthas】Arthas 导出堆栈信息

    1 概述 转载 Arthas 导出堆栈信息 2 开篇 arthas提供heapdump命令导出栈信息 类似jmap命令的heap dump功能 3 原理介绍 通过通过HotSpotDiagnosticMXBean的dumpHeap来导出栈参
  • Java面试题及答案整理汇总(2023最新版)

    前言 面试前还是很有必要针对性的刷一些题 很多朋友的实战能力很强 但是理论比较薄弱 面试前不做准备是很吃亏的 这里整理了很多面试常考的一些面试题 希望能帮助到你面试前的复习并且找到一个好的工作 也节省你在网上搜索资料的时间来学习 第1 10
  • 最长字符串匹配算法(KMP算法)

    include stdafx h include
  • k-means聚类算法总结

    聚类概念 聚类分析是在对象数据中发现对象之间关系 一般来说 组内相似性越高 组间相似性越大 则聚类的效果越好 k means概念 k means是一种无监督学习 它会将相似的对象归到同一类中 k means聚类的优缺点 优点 容易实现 缺点