【机器学习】Python详细实现基于欧式Euclidean、切比雪夫Chebyshew、曼哈顿Manhattan距离的Kmeans聚类

简介: 文章详细实现了基于不同距离度量(欧氏、切比雪夫、曼哈顿)的Kmeans聚类算法,并提供了Python代码,展示了使用曼哈顿距离计算距离矩阵并输出k=3时的聚类结果和轮廓系数评价指标。

1 算法过程

(1)随机选取K个簇中心点

(2)通过计算每个样本与每个簇中心点的距离,选择距离最小的簇心,将样本归类到该簇心的簇中

屏幕快照 2024-08-05 上午9.22.15.png

这里距离可以使用欧几里得距离(Euclidean Distance)、余弦距离(Cosine Distance)、切比雪夫距离(Chebyshew Distance)或曼哈顿距离(Manhattan Distance),计算距离之前需要先对特征值进行标准化。

3、在已经初次分配的簇中,计算该簇中所有向量的均值,作为该的簇中心点

4、重复步骤2和3来进行一定数量的迭代,直到簇中心点在迭代之间变化不大

评价指标

轮廓系数(Silhouette Coefficient),是聚类效果好坏的一种评价方式。 轮廓系数的值是介于 [-1,1] ,越趋近于1代表内聚度和分离度都相对较优。

2 实现

2.1 Python代码

# kmeans算法
#  1. 初始化k个族中心
#  2. 计算每个样本与k个族中心距离,标记样本为距离最短的族
#  3. 重新确定K族中心(族中平均位置)
#  4. 循环2-3,直到前后两次所有族中心距离变化<eps
"""
# 输入:
    X: 2d数组, 形如(n_samples, m_features),n_samples表示样本数,m_features表示特征维数
    K: int, 超参数,指定族格式
    metric:str, 距离类型,默认为欧式距离'Euler',其他暂时为实现
    eps: float, 精度(当族中心位置更新变化<eps时停止)
    random_state: 随机种子    
# 输出:
    centers: K族中心向量, 2d数组, 形如(K, m_features)
    pred: 1-d数组,长度为n_samples 
"""

import numpy as np
import random   # 用python的random模块,不用numpy的random
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from scipy.spatial.distance import pdist
from sklearn.preprocessing import StandardScaler

class kmeans:  # 创建kmeans类

    # 初始化函数
    def __init__(self, X=None, K=2, metric='Euler',eps=1e-6, init_centers=None, random_state=None):
        self.X = X
        self.K = K
        self.metric = metric
        self.eps = eps
        self.centers = init_centers
        self.random_state = random_state


    # 距离函数
    def calc_dist(self, x, c):
        dist_list = []
        for i in range(c.shape[0]):
            v = c[i]
            # 欧式距离
            if self.metric == 'Euler':
                lp = 2
                distance = np.power(np.power(x-v, lp), 1/lp).sum()
                dist_list.append(distance)
            # 切比雪夫距离
            elif self.metric == 'Chebyshew':
                distance = abs((x)-v).max()
                dist_list.append(distance)
            # 曼哈顿距离
            elif self.metric == 'Manhattan':
                distance = sum(abs(x-v))
                dist_list.append(distance)
            # jaccard距离
            elif self.metric == 'Jaccard':
                matV = np.vstack([x, v])
                distance = pdist(matV, 'jaccard')
                dist_list.append(distance)
            # 余弦距离
            elif self.metric == 'Cosine':
                distance = np.dot(x, v) /(np.linalg.norm(x)*np.linalg.norm(v))
                dist_list.append(distance)
        return dist_list

    # 迭代(训练)
    def fit(self, X):
        # 样本
        if X is not None:
            self.X = X
        # 样本形状
        n_samples, n_features = self.X.shape

        # 设置随机种子
        if self.random_state is not None:
            random.seed(self.random_state)

        # 初始化聚类中心
        if self.centers is None:
            # 随机选取簇心(这点可改进,比如kmeans++就是在此改进的)
            idx = idx = random.sample(range(n_samples), self.K)
            self.centers = X[idx, :]

        # 初始样本的族标记-1
        pred = np.array([-1]*n_samples)

        iter = 0
        stop = False  # 结束标志
        while (not stop):
            iter += 1
            print(iter)
            for i in range(n_samples):
                dists = self.calc_dist(X[i, :], self.centers)
                pred[i] = np.argmin(dists)

            # 重新确定族中心
            new_centers = np.zeros((self.K, n_features))
            for k in range(self.K):
                new_centers[k, :] = X[pred == k, :].mean(axis=0)

            # 判断停止条件
            delta = abs(new_centers - self.centers)
            flg = delta < self.eps
            stop = flg.all()
            self.centers = new_centers

        return pred, self.centers

    # 族预测
    def predict(self, X):
        # 遍历所有样本,划分族
        pred = np.array([-1]*n_samples)
        for i in range(n_samples):
            dists = self.calc_dist(X[i, :], self.centers)
            pred[i] = np.argmin(dists)
        return pred

