挖掘建模之K-means聚类算法

定义

K-Means算法(K-均值聚类)是典型的基于距离的非层次聚类算法,在最小化误差函数的基础上将数据划分为预定的类数K,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度越大。

算法过程

  • 从N个样本数据中随机选取K个对象作为初始的聚类中心
  • 分别计算每个样本到各聚类中心的距离,将对象分配到距离最近的聚类中
  • 所有对象分配完成之后,重新计算K个聚类的中心
  • 与前一次计算得到的K个聚类中心比较,如果聚类中发生变化,则转回过程2,否则转至过程5
  • 当质心不在发生变化时停止并输出聚类结果

在实践中,通常会选择不同的初始聚类中心,多次运行K-Means算法。目的是为了预防聚类结果依赖于初始聚类中心的随机选择而导致结果严重偏离全局最有分类。

距离公式

对于连续属性,要先对各属性值进行零-均值规范,再进行距离的计算。
样本与簇之间的距离可以用样本到簇中心的距离 d ( e i , x ) d(e_i,x) d(ei,x);簇与簇之间的距离可以用簇中心的距离 d ( e i , e j ) d(e_i,e_j) d(ei,ej)
用p个属性来表示n个样本的数据矩阵: [ x 11 ⋯ x 1 p ⋮ ⋱ ⋮ x n 1 ⋯ x n p ] \begin{bmatrix} x_{11} & \cdots & x_{1p}\\ \vdots & \ddots &\vdots \\ x_{n1} & \cdots & x_{np} \end{bmatrix} x11xn1x1pxnp

  • 欧几里得距离:
    d ( i , j ) = ( x i 1 − x j 1 ) 2 + ( x i 2 − x j 2 ) 2 + . . . + ( x i p − x j p ) 2 d\left ( i,j \right )=\sqrt{(x_{i1}-x_{j1})^2 +(x_{i2}-x_{j2})^2+...+(x_{ip}-x_{jp})^2} d(i,j)=(xi1xj1)2+(xi2xj2)2+...+(xipxjp)2

  • 曼哈顿距离:
    d ( i , j ) = ∣ x i 1 − x j 1 ∣ + ∣ x i 2 − x j 2 ∣ + . . . + ∣ x i p − x j p ∣ d\left ( i,j \right )=|x_{i1}-x_{j1}| +|x_{i2}-x_{j2}|+...+|x_{ip}-x_{jp}| d(i,j)=xi1xj1+xi2xj2+...+xipxjp

  • 闵可夫斯基距离:
    d ( i , j ) = ( ∣ x i 1 − x j 1 ∣ ) 2 + ( ∣ x i 2 − x j 2 ∣ ) 2 + . . . + ( ∣ x i p − x j p ∣ ) 2 q d\left ( i,j \right )=\sqrt[q]{(|x_{i1}-x_{j1}|)^2 +(|x_{i2}-x_{j2}|)^2+...+(|x_{ip}-x_{jp}|)^2} d(i,j)=q(xi1xj1)2+(xi2xj2)2+...+(xipxjp)2

q为正整数,q=1时即为曼哈顿距离;q=2时即为欧几里得距离。

对于文档数据使用余弦相似量,先将文档数据转化为文档-词矩阵格式,如下表所示
挖掘建模之K-means聚类算法_第1张图片
两文档之间的相似度的计算公式为:
d ( i , j ) = c o s ( i , j ) = i ⃗ ⋅ j ⃗ ∣ i ∣ ⃗ ∣ j ∣ ⃗ d(i,j) = cos(i,j) = \frac{\vec{i} \cdot \vec{j}}{\vec{|i|}\vec{|j|}} d(i,j)=cos(i,j)=i j i j

目标函数

使用误差平方和SSE作为度量聚类质量的目标函数

  • 连续属性的SSE计算公式为:
    S S E = ∑ i = 1 k ∑ x ϵ E i d i s t ( e i , x ) 2 SSE = \displaystyle\sum_{i=1}^{k}\displaystyle\sum_{x\epsilon E_i} dist(e_i,x)^2 SSE=i=1kxϵEidist(ei,x)2
  • 文档数据的SSE计算公式为:
    S S E = ∑ i = 1 k ∑ x ϵ E i c o s ( e i , x ) 2 SSE = \displaystyle\sum_{i=1}^{k}\displaystyle\sum_{x\epsilon E_i} cos(e_i,x)^2 SSE=i=1kxϵEicos(ei,x)2
  • E i E_i Ei的聚类中心 e i e_i ei计算公式为:
    e i = 1 n i ∑ x ϵ E i x e_i = \frac{1}{n_i}\displaystyle\sum_{x\epsilon E_i}x ei=ni1xϵEix

符号说明

符号 含义 符号 含义
K 聚类簇的个数 e i e_i ei E i E_i Ei的聚类中心
E i E_i Ei 第i个簇 n i n_i ni 第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)

运行结果:
挖掘建模之K-means聚类算法_第2张图片

你可能感兴趣的:(K-means,聚类算法)