首页 > 编程语言 >数据挖掘算法—K-Means算法

数据挖掘算法—K-Means算法

时间:2022-10-24 13:01:26浏览次数:53  
标签:Means centroids dataSet cluster np 算法 数据挖掘 质心

一位读者建议多分享一些具体算法相关的内容,这期分享一下数据挖掘相关的算法。

简介

又叫K-均值算法,是非监督学习中的聚类算法。


基本思想

k-means算法比较简单。在k-means算法中,用cluster来表示簇;容易证明k-means算法收敛等同于所有质心不再发生变化。基本的k-means算法流程如下:



选取k个初始质心(作为初始cluster,每个初始cluster只包含一个点);  

repeat:  

    对每个样本点,计算得到距其最近的质心,将其类别标为该质心所对应的cluster;  

    重新计算k个cluster对应的质心(质心是cluster中样本点的均值);  

until 质心不再发生变化  



repeat的次数决定了算法的迭代次数。实际上,k-means的本质是最小化目标函数,目标函数为每个点到其簇质心的距离的平方和:

数据挖掘算法—K-Means算法_数据集

N是元素个数,x表示元素,c(j)表示第j簇的质心


算法复杂度

时间复杂度是O(nkt) ,其中n代表元素个数,t代表算法迭代的次数,k代表簇的数目


优缺点

优点

简单、快速;

对大数据集有较高的效率并且是可伸缩性的;

时间复杂度近于线性,适合挖掘大规模数据集。

缺点

k-means是局部最优,因而对初始质心的选取敏感;

选择能达到目标函数最优的k值是非常困难的。


代码

# coding:utf-8

import numpy as np
import matplotlib.pyplot as plt


def loadDataSet(fileName):
'''
加载测试数据集,返回一个列表,列表的元素是一个坐标
'''
dataList = []
with open(fileName) as fr:
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = list(map(float, curLine))
dataList.append(fltLine)
return dataList


def randCent(dataSet, k):
'''
随机生成k个初始的质心
'''
n = np.shape(dataSet)[1] # n表示数据集的维度
centroids = np.mat(np.zeros((k, n)))
for j in range(n):
minJ = min(dataSet[:, j])
rangeJ = float(max(dataSet[:, j]) - minJ)
centroids[:, j] = np.mat(minJ + rangeJ * np.random.rand(k, 1))
return centroids


def kMeans(dataSet, k):
'''
KMeans算法,返回最终的质心坐标和每个点所在的簇
'''
m = np.shape(dataSet)[0] # m表示数据集的长度(个数)
clusterAssment = np.mat(np.zeros((m, 2)))

centroids = randCent(dataSet, k) # 保存k个初始质心的坐标
clusterChanged = True
iterIndex = 1 # 迭代次数
while clusterChanged:
clusterChanged = False
for i in range(m):
minDist = np.inf
minIndex = -1
for j in range(k):
distJI = np.linalg.norm(np.array(centroids[j, :]) - np.array(dataSet[i, :]))
if distJI < minDist:
minDist = distJI
minIndex = j
if clusterAssment[i, 0] != minIndex: clusterChanged = True
clusterAssment[i, :] = minIndex, minDist ** 2
print("第%d次迭代后%d个质心的坐标:\n%s" % (iterIndex, k, centroids)) # 第一次迭代的质心坐标就是初始的质心坐标
iterIndex += 1
for cent in range(k):
ptsInClust = dataSet[np.nonzero(clusterAssment[:, 0].A == cent)[0]] # get all the point in this cluster
centroids[cent, :] = np.mean(ptsInClust, axis=0)
return centroids, clusterAssment


def showCluster(dataSet, k, centroids, clusterAssment):
'''
数据可视化,只能画二维的图(若是三维的坐标图则直接返回1)
'''
numSamples, dim = dataSet.shape
if dim != 2:
return 1

mark = ['or', 'ob', 'og', 'ok', 'oy', 'om', 'oc', '^r', '+r', 'sr', 'dr', '<r', 'pr']

# draw all samples
for i in range(numSamples):
markIndex = int(clusterAssment[i, 0])
plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])

mark = ['Pr', 'Pb', 'Pg', 'Pk', 'Py', 'Pm', 'Pc', '^b', '+b', 'sb', 'db', '<b', 'pb']
# draw the centroids
for i in range(k):
plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=12)

plt.show()


if __name__ == '__main__':
dataMat = np.mat(loadDataSet('./data.txt')) # mat是numpy中的函数,将列表转化成矩阵
k = 6 # 选定k值,也就是簇的个数(可以指定为其他数)
cent, clust = kMeans(dataMat, k)
showCluster(dataMat, k, cent, clust)

txt内容为:


