k-means聚类算法实现

聚类算法简介

在未知模式识别问题中,通常需要从一堆没有标签的数据中找到其中的关联性。一是要发现数据之间的相似性,也被称为聚类(Clustering);二是要统计数据在空间上的分布,也就是密度估计。聚类可谓无监督学习中最重要的一个作用。

聚类的定义

聚类是将集中具有相似特性的数据分类组织的过程,聚类技术是一种无监督学习。聚类又称为群分析,是研究样本或指标分类问题的一种统计分析方法。聚类与分类的区别是其要划分的类是未知的,常用的聚类分析法中有系统聚类法、有序样本聚类法、动态聚类法、模糊聚类法、图论聚类法和聚类预报法等。

K-means算法概述

K-means聚类算法是基于距离的非层次聚类算法,在最小化误差函数的基础上将数据划分为预定的类别数K,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度越大。
1.首先确定常数K,常数K为最终的聚类类别数。
2.从n个样本中随机选定K个对象作为初始的质心(聚类中心)。
3.计算每个样本与质心的相似度,即通过欧式距离等公式计算每个样本到各个质心的距离,将样本点归到最相似也即最近的类中。
4.重新计算每个类的质心。
5.与前一次计算得到的K个质心比较,如果质心发生变化转至步骤3,否则转至步骤6。
6.当质心不再发生变化时,停止并输出聚类结果。

K-Means聚类算法的结果可能依赖于初始聚类中心的随机选择,使得结果严重偏离全局最优分类。实践中,为了得到较好的结果,通常选择不同的初始聚类中心,多次运行K-Means算法。由于每次都要计算所有样本与每个质心之间的相似度,因此在大规模的数据集上,K-Means算法收敛速比较慢。

K-Means算法实现

数据集为客户销毁行为特征数据,其中R代表平均消费间隔天数,F代表消费的次数,M代表消费的金额。数据集可从以下百度网盘中获得:
链接: https://pan.baidu.com/s/1-G7gb-ZipnCM7IyKAZtcXA
提取码: 4qfk 。

在数据预处理环节,使用z-score 标准化方法。即零 - 均值标准化(常用方法)
y=(x-μ)/σ 是一种统计的处理,基于正态分布的假设,将数据变换为均值为 0、标准差为 1 的标准正态分布。但即使数据不服从正态分布,也可以用此法。特别适用于数据的最大值和最小值未知,或存在孤立点。
使用sklearn进行实现:

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import pandas as pd
# 参数初始化
inputfile = 'data/consumption_data.xls'  # 销量及其他属性数据
outputfile = 'data/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
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration,random_state=1234)
# 分为k类,并发数4,迭代次数为500
model.fit(data_zs)  # 开始聚类
#print(model.labels_) 代表分类编号。
# 简单打印结果
r1 = pd.Series(model.labels_).value_counts()  # 统计各个类别的数目
#print(r1)
r2 = pd.DataFrame(model.cluster_centers_)  # 找出聚类中心
#print(r2)
#print([r2, r1])
r = pd.concat([r2, r1], axis = 1)  # 横向连接(0是纵向),得到聚类中心对应的类别下的数目
print(r)
r.columns = list(data.columns) + ['类别数目']  # 重命名表头



# 详细输出原始数据及其类别
r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1)   # 详细输出每个样本对应的类别
r.columns = list(data.columns) + ['聚类类别']  # 重命名表头

print(r.columns)
r.to_excel(outputfile)  # 保存结果




def density_plot(data):  # 自定义作图函数
  import matplotlib.pyplot as plt
  plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
  plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
  p = data.plot(kind='kde', linewidth = 2, subplots = True, sharex = False)
  [p[i].set_ylabel(u'密度') for i in range(k)]
  plt.legend()
  return plt

for i in range(k):
  density_plot(data[r[u'聚类类别']==i])
  plt.show()

from sklearn.manifold import TSNE
tsne = TSNE(random_state=105)
tsne.fit_transform(data_zs)#进行数据降维
tsne = pd.DataFrame(tsne.embedding_,index=data_zs.index)#转换数据格式

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False  #用来正常显示负号
#不同类别用不同颜色和样式绘图
d = tsne[r['聚类类别']==0]
plt.plot(d[0],d[1],'r.')
d = tsne[r['聚类类别']==1]
plt.plot(d[0],d[1],'go')
d = tsne[r['聚类类别']==2]
plt.plot(d[0],d[1],'b*')
plt.show()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值