Kmeans算法

1.归类

聚类(clustering)属于非监督学习(unsupervised learning)

无类别标记 (class label)

2.K-means算法

1)Clustering中的经典算法,数据挖掘十大经典算法之一;

2)算法接受参数K,然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足:

同一聚类中的对象相似度较高,而不同聚类中的对象相似度较小

3)算法思想:

以空间中k个点为中心进行聚类,对最近它们的对象归类,通过迭代的方法,逐次更新各聚类中心的值,直到得到最好的聚类结果;

4)算法描述:

(1)适当选择c个类的初始中心;

(2)在第k次迭代中,对任意一个样本,求其到c各中心的距离,将该样本归到距离最短的中心所在类;

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

(4)对于c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续;

算法结束条件:(1)分类不在变化(2)上一次分类变化小于本次(3)给定迭代次数

5)算法流程

6)实例

7)优缺点

优点:速度快,简单

缺点:最终结果跟初始点选择有关,容易陷入局部最优,需直到k值

3.实践

1)代码

# -*- coding: utf-8 -*-
import numpy as np

#数据:
#X值--Y值--分类结果
# 1    1   -1
# 2    1   -1
# 4    3   -2
# 5    4   -2


def kmeans(X,k,maxIt):
    #数据点的个数(行)和列(维度)
    numPoints,numDim = X.shape
    #多增加一列作为结果
    dataSet = np.zeros((numPoints,numDim+1))
    #去掉分类结果
    dataSet[:,:-1] = X
    #随机选取k行
    centroids = dataSet[np.random.randint(numPoints,size=k),:]
    #centroids = dataSet[0:2,:]
    #对各行进行分类
    centroids[:,-1] = range(1,k+1)
    #循环次数
    iteration = 0
    #旧的中心点
    oldCentroids = None
    
    while not showIdShop(oldCentroids,centroids,iteration,maxIt):
        print("iteration:",iteration)
        print("dataSet:",dataSet)
        print("centroids:",centroids)
        #它们为两个变量,在下边需要更新
        oldCentroids = np.copy(centroids)
        iteration+=1
        #根据数据集合中心点对每个点重新分类
        updateLabels(dataSet,centroids)
        #重新计算中心点
        centroids = getCentroids(dataSet,k)
    return dataSet
def showIdShop(oldCentroids,centroids,iteration,maxIt):
    if(iteration>maxIt):
        return True
    #比较两次的中心点是否变化(比较二者的值)
    return np.array_equal(oldCentroids,centroids)
def updateLabels(dataSet,centroids):
    numPoints,numDim = dataSet.shape
    for i in range(0,numPoints):
        dataSet[i,-1] = getLabelFromClosestCentroid(dataSet[i,:-1],centroids)


def getLabelFromClosestCentroid(dataSetRow,centroids):
    label = centroids[0,-1]
    minDist = np.linalg.norm(dataSetRow-centroids[0,:-1])
    for i in range(1,centroids.shape[0]):
        #距离计算
        dist = np.linalg.norm(dataSetRow-centroids[i,:-1])
        if(dist<minDist):
            minDist = dist
            label = centroids[i,-1]
    print("minDist",minDist)
    return label
    
def getCentroids(dataSet,k):
    result = np.zeros((k,dataSet.shape[1]))
    for i in range(1,k+1):
        oneCluster = dataSet[dataSet[:,-1]==i,:-1]
        result[i-1,:-1] = np.mean(oneCluster,axis=0)
        result[i-1,-1] = i
    return result
x1 = np.array([1,1])
x2 = np.array([2,1])
x3 = np.array([4,3])
x4 = np.array([5,4])
#把数组纵向组成大矩阵
testX = np.vstack((x1,x2,x3,x4))
result = kmeans(testX,2,10)
print("result",result)
   2)结果

iteration: 1
dataSet: [[ 1.  1.  1.]
 [ 2.  1.  1.]
 [ 4.  3.  2.]
 [ 5.  4.  2.]]
centroids: [[ 1.5  1.   1. ]
 [ 4.5  3.5  2. ]]
minDist 0.5
minDist 0.5
minDist 0.707106781187
minDist 0.707106781187
result [[ 1.  1.  1.]
 [ 2.  1.  1.]
 [ 4.  3.  2.]
 [ 5.  4.  2.]]    
        
    
    
    
    




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值