【机器学习】利用numpy实现K-Means聚类算法(Python代码)

简介: 【机器学习】利用numpy实现K-Means聚类算法(Python代码)

简 介:下面是我在学习时候的记录并加上自己的理解。本文意在记录自己近期学习过程中的所学所得,如有错误,欢迎大家指正。

 

关键词:Python、机器学习、K-Means聚类

"""
 * Created with PyCharm
 * 作者: 阿光
 * 日期: 2021/7/18
 * 时间: 14:19
 * 描述: 利用numpy自己实现K-Means算法
"""
import random
import warnings
import numpy as np
import pandas as pd
from Draw import draw
warnings.filterwarnings('ignore')
# 加载数据
data = pd.read_csv("../../data/cluster_500-10_7.csv", encoding="gbk")
X = data.iloc[:, 1:-2].values
y = data.iloc[:, -1].values.flatten()
cluster = 7  # 定义簇的个数
iter_ = 500  # 每轮的k-means的迭代次数
epochs = 20  # 模型的迭代轮数
label_ = np.zeros(len(X))  # 定义样本分类集合,代表每个样本所属的簇类别,[0,1,4,2]
best_label = []  # 保存最好的聚类效果
best_score = 99999  # 保存模型最优效果下的DB指数
def kmeans(x):
    """
     * 描述: K-Means算法的入口
     * 参数: x即样本数据
     * 返回值:
    """
    # 随机选择k个样本作为初始向量
    # test = random.sample(range(0, x.shape[0]), cluster)
    # print(test)
    x_center = x[random.sample(range(0, x.shape[0]), cluster), :]
    # x_center = init_cluster(X, cluster)
    # 新的簇的向量中心
    new_center = x_center.copy()
    k = 0  # 记录迭代轮数
    # 进行迭代更新,只要上一次和本次的簇中心不一致就继续迭代
    while True:
        if ((x_center == new_center).sum() == x_center.shape[0] * x_center.shape[1] and k != 0) or k > iter_:
            break
        x_center = new_center
        k += 1
        # 计算样本到簇中心的距离
        matrix = distance(x_center, x)
        # 更新每个样本的所属簇分类
        update_cluster(matrix)
        # 根据新的样本划分情况,更新每个簇的中心
        new_center = update_center(x)
    # print("聚类结束,共迭代{}轮".format(k))
def run(X):
    """
     * 描述: k-means算法的主调函数
     * 参数: X为样本数据
     * 返回值:
    """
    # 迭代多个epoch,根据DBI指数选取最好的结果
    for epoch in range(epochs):
        kmeans(X)  # 调用kmeans
        # 计算DBI指数
        DBI = optimizer_score(cluster, X)
        global best_score, best_label
        # 如果当前轮数的效果好于上一次的,记录最优的DBI指数,以及最好的聚类结果
        if DBI < best_score:
            best_score = DBI
            best_label = label_
def init_cluster(X, cluster):
    x_center = np.zeros((cluster, X.shape[1]))
    i = 0
    res = set()
    while True:
        if i == 0:
            index = random.sample(range(0, X.shape[0]), 1)
            res.add(index[0])
            x_center[i, :] = X[index]
            i += 1
        else:
            distance_ = np.zeros((X.shape[0], i))
            for j in range(i):
                row = x_center[j, :]
                distance_[:, j] = np.sqrt(((X - row) ** 2).sum(axis=1))
            distance_ = (distance_ - distance_.mean(axis=0)) / distance_.std(axis=0)
            rank = np.argsort(distance_, axis=0)
            rank = (rank - rank.mean(axis=0)) / rank.std(axis=0)
            loc = np.sum(rank, axis=1)
            # distance_ = np.sum(distance_, axis=1)
            # location = np.where(distance_ == distance_.max())
            index = np.argmax(loc)
            print(res)
            if index not in res:
                x_center[i, :] = X[index]
                res.add(index)
                i += 1
            else:
                while index < X.shape[0] - 2:
                    index = index + 1
                    if index not in res:
                        x_center[i, :] = X[index]
                        res.add(index)
                        i += 1
                        break
        if i == cluster:
            break
    return x_center
def optimizer_score(cluster, X):
    """
     * 描述: 计算DBI优化指标
     * 参数:
            cluster:聚类簇数
            X:样本数据
     * 返回值: 模型的DBI指数
    """
    # 用于计算簇内平均值
    def avg_C(label):
        distance_ = np.zeros((X[label_ == label, :].shape[0], X[label_ == label, :].shape[0]))
        for i, row in enumerate(X[label_ == label, :]):
            distance_[i, :] = np.sqrt(np.sum((X[label_ == label, :] - row) ** 2, axis=1))
        distance_ = distance_.sum() / (X.shape[0] * (X.shape[0] - 1))
        return distance_
    # 用于计算簇间中心的距离
    def d_cen(cluster_i, cluster_j):
        X_i = X[label_ == cluster_i, :]
        X_j = X[label_ == cluster_j, :]
        X_i_mean = X_i.mean(axis=0)
        x_j_mean = X_j.mean(axis=0)
        return np.sqrt(((X_i_mean - x_j_mean) ** 2).sum())
    DBI = 0
    # 迭代每个簇,计算每个簇的DB指数,然后求平均值
    for i in range(cluster):
        dis_list = []
        for j in range(cluster):
            if i != j:
                dis_list.append((avg_C(i) + avg_C(j)) / d_cen(i, j))
        DBI += max(dis_list)
    return DBI / cluster