if __name__ == "__main__":

    # 生成数据
    n_samples = 1500
    random_state = 170
    X, y = make_blobs(n_samples=n_samples, random_state=random_state)

    # 调用kmeans
    metric_dist = 'Cosine'
    model = kmeans(X, K=3, metric=metric_dist, eps=1e-3, random_state=1)

    ss = StandardScaler()
    X_n = ss.fit_transform(X)
    pred, centers = model.fit(X_n)
    n_samples, _ = X.shape
    # 评价指标:轮廓系数,【-1 1】越接近1 ,聚类效果越好
    score = silhouette_score(X, pred)

    # 族预测,如果仅是训练数据,直接用fit(X)返回的族划分
    # pred = model.predict(X)
    plt.scatter(X[:, 0], X[:, 1], c=pred)
    plt.title("{}—kmeans".format(metric_dist))
    plt.show()
    print()

2.2 实验结果

(1)曼哈顿距离

轮廓系数:0.7333423486262539

1.png

(2)切比雪夫距离

轮廓系数0.7333423486262539

2.png

(3)欧式距离

轮廓系数:0.7333423486262539

3.png

目录
相关文章
|
1月前
|
机器学习/深度学习 数据采集 算法
【CNN-BiLSTM-attention】基于高斯混合模型聚类的风电场短期功率预测方法(Python&matlab代码实现)
【CNN-BiLSTM-attention】基于高斯混合模型聚类的风电场短期功率预测方法(Python&matlab代码实现)
106 4
|
6月前
|
机器学习/深度学习 算法 Python
机器学习特征筛选:向后淘汰法原理与Python实现
向后淘汰法(Backward Elimination)是机器学习中一种重要的特征选择技术,通过系统性地移除对模型贡献较小的特征,以提高模型性能和可解释性。该方法从完整特征集出发,逐步剔除不重要的特征,最终保留最具影响力的变量子集。其优势包括提升模型简洁性和性能,减少过拟合,降低计算复杂度。然而,该方法在高维特征空间中计算成本较高,且可能陷入局部最优解。适用于线性回归、逻辑回归等统计学习模型。
242 7
|
4月前
|
机器学习/深度学习 人工智能 算法
Scikit-learn:Python机器学习的瑞士军刀
想要快速入门机器学习但被复杂算法吓退?本文详解Scikit-learn如何让您无需深厚数学背景也能构建强大AI模型。从数据预处理到模型评估,从垃圾邮件过滤到信用风险评估,通过实用案例和直观图表,带您掌握这把Python机器学习的'瑞士军刀'。无论您是AI新手还是经验丰富的数据科学家,都能从中获取将理论转化为实际应用的关键技巧。了解Scikit-learn与大语言模型的最新集成方式,抢先掌握机器学习的未来发展方向!
738 12
Scikit-learn:Python机器学习的瑞士军刀
|
10月前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
1032 6
|
7月前
|
机器学习/深度学习 数据可视化 算法
Python与机器学习:使用Scikit-learn进行数据建模
本文介绍如何使用Python和Scikit-learn进行机器学习数据建模。首先,通过鸢尾花数据集演示数据准备、可视化和预处理步骤。接着,构建并评估K近邻(KNN)模型,展示超参数调优方法。最后,比较KNN、随机森林和支持向量机(SVM)等模型的性能,帮助读者掌握基础的机器学习建模技巧,并展望未来结合深度学习框架的发展方向。
Python与机器学习:使用Scikit-learn进行数据建模
|
6月前
|
机器学习/深度学习 数据可视化 TensorFlow
Python 高级编程与实战:深入理解数据科学与机器学习
本文深入探讨了Python在数据科学与机器学习中的应用,介绍了pandas、numpy、matplotlib等数据科学工具,以及scikit-learn、tensorflow、keras等机器学习库。通过实战项目,如数据可视化和鸢尾花数据集分类,帮助读者掌握这些技术。最后提供了进一步学习资源,助力提升Python编程技能。
|
6月前
|
机器学习/深度学习 数据可视化 算法
Python 高级编程与实战:深入理解数据科学与机器学习
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化和调试技巧。本文将深入探讨 Python 在数据科学和机器学习中的应用,并通过实战项目帮助你掌握这些技术。
|
10月前
|
机器学习/深度学习 数据采集 数据可视化
Python数据科学实战:从Pandas到机器学习
Python数据科学实战:从Pandas到机器学习
|
10月前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
382 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
10月前
|
机器学习/深度学习 数据可视化 数据处理
掌握Python数据科学基础——从数据处理到机器学习
掌握Python数据科学基础——从数据处理到机器学习
164 0

推荐镜像

更多