编程语言
首页 > 编程语言> > 机器学习-KMeans算法

机器学习-KMeans算法

作者:互联网

线性回归算法是一种有监督的算法。

聚类是一种无监督的机器学习任务,他可以自动将数据划分成类cluster.因此聚类分组不需要提前被告知所划分的组应该是什么样的。因为我们针织可能都不知道我们在寻找什么,所以聚类是用于知识发现而不是预测

 

KMeans聚类的原理以及聚类流程

  1. 随机找K个样本(中心点)
  2. 计算空间中所有的样本与这K个样本的距离
  3. 统计每一个样本与K个样本的距离大小,距离哪一个样本最近,那么这个样本就属于哪一类。
  4. 以上使用的是KNN思想(当k =1时满足)
  5.  分完类之后,每个组中重新计算一个新的中心点,中心点有可能不会坐落于某一个样本上,有可能是一个虚拟的点
  6.  再次计算空间中所有的样本与这K个中心点的距离
  7. 再次重新分类
  8. 一次迭代,一直到每个中心的点坐标不在发生改变(每一个中心点的坐标与上一个中心点的坐标不在发生改变)

问题1: 当数据量特别大怎么办?

问题2: 最开始随机找的K个中心点,如果距离很近怎么办?

问题3: 聚类效果好不好?怎么衡量?标准是什么?

问题4: K值怎么选择? 选几个?

 

 

 

KMeans聚类代码

import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 12))


def loadDataSet(fileName):
    dataMat = []
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = list(map(float, curLine))
        dataMat.append(fltLine)
        # 80 *2 的矩阵
    return dataMat

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


# 生成key个中心点
def randCent(dataSet, key):
    # shape是80*2 n = 2
    n = np.shape(dataSet)[1]
    '''
        centroids是一个3*2的矩阵,用于存储三个中心点的坐标
        生成key * n 的 0矩阵
    '''
    centroids = np.mat(np.zeros((key, n)))
    for j in range(n):
        minJ = np.min(dataSet[:, j])
        rangeJ = np.max(dataSet[:, j]) - minJ
        # [:, j]纵向赋值, 第一次复制0列,第二次复制1列
        centroids[:, j] = np.mat(minJ + rangeJ * np.random.rand(key, 1))
    return centroids


def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
    # m=80
    m = np.shape(dataSet)[0]
    # clusterAssment是 80*2de 0矩阵, 存放所有的点到中心点的距离
    clusterAssment = np.mat(np.zeros((m, 2)))
    #     createCent找到K个随机中心点
    centroids = createCent(dataSet, k)
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False
        #循环80 次
        for i in range(m):
            minDist = np.inf
            minIndex = -1
            # 循环3次, 用数据上的点去和三个中心点比较,那个中心点最近,该点就是 minDist(离中心点最近的距离) minIndex(哪个中心点)
            for j in range(k):
                # 拿到中心的第j行
                x = centroids[j, :]
                # 使用中心的第j行 和数据的第i行进行距离计算
                distJI = distMeas(x, dataSet[i, :])
                if distJI < minDist:
                    minDist = distJI
                    minIndex = j
             # 0矩阵的x值不等于   离中心点最近的距离, 跳出去的条件
            if clusterAssment[i, 0] != minIndex:
                clusterChanged = True
            # 0矩阵赋值 x=中心点 y=离中心点最近的距离
            clusterAssment[i, :] = minIndex, minDist
        for cent in range(k):
            # 0矩阵的所有x值
            a = clusterAssment[:, 0].A
            # 选择矩阵上中心点=cent的值,也就是矩阵的下标, b是两个数组,b[0] = 矩阵下标 b[1] = cent
            b =np.nonzero(a == cent)
            # 根据矩阵下标取出改中心点的所有最近的点
            ptsInClust = dataSet[b[0]]
            # 根据最近的点重新计算中心点,并将新的中心点赋值给centroids
            centroids[cent, :] = np.mean(ptsInClust, axis=0)
    return centroids, clusterAssment


if __name__ == '__main__':
    dataMat = np.mat(loadDataSet('D:\\code\\python\\test2\\data\\KMeans_testSet.txt'))
    k = 3
    centroids, clusterAssment = kMeans(dataMat, k, distMeas=distEclud, createCent=randCent)
    # centroids 生成的3个中心点, clusterAssment是 80*2de 0矩阵, 存放所有的点到中心点的距离  0矩阵赋值 x=中心点 y=离中心点最近的距离
    print(clusterAssment)
    print(centroids)

    dataMat = np.array(dataMat)
    y_pred1 = np.array([int(i) for j in clusterAssment[:, 0].A for i in j])
    plt.subplot(224)
    plt.scatter(dataMat[:, 0], dataMat[:, 1], c=y_pred1)
    plt.title("kmeans04")
    plt.show()

 

标签:机器,矩阵,KMeans,centroids,算法,中心点,clusterAssment,np,dataMat
来源: https://www.cnblogs.com/bigdata-familyMeals/p/14616907.html