k-Means 算法分析

本人小白,第一次发布博客,大神绕路,不喜勿喷。

最近公司要求一些机器学习的内容,所以在看一些机器学习有关的资料,最近看的书名字叫做 机器学习实战。这是一本不错的书籍,很值得一读。

好,不说废话,进入我们今天的正题。

k-均值算法(k-means算法)

1.k-means算法是一种聚类算法。

何为聚类?聚类就是你在分类之前并不知道有几类,也不知道分别是哪几类,而让计算机根据数据的特征分成不同的几个类别,这些类别没有进行事先定义。这种分类方法又被称为无监督分类。

2.算法思想

在数据集中随机选取k个初始点作为质心,将数据集中的每一个点分配到一个簇中,为每个点找距离其最近的质心,将其分配到该质心所对应的簇,这一步完成之后,每个簇的质心更新为该簇所有点的平均值。到这里初始质心已经发生变化,重复以上步骤n次直到之心不再发生变化为止。

3.Python实现

# coding=utf-8

from numpy import *import matplotlibimport matplotlib.pyplot as pltimport operatorfrom os import listdirimport time

初始化数据集

def createDataSet():    group = array([[1.0, 1.1], [1.0, 1.0],                   [0, 0], [0, 0.1],                   [2, 1.0], [2.1, 0.9],                   [0.3, 0.0], [1.1, 0.9],                   [2.2, 1.0], [2.1, 0.8],                   [3.3, 3.5], [2.1, 0.9],                   [2, 1.0], [2.1, 0.9],                   [3.5, 3.4], [3.6, 3.5]                   ])    return group

#自己写的画图函数,每次都会画出初始数据集的点(红色),和要观察的点。
def show(data,color=None):    if not color:        color=‘green‘    group=createDataSet()    fig = plt.figure(1)    axes = fig.add_subplot(111)    axes.scatter(group[:, 0], group[:, 1], s=40, c=‘red‘)    axes.scatter(data[:, 0], data[:, 1], s=50, c=color)    plt.show()

代码取自机器学习实战第二章,在此加上我对这些代码的理解

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

由于数据量级之间的差异会对影响度造成干扰,所以要对初始数据做数据归一化处理。

def randCent(dataSet, k):       #数据归一化处理    n = shape(dataSet)[1]    centroids = mat(zeros((k, n)))  # create centroid mat    for j in range(n):  # create random cluster centers, within bounds of each dimension        minJ = min(dataSet[:, j])        rangeJ = float(max(dataSet[:, j]) - minJ)        centroids[:, j] = mat(minJ + rangeJ * random.rand(k, 1))    return centroids

shape(dataSet)是numpy库的一个方法,返回的是一个n维矩阵依次的维度。比如dataset=[[1,2,3],[2,4,5]] 的话,那么shape(dataset)=(2,3)

mat 方法是初始化矩阵

接下来是kmeans函数

def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent): #参数dataSet是待聚类数据矩阵,k是聚类类数    m = dataSet.shape[0]  #训练集中含有点的个数    clusterAssment = zeros((m, 2))  #初始化结果集,个数等于训练集中点的个数    centroids = createCent(dataSet, k)    # print centroids    # show(centroids) #matplotlib画图展示训练数据分布      clusterChanged = True  #标记参数,用来检测每次循环后质心位置是否还会发生变化    while clusterChanged:        clusterChanged = False

for i in range(m):                  point = dataSet[i, :]  # 遍历数据集中的每个点            mindist = inf      #inf 是Python中的正无穷            minindex = -1      #随机定义一个序号,此序号用来表示每个点与哪个质心的距离最近,是质心的序号,初始随便取个负数就好

for n in range(k):                heart = centroids[n, :]  # 遍历每个质心                distance = distMeas(point, heart)  # 求点与质心距离                if distance < mindist: #如果此质心的距离比当前最小距离小                    mindist = distance  # 更新最小距离mindist                    minindex = n  # 更新最小距离的质心序号

if clusterAssment[i, 0] != minindex: clusterChanged = True 如果质心的序号发生变化,改变标记数据            clusterAssment[i, :] = minindex, mindist ** 2  # 将第i个点存为(最近质心序号,此点到质心距离的平方)        # print clusterAssment        for cent in range(k):#遍历数据集,更新质心的位置            ptsInClust = dataSet[(clusterAssment[:, 0] == cent)]  # 取出该质心绑定的点            # print ptsInClust            if len(ptsInClust):                centroids[cent, :] = mean(ptsInClust, axis=0)  # 取出点的均值            else:                centroids[cent, :] = array([[0, 0]])        show(centroids,color=‘green‘)  #作图画出此次循环后质心的变化情况        # print centroids        # print "----------------"

