1 小序
聚类分析最早起源于分类学,初期人们依靠经验将某类事件的集合分为若干子集.随科技发展,数学工具被引入到分类学,聚类算法被归入到数值分类学领域,大数据时代到来,数据结构的复杂性和内容的多元化为聚类提出了新的要求,于是多元分析技术被引入数值分析学,形成了聚类分析学.
聚类(Cluster),即按照某个特定标准(如距离准则)将一个数据集分成不同的类或簇,使同一个簇内的数据对象相似性尽可能大,同事不在同一簇中数据对象的差异性尽可能大.聚类后同一类数据尽可能聚集到一起,不同数据尽量分离.
2 分类方法
2.1 传统分类
- 划分聚类
- 层次聚类
- 密度聚类
- 网格聚类
2.2 现代分类
- 模糊聚类
- 量子聚类
- 谱聚类
3 划分聚类
- 环境
- Ubuntu18.04
- Python2.7
- matplotlib
- numpy
划分聚类属于硬聚类,将给定的数据集初始分为k个簇,每个簇至少包含一条数据记录,然后通过反复迭代至每个簇不再改变即得到聚类结果.
3.1 K-means算法
即K均值算法,假设原始数据集合D{
x
1
,
x
2
,
.
.
.
,
x
n
x_1,x_2,...,x_n
x1,x2,...,xn},每个
x
i
x_i
xi为d维向量,K-means聚类将给定分类组数k(k<=n)值的条件下,将原始数据分成k类,S={
S
1
,
S
2
,
.
.
.
,
S
k
S_1,S_2,...,S_k
S1,S2,...,Sk},在数值模型上,最小值:
m
i
n
S
∑
i
=
1
k
∑
x
j
ϵ
S
i
∣
∣
x
j
−
μ
i
∣
∣
2
min_S\sum_{i=1}^{k}\sum_{x_j\epsilon{S_i}}||x_j-μ_i||^2
minSi=1∑kxjϵSi∑∣∣xj−μi∣∣2
其中,
μ
i
μ_i
μi表示分类
S
i
S_i
Si的平均值.
3.2 步骤
从D中随机取k个元素,作为k个簇的中心;
分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇;
根据聚类结果,重新计算k个簇各自的中心,即取簇中所有元素各自维度的算数平均值;
将D中全部数据按照新的中心重新聚类;
重复(4),直至聚类结果不再变化;
输出结果;
3.3 源码
# 源数据处理
from numpy import *
import matplotlib.pyplot as plt
# 加载数据
data = open('data.txt')
# 源数据列表
datas = []
for line in data.readlines():
# 行数据拆分
# 格式为['1.65', '4.28']
axisData = line.strip().split('\t')
# 列表数据转为float类型
# [1.65, 4.28]
axisDatass = map(float, axisData)
# 存储数据
datas.append(axisDatas)
# 源数据矩阵
datasMat = mat(datas)
# 获取源数据维度
m = shape(datasMat[0])
n = shape(datasMat[1])
# 生成聚类矩阵
# 存储聚类结果,第一列为元素所在组,第二列为元素到中心点的距离
clusterAssment = mat(zeros((m, n)))
# 生成中心点矩阵,4为种类,2为源数据列数
centroids = mat(zeros((4, 2)))
# 获取源数据最大值与最小值坐标
minJ0 = min(datasMat[:, 0])
minJ1 = min(datasMat[:, 1])
maxJ0 = max(datasMat[:, 0])
maxJ1 = max(datasMat[:, 1])
rangeJ0 = float(maxJ0 - minJ0)
rangeJ1 = float(maxJ1 - minJ1)
# 随机生成中心点
centroids[:, 0] = minJ0 + rangeJ0 * random.rand(4, 1)
centroids[:, 1] = minJ1 + rangeJ1 * random.rand(4, 1)
# 迭代标志位
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(20):
minDistance = inf
minIndex = -1
for j in range(4):
# 计算中心点与各点的距离
distance = sqrt(sum(power(centroids[j,:] - datasMat[i, :], 2)))
if distance < minDistance:
# 更新距离,找到最小距离
minDistance = distance
# 依据最小距离聚类,记录所在的组号
minIndex = j
# 若聚类发生改变,继续迭代
if clusterAssment[i, 0] != minIndex:
clusterChanged = True
# 结果:分类结果
clusterAssment[i, :] = minIndex, minDistance**2
# 结果:中心点
for center in range(4):
pointsCluster = datasMat[nonzero(clusterAssment[:, 0].A == center)[0]]
centroids[center, :] = mean(pointsCluster, axis=0)
# 打印聚类结果:中心点及聚类结果
print("Center of points: {}".format(centroids))
print("Cluster result: {}".format(clusterAssment))
# 源数据各点的分类及到中心点的距离
# 第一列为组别,第二列为各点到中心点的距离
# 获取第一列为组别标签
label = clusterAssment[:, 0].tolist()
# 绘图点形状及颜色,依据组别绘制不同颜色
mark = ['or', 'ob', 'og', 'oy', '^r', '+r', 'sr', 'dr', '<r', 'pr']
# 中心点形状及颜色
color = ['*r', '*b', '*g', '*y']
j = 0
for i in range(4):
plt.plot(centroids[i,0], centroids[i, 1],color[i] ,markersize=12)
# label为列表形式[[0.0],[1.0]]
# 使用需要提取数字,并转为int
for i in label:
plt.plot(datasMat[j,0], datasMat[j, 1], mark[int(i[0])], markersize=5)
j += 1
# plt.scatter()
plt.show()
3.4 结果
图2.1为聚类结果
3.5 K-means优点及缺点
- 优点
(1) 算法简单,速度快;
(2) 处理大数据集合,该算法是相对可伸缩和高效的;
(3) 算法尝试找出使平方误差函数值最小的k个划分; - 缺点
(1) K-means聚类只有在簇的平均值被定义情况下使用;
(2) 需事先确定生成簇k的数量,即需要聚成几类;
(3) 对初值敏感;
(4) 不适合发现非凸面形状的簇,或大小差别很大的簇;
(5) 对"噪声"和孤立点数据敏感;
4 应用
- 模式识别: 语音识别,字符识别
- 机器学习: 图像分割,机器视觉
- 图像处理: 数据压缩,信息检索
- 数据挖掘: 关系数据挖掘,时空数据挖掘(GIS等),序列和异类数据分析
[参考文献]
[1]https://wenku.baidu.com/view/9331e8e8dd88d0d232d46a53.html?from=search
[2]https://wenku.baidu.com/view/aa46a2737375a417866f8fcb.html?from=search
[3]https://blog.csdn.net/u010212101/article/details/78264631/
[4]https://www.cnblogs.com/ahu-lichang/p/7161613.html