0
点赞
收藏
分享

微信扫一扫

聚类算法---k-means算法

洛茄 2022-04-24 阅读 66

学习目标:

聚类算法

学习内容:

k-means算法

学习记录:

距离计算有闵可夫斯基距离,欧几里得距离,曼哈顿距离,切比雪夫距离。皮尔逊相关系数,余弦相似度,杰卡德相似系数。
这一部分内容下一篇文章再记录。

K-means聚类

K-means聚类要求样本点与中心点的欧几里得距离最小。

算法思想:
1.先导入数据。要求数据为数值型矩阵
2.创建初始质心:指定聚类数k,从原始数据集中随机选择k个对象作为初始质心。
3.计算数据集中每一个点到所有质心的距离,将数据点分配到距离最近的质心。,从而形成簇分配矩阵。
4.重新计算质心:将簇中所有点的均值作为新的质心。
5.重复3,4直至质心不再变化。

上面是算法实现的思想,写一下我认为的:开始的原始数据是杂乱无章的,但是我们要实现对其聚类,以什么为标准呢?以他们之间的到一个中心的欧几里得距离最小。这个中心是不断迭代来实现对其聚类的。假设四类东西,开始首先要输入要输入我们要分为4类,(即k=4),在这群数据中随机生成四个中心,然后我们计算每一个数据点到这个四个中心的距离,如果数据距离这个1号中心最近,那么说明他最可能是第一类。将它暂且归到第一类中,生成簇分配矩阵。因为一次聚类的肯定不准确,要重新绘制中心,经过第一次聚类已经形成了四个簇,计算簇的均值作为新的中心,在计算每个数据点到中心的距离重复下去,到中心稳定下来。

代码:

import numpy as np
import matplotlib.pyplot as plt


def loadFile(path):
    dataList = []
    # 打开文件:以二进制读模式、utf-8格式的编码方式打开
    fr = open(path, 'r', encoding='UTF-8')
    record = fr.read()
    fr.close
    # 按照行转换为一维表即包含各行作为元素的列表,分隔符有'\\r', '\\r\\n', \\n'\n",
    recordList = record.splitlines()
    # 逐行遍历:行内字段按'\\t'分隔符分隔,转换为列表
    for line in recordList:
        if line.strip():
            dataList.append(list(map(float, line.split('\t'))))
    # 返回转换后的矩阵
    recordmat = np.mat(dataList)
    return recordmat


def distEclud(vecA, vecB):
    return np.linalg.norm(vecA - vecB, ord=2)


def randCents(dataSet, k):
    n = np.shape(dataSet)[1]
    cents = np.mat(np.zeros((k, n)))
    for j in range(n):
        # 质心必须在数据集范围内,也就是在min到max之间
        minCol = min(dataSet[:, j])
    maxCol = max(dataSet[:, j])
    # 利用随机函数生成0到1.0之间的随机数
    cents[:, j] = np.mat(minCol + float(maxCol - minCol) * np.random.rand(k, 1))
    return cents


def kMeans(dataset, k):
    m = np.shape(dataset)[0]
    ClustDist = np.mat(np.zeros((m, 2)))
    cents = randCents(dataset, k)
    clusterChanged = True
    # 循环迭代,得到最近的聚类中心
    while clusterChanged:
        clusterChanged = False
        for i in range(m):
            DistList = [distEclud(dataset[i, :], cents[jk, :]) for jk in range(k)]
            minDist = min(DistList)
            minIndex = DistList.index(minDist)
            if ClustDist[i, 0] != minIndex:
                clusterChanged = True
            ClustDist[i, :] = minIndex, minDist
        # 更新聚类
        for cent in range(k):
            ptsInClust = dataset[np.nonzero(ClustDist[:, 0].A == cent)[0]]
            # 更新聚类中心cents,axis=0按列求均值
            cents[cent, :] = np.mean(ptsInClust, axis=0)

    # 返回聚类中心和聚类分配矩阵
    return cents, ClustDist

path_file = "TESTDATA.TXT"
recordMat = loadFile(path_file)
k = 4
cents, distMat = kMeans(recordMat, k)

for indx in range(len(distMat)):
    if distMat[indx, 0] == 0:
        plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='red', marker='o')
    if distMat[indx, 0] == 1:
        plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='blue', marker='o')
    if distMat[indx, 0] == 2:
        plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='cyan', marker='o')
    if distMat[indx, 0] == 3:
        plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='green', marker='o')
    # 绘制聚类中心
x = [cents[i, 0] for i in range(k)]
y = [cents[i, 1] for i in range(k)]
plt.scatter(x, y, s=80, c='yellow', marker='o')
plt.show()

运行结果:
在这里插入图片描述
使用sklearn提供的k-means方法:



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


def loadFile(path):
    dataList = []
    # 打开文件:以二进制读模式、utf-8格式的编码方式打开
    fr = open(path, 'r', encoding='UTF-8')
    record = fr.read()
    fr.close
    # 按照行转换为一维表即包含各行作为元素的列表,分隔符有'\\r', '\\r\\n', \\n'\n",
    recordList = record.splitlines()
    # 逐行遍历:行内字段按'\\t'分隔符分隔,转换为列表
    for line in recordList:
        if line.strip():
            dataList.append(list(map(float, line.split('\t'))))
    # 返回转换后的矩阵
    recordmat = np.mat(dataList)
    return recordmat



path_file = "TESTDATA.TXT"
recordMat = loadFile(path_file)
k = 4


#生成初始聚类数据
x=np.array(recordMat)
plt.axis([np.min(x[:,0])-1,np.max(x[:,0]+1),np.min(x[:,1])-1,np.max(x[:,1])-1])
plt.grid(True)
colors = ['r', 'g', 'b','c'] # 聚类颜色
markers = ['o', 's', 'D', '+'] # 聚类标志
kmeans_model=KMeans(n_clusters=k,init='k-means++')
kmeans_model.fit(x)
for i, l in enumerate(kmeans_model.labels_):
    plt.plot(x[i][0], x[i][1], color=colors[l],marker=markers[l],ls='None')
    plt.title('K = %s' %(k))
plt.show()

在这里插入图片描述

sklearn的KMearn的参数看下面这个文章:
聚类算法学习----之----sklearn.cluster.KMeans

文章内容是个人学习笔记《机器学习及应用》李克清老师。

举报

相关推荐

0 条评论