1.658985 4.285136
-3.453687 3.424321
4.838138 -1.151539
-5.379713 -3.362104
0.972564 2.924086
-3.567919 1.531611
0.450614 -3.302219
-3.487105 -1.724432
2.668759 1.594842
-3.156485 3.191137
3.165506 -3.999838
-2.786837 -3.099354
4.208187 2.984927
-2.123337 2.943366
0.704199 -0.479481
-0.392370 -3.963704
2.831667 1.574018
-0.790153 3.343144
2.943496 -3.357075
-3.195883 -2.283926
2.336445 2.875106
-1.786345 2.554248
2.190101 -1.906020
-3.403367 -2.778288
1.778124 3.880832
-1.688346 2.230267
2.592976 -2.054368
-4.007257 -3.207066
2.257734 3.387564
-2.679011 0.785119
0.939512 -4.023563
-3.674424 -2.261084
2.046259 2.735279
-3.189470 1.780269
4.372646 -0.822248
-2.579316 -3.497576
1.889034 5.190400
-0.798747 2.185588
2.836520 -2.658556
-3.837877 -3.253815
2.096701 3.886007
-2.709034 2.923887
3.367037 -3.184789
-2.121479 -4.232586
2.329546 3.179764
-3.284816 3.273099
3.091414 -3.815232
-3.762093 -2.432191
3.542056 2.778832
-1.736822 4.241041
2.127073 -2.983680
-4.323818 -3.938116
3.792121 5.135768
-4.786473 3.358547
2.624081 -3.260715
-4.009299 -2.978115
2.493525 1.963710
-2.513661 2.642162
1.864375 -3.176309
-3.171184 -3.572452
2.894220 2.489128
-2.562539 2.884438
3.491078 -3.947487
-2.565729 -2.012114
3.332948 3.983102
-1.616805 3.573188
2.280615 -2.559444
-2.651229 -3.103198
2.321395 3.154987
-1.685703 2.939697
3.031012 -3.620252
-4.599622 -2.185829
4.196223 1.126677
-2.133863 3.093686
4.668892 -2.562705
-2.793241 -2.149706
2.884105 3.043438
-2.967647 2.848696
4.479332 -1.764772
-4.905566 -2.911070

​结果为:

k=5时

数据挖掘算法—K-Means算法_迭代_02

k=6时

数据挖掘算法—K-Means算法_数据集_03


收录于合集 #算法

上一篇GPS抽稀之道格拉斯-普克(Douglas-Peuker)算法下一篇Matlab RBF神经网络及其实例


标签:Means,centroids,dataSet,cluster,np,算法,数据挖掘,质心
From: https://blog.51cto.com/domi/5789461

相关文章

  • 实验一:决策树算法实验
    【实验目的】理解决策树算法原理,掌握决策树算法框架;理解决策树学习算法的特征选择、树的生成和树的剪枝;能根据不同的数据类型,选择不同的决策树算法;针对特定应用场景及......
  • React面试:谈谈虚拟DOM,Diff算法与Key机制
    1.虚拟dom原生的JSDOM操作非常消耗性能,而React把真实原生JSDOM转换成了JavaScript对象。这就是虚拟Dom(VirtualDom)每次数据更新后,重新计算虚拟Dom,并和上一次生成的虚拟......
  • 实验一:决策树算法实验
    一、【实验目的】理解决策树算法原理,掌握决策树算法框架;理解决策树学习算法的特征选择、树的生成和树的剪枝;能根据不同的数据类型,选择不同的决策树算法;针对特定应用场景......
  • docker swarm中的raft 一致性算法,究竟有什么作用?
    当docker运行在swarm集群模式时,管理节点通过Raft一致性算法来管理全局的集群状态。 Dockerswarm集群模式使用raft一致性算法的原因是: 确保集群中负责管理和......
  • 什么是算法和数据结构
    【1】算法(1)可以解决具体问题:例如1+2+3+4+。。。+99+100解题流程=算法(2)有设计解决的具体流程算法1: 1+2=3 3+3=66+4=10.。。加到100--->5050算法2:(1*100*50=101*5......
  • 数组中的排序算法以及普通查找
    数组中的排序算法以及普通查找普通查找基本查找publicclassDemo01{publicstaticvoidmain(String[]args){int[]m={10,45,78,4,6,85,14,......
  • 查找算法
    总结常用的查找算法,针对不同的情况,能够反应出哪种数组结构是效率最快的##顺序查找条件:无序或有序队列。原理:按顺序比较每个元素,直到找到关键字为止。时间复杂度:O(n)#......
  • 单链表插入和删除一个节点的伪代码算法
    插入设ai-1节点为pai+1节点为q插入节点为t则p-->t-->next=q-->next删除设ai-1节点为pai+1节点为q删除的字节为tp-->next=t-->nextfree(t)参考链接https://bl......
  • c++算法竞赛常用板子集合(持续更新)
    前言本文主要包含算法竞赛一些常用的板子,码风可能不是太好,还请见谅。后续会继续补充没有的板子。当然我太菜了有些可能写不出来T^T稍微有些分类但不多,原谅我QwQ建议Ct......
  • 基于miu小波变换的人体步态数据检测和识别算法matlab仿真
    目录一、理论基础3.2.1加速度计3.2.2陀螺仪 3.3基于IMU设备的人体步态数据的采集二、MATLAB仿真程序三、仿真结果一、理论基础在进行数据采集的过程中,需要根据实......