机器学习实战(python3.7)-K-MEANS聚类

如果觉得本篇文章对您的学习起到帮助作用,请 点赞 + 关注 + 评论 ,留下您的足迹💪💪💪

本篇文章为我对机器学习实战-K-MEANS聚类的理解与我在学习时所做笔记,一是为了日后查找方便并加深对代码的理解,二是希望能帮助到使用这本书遇到困难的人。

代码可在python3.7跑通
因此代码相对原书做了一些修改,增加了可读性,同时也解决了一些问题。

代码k_means.py及详细注释如下:

import numpy as np
import matplotlib as mpl
import  matplotlib.pyplot as plt

def loadDataset(filename):
    '''
    # 加载数据,并转化为 numpy.ndarray 类型
    :param filename: 文档路径及名字
    :return: 返回数据为 numpy.ndarray 类型
    '''
    dataMat = []
    with open(filename) as fr:
        for line in fr.readlines():
            curline = line.strip().split('\t')
            dataMat.append([float(curline[0]), float(curline[1])])
    dataMat = np.array(dataMat)
    return dataMat

def draw(dataset):
    # 显示汉字
    mpl.rcParams['font.sans-serif'] = [u'SimHei']
    # 解决负号错误问题
    mpl.rcParams['axes.unicode_minus'] = False

    fig = plt.figure(figsize=(10, 8))
    ax = fig.add_subplot(111)
    ax.plot(dataset[:,0], dataset[:,1],'bo')
    plt.show()

def distEclud(vecA, vecB):
    '''
    # 计算 vecA 和 vecB 两个向量的欧式距离
    :param vecA: 向量A
    :param vecB: 向量B
    :return:
    '''
    return np.sqrt(np.sum(np.power(vecA - vecB, 2)))

def randCent(dataset, k):
    '''
    # 该函数为给定数据集生成包含 k 个随机质心的集合。
    # 随机质心必须在整个数据集的边界之内,需要通过数据集每一维的最小最大值来确定。
    :param dataset:数据集
    :param k:聚类算法簇的个数
    :return:
    '''
    n = np.shape(dataset)[1]
    centroids = np.zeros((k, n))
    for j in range(n):
        minJ = np.min(dataset[:,j])
        rangeJ = float(np.max(dataset[:,j]) - minJ)
        # 最小值 + 最小最大范围 * [0, 1]
        centroids[:,j] = np.squeeze(minJ + rangeJ * np.random.rand(k, 1))   # 去掉一个维度,与centroids[:,j]同维
    return centroids

def KMeans(dataset, k, distMeas=distEclud, creatCent=randCent):
    m = np.shape(dataset)[0]
    # 簇分类结果矩阵,分为两列
    # 第一列记录:簇索引值
    # 第二列记录:存储误差(当前点到簇质心的距离)
    clusterAssment = np.zeros((m, 2))
    centroids = creatCent(dataset, k)
    clusterChanged = True   # 判断是否继续迭代的标志位,所有数据点不在重新分配则为Flase
    while clusterChanged:
        clusterChanged = False
        for i in range(m):
            minDist = np.inf    # np.inf 表示一个无穷大的正数
            minIndex = -1
            for j in range(k):
                distJI = distMeas(dataset[i,:], centroids[j,:]) # 数据点和质心的距离
                if distJI < minDist:    # 比较数据点到第k个质心的距离,取数据点到质心距离最小的质心
                    minDist = distJI
                    minIndex = j
            if clusterAssment[i,0] != minIndex: clusterChanged = True   # 所有数据分类簇的索引值不再变化则停止迭代
            clusterAssment[i,:] = minIndex,minDist**2   # 距离取平方,对应于损失函数

        for cent in range(k):  # 重新计算质心
            # ptsInClust = dataset[np.nonzero(clusterAssment[:, 0] == cent)[0]]  # 在这个群集中找到对应簇的所有点
            ptsInClust = dataset[clusterAssment[:, 0] == cent]  # 很简单代码就可以解决
            centroids[cent, :] = np.mean(ptsInClust, axis=0)  # 质心取平均值

    return centroids, clusterAssment


if __name__ == '__main__':
    filename = 'dataset//testSet.txt'
    dataMat = loadDataset(filename)
    centroids, clusterAssment = KMeans(dataMat, 4, distMeas=distEclud, creatCent=randCent)
    print(centroids)
    print(clusterAssment)

希望文章内容可以帮助到你,快来动手敲代码吧!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值