# show(centroids)    return centroids, clusterAssment  #返回质心,以及各个点的信息
centroids, clusterAssment=kMeans(createDataSet(),4)  #聚类为4类show(centroids,color=‘yellow‘)  #聚类结果展示为黄色点

图片

初始数据集以及初始随机选取质心

一种结果比较完美

尝试几次会出现以下不尽如人意的结果

以上就是kmeans的具体实现方法,但这个方法并不尽人意,多次执行会发现聚类得到的点并不稳定,也不是每次都能得到我们想要的最佳结果,这是因为这个算法只能达到局部最优,不能保证全局最优,而这个原因就在于我们不能保证我们出是选取到的点是最佳的点。当然也是有改进方法的,我会继续更新下一节二分 k-均值算法


				
时间: 2024-08-06 09:49:38

k-Means 算法分析的相关文章

软件——机器学习与Python,聚类,K——means

K-means是一种聚类算法: 这里运用k-means进行31个城市的分类 城市的数据保存在city.txt文件中,内容如下: BJ,2959.19,730.79,749.41,513.34,467.87,1141.82,478.42,457.64TianJin,2459.77,495.47,697.33,302.87,284.19,735.97,570.84,305.08HeBei,1495.63,515.90,362.37,285.32,272.95,540.58,364.91,188.63

k means聚类过程

k-means是一种非监督 (从下图0 当中我们可以看到训练数据并没有标签标注类别)的聚类算法 0.initial 1.select centroids randomly 2.assign points 3.update centroids 4.reassign points 5.update centroids 6.reassign points 7.iteration reference: https://www.naftaliharris.com/blog/visualizing-k-me

快速查找无序数组中的第K大数?

1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN).在此,我们想探索是否存在时间复杂度 < O(NlgN),而且近似等于O(N)的高效算法. 还记得我们快速排序的思想麽?通过“partition”递归划分前后部分.在本问题求解策略中,基于快排的划分函数可以利用“夹击法”,不断从原来的区间[0,n-1]向中间搜索第k大的数,大概搜索方向见下图: 2.参考代码: 1 #include <cstdio> 2 3 #define sw

R语言学习笔记—K近邻算法

K近邻算法(KNN)是指一个样本如果在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.即每个样本都可以用它最接近的k个邻居来代表.KNN算法适合分类,也适合回归.KNN算法广泛应用在推荐系统.语义搜索.异常检测. KNN算法分类原理图: 图中绿色的圆点是归属在红色三角还是蓝色方块一类?如果K=5(离绿色圆点最近的5个邻居,虚线圈内),则有3个蓝色方块是绿色圆点的"最近邻居",比例为3/5,因此绿色圆点应当划归到蓝色方块一类:如果

HDU 3657 Game(取数 最小割)经典

Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1065    Accepted Submission(s): 449 Problem Description onmylove has invented a game on n × m grids. There is one positive integer on each g

HDU 5175 Misaki&#39;s Kiss again (异或运算,公式变形)

Misaki's Kiss again Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 201    Accepted Submission(s): 57 Problem Description After the Ferries Wheel, many friends hope to receive the Misaki's kiss

HDU 6065 RXD, tree and sequence (LCA DP)

RXD, tree and sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 234    Accepted Submission(s): 82 Problem Description RXD has a rooted tree T with size n, the root ID is 1, with the dep

Android 常用 adb 命令

在开发或者测试的过程中,我们可以通过 adb 来管理多台设备,其一般的格式为: adb [-e | -d | -s <设备序列号>] <子命令> 在配好环境变量的前提下,在命令窗口当中输入 adb help 或者直接输入 adb ,将会列出所有的选项说明及子命令.这里介绍一些里面常用的命令: 1 adb devices , 获取设备列表及设备状态 2 [xuxu:~]$ adb devices 3 List of devices attached 4 44c826a0 device

HDU 2126 01背包(求方案数)

Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1886    Accepted Submission(s): 699 Problem Description When the winter holiday comes, a lot of people will have a trip. Genera

自学成才的数据科学家告诉你5个学习大数据的正确姿势!

对于数据科学来说,现在是发展的黄金时期.这是个新领域,但增长迅速,同时数据科学家的缺口也很大,据说他们的平均年薪可以达到10万美元.哪里有高薪,哪里就吸引人们,但是数据科学技能的差距意味着许多人需要努力学习.      第一步当然是询问“我怎么学习数据科学”,这个问题的答案往往是一长串的课程和书籍阅读,从线性代数到统计数据,这几年我也是这样学习过来的.我没有编程背景,但我知道我喜欢处理数据. 我比较不能理解在完全没有理解别人的背景时就给他一份长长的书单或者技能表.这就类似于一个老师给你一堆教科书