赞
踩
所谓聚类问题,就是给定一个元素集合 D,其中每个元素具有 n 个可观察属性,使用某 种算法将 D 划分成 k 个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的 元素相异度尽可能高。其中每个子集叫做一个簇。与分类不同,分类是示例式学习,要求分 类前明确各个类别,并断言每个元素映射到一个类别,而聚类是观察式学习,在聚类前可以 不知道类别甚至不给定类别数量,是无监督学习的一种。目前聚类广泛应用于统计学、生物 学、数据库技术和市场营销等领域,如:
在商务上,聚类能帮助市场分析人员从客户基本库中发现不同的客户群,并且用不同的 购买模式来刻画不同的消费群体的特征
给定医学数据,通过肿瘤的大小来预测该肿瘤是恶性瘤还是良性瘤,这就是一个聚类问 题,它的输出是 0 或者 1 两个离散的值。(0 代表良性,1 代表恶性)
在生物学上,聚类能用于帮助推导植物和动物的种类,基因和蛋白质的分类,获得对种 群中固定结构的认识
聚类在地球观测数据中相似地区的确定,根据房屋的类型、价值和位置对一个城市中房 屋的分类发挥作用
聚类也能用来对 web 上的文档进行分类,以发现有用的信息。聚类分析能作为一种独立 的工具来获得数据分布的情况,观察每个簇的特点,并对某些特定的节点进一步分析
为此,相应的算法也非常多。本文仅介绍一种最简单的聚类算法——k 均值(k-means) 算法
K-Means 聚类原理:
K-Means 聚类原理概述:
1、从 D 中随机取 k 个元素,作为 k 个簇的各自的中心(质心)
2、分别计算剩下的元素到 k 个簇中心的相异度,将这些元素分别划归到相异度最低的簇
3、根据聚类结果,重新计算 k 个簇各自的中心,计算方法是取簇中所有元素各自维度 的算术平均数
4、将 D 中全部元素按照新的中心重新聚类
5、重复第 4 步,直到聚类结果不再变化
6、将结果输出, n: 元素个数,k:第一步中选取的元素个数,m: 每个元素的特征项个数,T: 第 5 步中 迭代的次数
案例说明:通过给定的超市顾客购物信息,可以按照顾客的消费水平,运用聚类算法, 将顾客分为三种等级
表 xx 超市顾客购物信息表
客户年龄 | 平均每次消费金额 | 平均消费周期(天) |
---|---|---|
23 | 317 | 10 |
22 | 147 | 13 |
24 | 172 | 17 |
27 | 194 | 67 |
37 | 789 | 35 |
超市顾客聚类结果展示:
sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)
表 xx KMeans 函数参数说明
参数名称 | 说明 |
---|---|
n_clusters | 接收 int,表示开始的聚类中心的数量 |
init | 初始化聚类中心的算法方式,默认为’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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。