K-Means 算法

本文深入探讨了K-Means聚类算法,包括算法原理、自实现、API使用、评估方法和实际案例。通过航空公司客户价值分析案例,展示了K-Means在客户分群和营销策略制定中的作用,强调了K-Means算法的聚类效果受类别数目影响,可能存在局部最优解的问题。
摘要由CSDN通过智能技术生成
一、聚类算法概念

所谓聚类问题,就是给定一个元素集合 D,其中每个元素具有 n 个可观察属性,使用某 种算法将 D 划分成 k 个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的 元素相异度尽可能高。其中每个子集叫做一个簇。与分类不同,分类是示例式学习,要求分 类前明确各个类别,并断言每个元素映射到一个类别,而聚类是观察式学习,在聚类前可以 不知道类别甚至不给定类别数量,是无监督学习的一种。目前聚类广泛应用于统计学、生物 学、数据库技术和市场营销等领域,如:

在商务上,聚类能帮助市场分析人员从客户基本库中发现不同的客户群,并且用不同的 购买模式来刻画不同的消费群体的特征

给定医学数据,通过肿瘤的大小来预测该肿瘤是恶性瘤还是良性瘤,这就是一个聚类问 题,它的输出是 0 或者 1 两个离散的值。(0 代表良性,1 代表恶性)

在生物学上,聚类能用于帮助推导植物和动物的种类,基因和蛋白质的分类,获得对种 群中固定结构的认识

聚类在地球观测数据中相似地区的确定,根据房屋的类型、价值和位置对一个城市中房 屋的分类发挥作用

聚类也能用来对 web 上的文档进行分类,以发现有用的信息。聚类分析能作为一种独立 的工具来获得数据分布的情况,观察每个簇的特点,并对某些特定的节点进一步分析

为此,相应的算法也非常多。本文仅介绍一种最简单的聚类算法——k 均值(k-means) 算法

二、K-Means 算法原理

K-Means 聚类原理:

在这里插入图片描述
在这里插入图片描述
K-Means 聚类原理概述:

1、从 D 中随机取 k 个元素,作为 k 个簇的各自的中心(质心)

2、分别计算剩下的元素到 k 个簇中心的相异度,将这些元素分别划归到相异度最低的簇

3、根据聚类结果,重新计算 k 个簇各自的中心,计算方法是取簇中所有元素各自维度 的算术平均数

4、将 D 中全部元素按照新的中心重新聚类

5、重复第 4 步,直到聚类结果不再变化

6、将结果输出, n: 元素个数,k:第一步中选取的元素个数,m: 每个元素的特征项个数,T: 第 5 步中 迭代的次数

三、K-Means 算法原理自实现

案例说明:通过给定的超市顾客购物信息,可以按照顾客的消费水平,运用聚类算法, 将顾客分为三种等级

表 xx 超市顾客购物信息表

客户年龄 平均每次消费金额 平均消费周期(天)
23 317 10
22 147 13
24 172 17
27 194 67
37 789 35

超市顾客聚类结果展示:

在这里插入图片描述

四、K-Means 算法 API

sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)

表 xx KMeans 函数参数说明

参数名称 说明
n_clusters 接收 int,表示开始的聚类中心的数量
init 初始化聚类中心的算法方式,默认为’k-means++’
五、K-Means 算法评估

如何去评估聚类的效果呢?

Kmeans 性能评估指标----轮廓系数

在这里插入图片描述
注意: 对于每个点i 为已聚类数据中的样本 ,b_i 为i 到其它族群的所有样本的距离最小值, a_i 为i 到本身簇的距离平均值。最终计算出所有的样本点的轮廓系数平均值

轮廓系数分析

在这里插入图片描述

(1)分析过程(我们以一个蓝 1 点为例) 计算出蓝 1 离本身族群所有点的距离的平均值 a_i 蓝 1 到其它两个族群的距离计算出平均值红平均,绿平均,取最小的那个距离作为b_i 根据公式:极端值考虑:如果b_i >> a_i : 那么公式结果趋近于 1;如果 a_i >> b_i : 那么公式结果趋近于-1

(2)结论: 如果b_i >> a_i :趋近于 1 效果越好, b_i << a_i :趋近于-1,效果不好。轮廓系数 的值是介于 [-1,1] ,越趋近于 1 代表内聚度和分离度都相对较优

(3)轮廓系数 API: sklearn.metrics.silhouette_score(X, labels)

计算所有样本的平均轮廓系数

X:特征值

labels:被聚类标记的目标值

代码实现:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from sklearn.cluster import KMeans

from sklearn.metrics import silhouette_score  # 轮廓系数


def min_max_sca(data):
    """
    离差标准化来标准化数据
    :param data: 需要标准化的数据
    :return: 标准化之后的数据
    """
    data = (data - data.min()) / (data.max() - data.min())

    return data


def build_data():
    """
    加载并处理数据
    :return: data
    """
    # 加载数据
    data = pd.read_csv('./company.csv', encoding='gbk')
    # print('data:\n', data)

    # 使用 平均每次消费金额 平均消费周期(天) 进行聚类
    # 筛选数据
    data = data.loc[:, ['平均每次消费金额', '平均消费周期(天)']]
    # print('data:\n', data)

    # 检测缺失值
    res_null = pd.isnull(data).sum()
    # print('缺失值检测结果:\n', res_null)

    # 异常值 ---无异常值

    # 标准化数据
    # 离差标准化
    for column in data.columns:
        data.loc[:, column] = min_max_sca(data.loc[:, column])
    # print('标准化之后的数据:\n', data)

    # 转化为 ndarray
    data = data.values

    # print('data:\n', data)

    return data


def center_init(data, k):
    """
    聚类中心初始化
    :param data: 数据
    :param k: 聚类的类别数目即聚类中心数目
    :return: center
    """
    # 获取data的行数
    index_num = data.shape[0]
    # 构建行下标数组
    index = np.arange(index_num)
    # 随机初始化聚类中心
    # 随机在 data 选中 k个样本 作为k个中心
    # 随机选择  k 行
    # 参数1: 选择的数组
    # 参数2:选择的数据的个数
    # replace=False 不重复
    mask = np.random.choice(index, k, replace=False)
    print('mask:\n', mask)

    # 筛选数据
    center = data[mask, :]
    # print('center:\n', center)

    return center


def distance(v1, v2):
    """
    利用欧式距离来计算两点之间的距离
    :param v1: 点1
    :param v2: 点2
    :return: dst
    """
    dst = np.sqrt(np.sum(np.power((v1 - v2), 2)))

    return dst


def k_means_owns(data, k):
    """
    自实现超市用户聚类
    :param data: 数据
    :param k: 聚类的类别
    :return: center, new_data
    """
    # 初始化聚类中心
    center = center_init(data, k)
    # 获取 data的行数
    index_num = data.shape[0]
    # 构建一个占位数组 --- (每一个样本的最小距离,该样本所属的簇的下标)
    new_data = np.zeros(shape=(index_num, 2))
    # 设置开关
    flag = True
    while flag:
        # 打开开关
        flag = False
        # 计算每一个样本与每一个聚类中心的距离
        for i in range(index_num):
            # i :代表的是样本的行下标
            # 构建一个 min_dst
            min_dst = 1000000
            #  构建一个 min_index(该样本最小的距离属于哪一个聚类中心)
            min_index = -1
            for j in range(k):
                # j 代表的是 聚类中心的行下标
                dst = distance(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值