挖掘建模之K-means聚类算法
定义
该算法采用基于距离的方法进行非层次聚类分析;通过最小化误差函数将数据划分为预先设定的数量K;以距离作为衡量对象间相似程度的标准;意味着被考察的对象之间的距离越近,则其相似程度越高。
算法过程
- 首先,在包含N个样本的数据集中随机抽取K个样本作为初始的聚类核心位置
- 对每一个样本计算其至各个预设核心位置的距离值
- 将所有待分类样本全部分配完毕后
- 计算当前各核心位置对应的最终核心坐标值
- 将新的核心坐标设置与上一轮迭代的结果进行对比分析
- 直到新旧核心坐标稳定不再发生变动时为止
在实践中普遍采用的方式是通过多轮运行K-Means算法来选择不同的初始聚类中心以增强算法的效果和稳定性。其主要目标是尽量避免由于初始聚类中心随机选择所带来的影响从而确保算法收敛到较为合理的解上
距离公式
在处理连续属性时,在对各属性值执行零均值化处理的基础上完成后续的计算步骤
欧几里得距离:
d\left ( i,j \right )=\sqrt{(x_{i1}-x_{j1})^2 +(x_{i2}-x_{j2})^2+...+(x_{ip}-x_{jp})^2}
曼哈顿距离:
d\left ( i,j \right )=|x_{i1}-x_{j1}| +|x_{i2}-x_{j2}|+...+|x_{ip}-x_{jp}|
闵可夫斯基距离:
d\left ( i,j \right )=\sqrt[q]{(|x_{i1}-x_{j1}|)^2 +(|x_{i2}-x_{j2}|)^2+...+(|x_{ip}-x_{jp}|)^2}
q为正整数,q=1时即为曼哈顿距离;q=2时即为欧几里得距离。
在处理文档数据时,应用余弦相似度量。首先需将这些文档转换为基于词的矩阵表示,请参考表1。

两个文档之间计算它们的相似程度的方法涉及使用余弦相似度来评估两个向量之间的角度。数学表达式为:d(i,j) = cosθ = \frac{\vec{i} \cdot \vec{j}}{|\vec{i}| |\vec{j}|}
目标函数
使用误差平方和SSE作为度量聚类质量的目标函数
- 基于连续型属性的SSE计算公式是:
SSE = \displaystyle\sum_{i=1}^{k}\displaystyle\sum_{x \in E_i} d(e_i, x)^2
表示为文档数据的SSE计算公式的数学表达式
- 簇E_i的聚类中心e_i计算公式为:
e_i = \frac{1}{n_i}\displaystyle\sum_{x\epsilon E_i}x
符号说明
| 符号 | 含义 | 符号 | 含义 |
|---|---|---|---|
| K | 聚类簇的个数 | e_i | 簇E_i的聚类中心 |
| E_i | 第i个簇 | n_i | 第i个簇中样本的个数 |
| x | 对象(样本) |
代码说明
# !/usr/bin/python3
# coding=gbk
# @Time: 2019/5/7 10:55
import pandas as pd
# 参数初始化
inputfile = '../data/5-3 consumption_data.xls'
outputfile = '../tmp/data_type.xls'
# 聚类的类别(聚类的个数)
k = 3
# 聚类最大的循环次数
iteration = 500
data = pd.read_excel(inputfile, index_col='Id')
# 数据标准化
data_zs = 1.0 * (data - data.mean())/data.std()
from sklearn.cluster import KMeans
# 分为k类,并发数为4
model = KMeans(n_clusters=4, n_jobs=4, max_iter=iteration)
# 开始聚类
model.fit(data_zs)
# 简单打印结果
r1 = pd.Series(model.labels_).value_counts() # 统计各类别的数目
r2 = pd.DataFrame(model.cluster_centers_) # 找出聚类中心
# 横向连接(0是纵向),得到聚类中心对应的类别下的数目
r = pd.concat([r2, r1], axis=1)
# 重命名表头
r.columns = list(data.columns) + [u'类别数目']
print(r)
# 详细输出原始数据及其类别
# 详细输出每个样本对应的类别
r = pd.concat([data, pd.Series(model.labels_, index=data.index)], axis=1)
# 重命名表头
r.columns = list(data.columns) +[u'聚类类别']
# 保存结果
r.to_excel(outputfile)
运行结果:

