python实现kmeans算法并可视化_机器学习(一)Kmeans算法+简单可视化展示

0.我们导师的土味理解

均值聚类算法通俗解释

有一个黑社会,总共有10个人,分别是p1~p10,每个人都有智商,力量,情商,颜值四项打分。

现在要选两个大佬,

首先,p1与p2自高奋勇要当大佬,这时,其他人开始评估自己和两位大佬的各项差距,一部分人觉得他和p1差距较小,就成p1的小弟,另一部分人觉得和p2差距较小,就成了p2的小弟,

这时分别计算两群人各项属性的均值,获得的均值就成为虚拟的大佬v1和v2,这时拿v1 v2分别和p1 p2做比较,如果各项相等,就说明p1和p2确实是公认的大佬

如果不相等,就说明选的大佬不合适,再计算这群人和虚拟大佬v1 v2的差距,这时v1和v2就成为指定大佬,再计算每人和指定大佬的差距,推算出新的虚拟大老v3 v4,如果虚拟大佬与指定大佬相吻合,选举大佬结束,这样,10个人就分成两组,完成聚类。如果不吻合,继续选举。Kmeans算法(百度百科)

K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。K-means算法的基本思想是:以空间中k个点为形心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各簇的形心的值,直至得到最好的聚类结果。(形心可以是实际的点、或者是虚拟点)

假设要把样本集分为c个簇,算法描述如下:

(1)适当选择c个簇的初始形心;

(2)在第k次迭代中,对任意一个样本,求其到c个形心的欧氏距离或曼哈顿距离,将该样本归类到距离最小的形心所在的簇;

(3)利用均值等方法更新该簇的形心值;

(4)对于所有的c个簇形心,如果利用(2)(3)的迭代法更新后,当形心更新稳定或误差平方和最小时,则迭代结束,否则继续迭代。(误差平方和即簇内所有点到形心的距离之和)

该算法的最大优势在于简洁和快速。算法的关键在于初始中心的选择和距离公式。

2.伪代码(我的理解)

'''随机选择k个初始质心while(true){计算每个点到最近距离的质心,归为该类。重新计算每个类的质心。if(质心与上一次质心一样or达到最大迭代次数)break;}'''

3.代码(Python 3 语言实现)

from numpy import *

import matplotlib.pyplot as plt

from sklearn.cluster import KMeans

#dataSet:聚类数据集

#k:指定的k个类(大佬)

def kmeans(dataSet, k):

#得到数据样本的维度n

sampleNum, col = dataSet.shape

#初始化为一个(k,n)的矩阵=簇

cluster = mat(zeros((sampleNum, 2)))

#生成全零阵

centroids = zeros((k, col))

#选择质心

for i in range(k):

#索引为随机生成的int类型的且在0-sampleNum间的数

index = int(random.uniform(0, sampleNum))

centroids[i, :] = dataSet[index, :]

#设置flag,查看聚类结果是否发生变化

clusterChanged = True

#只要聚类结果一直发生变化,就一直执行聚类算法,直至所有数据点聚类结果不变化

while clusterChanged:

#聚类结果变化布尔类型置为false

clusterChanged = False

#遍历数据集每一个样本向量

for i in range(sampleNum):

#使用sqrt函数(二分法)

minDist = sqrt(sum(power(centroids[0, :] - dataSet[i, :], 2)))

minIndex = 0

#计算点到质心的距离

for j in range(1,k):

distance = sqrt(sum(power(centroids[j, :] - dataSet[i, :], 2)))

#当前最小距离一定时,索引为J

if distance < minDist:

minDist = distance

minIndex = j

# 当前聚类结果中第i个样本的聚类结果发生变化:布尔类型置为true,继续聚类算法

if cluster[i, 0] != minIndex:

clusterChanged = True

#更新聚类结果和平方误差

cluster[i, :] = minIndex, minDist**2

#遍历每一个质心

for j in range(k):

#筛选出属于当前质心类的所有样本

pointsInCluster = dataSet[nonzero(cluster[:, 0].A == j)[0]]

#计算列的均值(使用axis=0:求列的均值)

centroids[j, :] = mean(pointsInCluster, axis = 0)

return centroids, cluster

#创建简单数据集以及进行可视化

dataSet = [[1,1],[3,1],[1,4],[2,5],[11,12],[14,11],[13,12],[11,16],[17,12],[28,10],[26,15],[27,13],[28,11],[29,15]]

dataSet = mat(dataSet)

k = 3

centroids, cluster = kmeans(dataSet, k)

sampleNum, col = dataSet.shape

mark = ['or', 'ob', 'og']

for i in range(sampleNum):

markIndex = int(cluster[i, 0])

plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])

mark = ['+r', '+b', '+g']

for i in range(k):

plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=12)

plt.show()

简单可视化展示由于每次的K值是随机,所以可视化图不一需要注意的是: Kmeans中判断循环是否结束,应该就是判断第N次计算的聚类的中心点是否和原聚类中心点一致,但是有个问题,我用的Python语言,在做数值相等判断中(尤其是flaot类型时数据并不可能完全一致比如

),实际运算会因为小数点后的些许差距导致判断为Flase,所以应该有允许范围内的误差,这一点需要大家在实际应用中体验,在此不再一一赘述。

代码仅供交流。

你可能感兴趣的:(python实现kmeans算法并可视化_机器学习(一)Kmeans算法+简单可视化展示)