def distance(center, x):
    """
     * 描述: 计算每个样本到簇中心的距离
     * 参数:
            center:簇中心,形状为(10,5)10个簇,5个特征属性
            x:数据样本,形状(100,5),100个样本,5个特征
     * 返回值: 返回每个样本到各个簇中心的距离,形状为(100,10),每一行代表每个样本到各个簇的距离
    """
    matrix = np.random.rand(x.shape[0], center.shape[0])
    # 迭代每一行,进行计算到各个簇中心的距离
    for i, row in enumerate(x):
        matrix[i, :] = np.sum((row - center) ** 2, axis=1)  # 平方差,然后按照每一行进行求和
    return matrix
def update_cluster(matrix):
    """
     * 描述: 更新每个样本所属的簇分类
     * 参数: matrix就是样本到簇中心的距离矩阵
     * 返回值:
    """
    global label_
    # 返回每行的最小值的下标,即返回距离最近的簇中心所属的类别
    label_ = np.argmin(matrix, axis=1)
def update_center(x):
    """
     * 描述: 更新每个簇的中心
     * 参数: x,样本数据
     * 返回值:
    """
    new_center = np.zeros((cluster, x.shape[1]))
    # 依次迭代每个类别下的数据,计算该类数据的均值
    for category in range(cluster):
        new_center[category, :] = x[label_ == category, :].mean(axis=0)
    return new_center
if __name__ == "__main__":
    run(X)  # 调用算法
    draw(X, y, best_label, cluster)  # 将聚类结果可视化

目录
相关文章
|
23天前
|
机器学习/深度学习 算法 Python
机器学习特征筛选:向后淘汰法原理与Python实现
向后淘汰法(Backward Elimination)是机器学习中一种重要的特征选择技术,通过系统性地移除对模型贡献较小的特征,以提高模型性能和可解释性。该方法从完整特征集出发,逐步剔除不重要的特征,最终保留最具影响力的变量子集。其优势包括提升模型简洁性和性能,减少过拟合,降低计算复杂度。然而,该方法在高维特征空间中计算成本较高,且可能陷入局部最优解。适用于线性回归、逻辑回归等统计学习模型。
76 7
|
21天前
|
机器学习/深度学习 数据可视化 TensorFlow
Python 高级编程与实战:深入理解数据科学与机器学习
本文深入探讨了Python在数据科学与机器学习中的应用,介绍了pandas、numpy、matplotlib等数据科学工具,以及scikit-learn、tensorflow、keras等机器学习库。通过实战项目,如数据可视化和鸢尾花数据集分类,帮助读者掌握这些技术。最后提供了进一步学习资源,助力提升Python编程技能。
|
23天前
|
机器学习/深度学习 数据可视化 算法
Python 高级编程与实战:深入理解数据科学与机器学习
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化和调试技巧。本文将深入探讨 Python 在数据科学和机器学习中的应用,并通过实战项目帮助你掌握这些技术。
|
1月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于机器学习的人脸识别算法matlab仿真,对比GRNN,PNN,DNN以及BP四种网络
本项目展示了人脸识别算法的运行效果(无水印),基于MATLAB2022A开发。核心程序包含详细中文注释及操作视频。理论部分介绍了广义回归神经网络(GRNN)、概率神经网络(PNN)、深度神经网络(DNN)和反向传播(BP)神经网络在人脸识别中的应用,涵盖各算法的结构特点与性能比较。
|
1月前
|
机器学习/深度学习 数据可视化 算法
Python与机器学习:使用Scikit-learn进行数据建模
本文介绍如何使用Python和Scikit-learn进行机器学习数据建模。首先,通过鸢尾花数据集演示数据准备、可视化和预处理步骤。接着,构建并评估K近邻(KNN)模型,展示超参数调优方法。最后,比较KNN、随机森林和支持向量机(SVM)等模型的性能,帮助读者掌握基础的机器学习建模技巧,并展望未来结合深度学习框架的发展方向。
58 9
Python与机器学习:使用Scikit-learn进行数据建模
|
2月前
|
机器学习/深度学习 算法 网络安全
CCS 2024:如何严格衡量机器学习算法的隐私泄露? ETH有了新发现
在2024年CCS会议上,苏黎世联邦理工学院的研究人员提出,当前对机器学习隐私保护措施的评估可能存在严重误导。研究通过LiRA攻击评估了五种经验性隐私保护措施(HAMP、RelaxLoss、SELENA、DFKD和SSL),发现现有方法忽视最脆弱数据点、使用较弱攻击且未与实际差分隐私基线比较。结果表明这些措施在更强攻击下表现不佳,而强大的差分隐私基线则提供了更好的隐私-效用权衡。
72 14
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
解锁机器学习的新维度:元学习的算法与应用探秘
元学习作为一个重要的研究领域,正逐渐在多个应用领域展现其潜力。通过理解和应用元学习的基本算法,研究者可以更好地解决在样本不足或任务快速变化的情况下的学习问题。随着研究的深入,元学习有望在人工智能的未来发展中发挥更大的作用。
|
5月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
168 3
|
8月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【7月更文挑战第22天】在大数据领域,Python算法效率至关重要。本文深入解析时间与空间复杂度,用大O表示法衡量执行时间和存储需求。通过冒泡排序(O(n^2)时间,O(1)空间)与快速排序(平均O(n log n)时间,O(log n)空间)实例,展示Python代码实现与复杂度分析。策略包括算法适配、分治法应用及空间换取时间优化。掌握这些,可提升大数据处理能力,持续学习实践是关键。
190 1
|
9月前
|
存储 机器学习/深度学习 算法
Python算法基础教程
Python算法基础教程
59 0

热门文章

最新文章