博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python数据分析笔记:聚类算法之K均值
阅读量:5924 次
发布时间:2019-06-19

本文共 2831 字,大约阅读时间需要 9 分钟。

我们之前接触的所有机器学习算法都有一个共同特点,那就是分类器会接受2个向量:一个是训练样本的特征向量X,一个是样本实际所属的类型向量Y。由于训练数据必须指定其真实分类结果,因此这种机器学习统称为有监督学习

然而有时候,我们只有训练样本的特征,而对其类型一无所知。这种情况,我们只能让算法尝试在训练数据中寻找其内部的结构,试图将其类别挖掘出来。这种方式叫做无监督学习。由于这种方式通常是将样本中相似的样本聚集在一起,所以又叫聚类算法

下面我们介绍一个最常用的聚类算法:K均值聚类算法(K-Means)。

1K均值聚类

K-Means算法思想简单,效果却很好,是最有名的聚类算法。聚类算法的步骤如下:

1:初始化K个样本作为初始聚类中心;

2:计算每个样本点到K个中心的距离,选择最近的中心作为其分类,直到所有样本点分类完毕;

3:分别计算K个类中所有样本的质心,作为新的中心点,完成一轮迭代。

通常的迭代结束条件为新的质心与之前的质心偏移值小于一个给定阈值。

下面给一个简单的例子来加深理解。如下图有4个样本点,坐标分别为A(-1,-1),B(1,-1),C(-1,1),D(1,1)。现在要将他们聚成2类,指定A、B作为初始聚类中心(聚类中心A0, B0),指定阈值0.1。K-Means迭代过程如下:

step 1.1:计算各样本距离聚类中心的距离:

样本A:d(A,A0) = 0; d(A,B0) = 2;因此样本A属于A0所在类;

样本B:d(B,A0) = 2; d(B,B0) = 0;因此样本B属于B0所在类;

样本C:d(C,A0) = 2; d(C,B0) = 2.8;;因此样本C属于A0所在类;

样本C:d(D,A0) = 2.8; d(D,B0) = 2;;因此样本C属于B0所在类;

step 1.2:全部样本分类完毕,现在计算A0类(包含样本AC)和B0类(包含样本BD)的新的聚类中心:

A1 = (-1, 0); B1 = (1,0);

step 1.3:计算聚类中心的偏移值是否满足终止条件:

|A1-A0| = |(-1,0)-(-1,-1) | = |(0,1)| = 1 >0.1,因此继续迭代。

此时的状态如下图所示:

step 2.1:计算各样本距离聚类中心的距离:

样本A:d(A,A1) = 1; d(A,B1) = 2.2;因此样本A属于A1所在类;

样本B:d(B,A1) = 2.2; d(B,B1) = 1;因此样本B属于B1所在类;

样本C:d(C,A1) = 1; d(C,B1) = 2.2;;因此样本C属于A1所在类;

样本D:d(D,A1) = 2.2; d(D,B1) = 1;;因此样本C属于B1所在类;

step 2.2:全部样本分类完毕,现在计算A1类(包含样本AC)和B1类(包含样本BD)的新的聚类中心:

A2 = (-1, 0); B2 = (1,0);

step 2.3:计算聚类中心的偏移值是否满足终止条件:

|A2-A1| = |B2-B1| = 0 <0.1,因此迭代终止。

2、测试数据

下面这个测试数据有点类似SNS中的好友关系,假设是10个来自2个不同的圈子的同学的SNS聊天记录。显然,同一个圈子内的同学会有更密切的关系和互动。

数据如下所示,每一行代表一个好友关系。如第一行表示同学0与同学1的亲密程度为9(越高表示联系越密切)。

显然,这个数据中并没有告知我们这10个同学分别属于哪个圈子。因此我们的目标是使用K-Means聚类算法,将他们聚成2类。

[plain] view plaincopy

  1. 0 1 9
  2. 0 2 5
  3. 0 3 6
  4. 0 4 3
  5. 1 2 8
  6. ......

这个例子设计的很简单。我们使用上一篇文章中提到的关系矩阵,将其可视化出来,会看到如下结果:

这是个上三角矩阵,因为这个数据中认为好友关系是对称的。上图其实很快能发现,0,1,2,3,4用户紧密联系在一起,而5,6,7,8,9组成了另外一个圈子。

下面我们看看K-Means算法能否找出这个答案。

3、代码与分析

K-Means算法的Python代码如下:

[python] view plaincopy

  1. # -*- coding: utf-8 -*-
  2. from matplotlib import pyplot
  3. import scipy as sp
  4. import numpy as np
  5. from sklearn import svm
  6. import matplotlib.pyplot as plt
  7. from sklearn.cluster import KMeans
  8. from scipy import sparse
  9. #数据读入
  10. data = np.loadtxt('2.txt')
  11. x_p = data[:, :2] # 取前2列
  12. y_p = data[:, 2] # 取前2列
  13. x = (sparse.csc_matrix((data[:,2], x_p.T)).astype(float))[:, :].todense()
  14. nUser = x.shape[0]
  15. #可视化矩阵
  16. pyplot.imshow(x, interpolation='nearest')
  17. pyplot.xlabel('用户')
  18. pyplot.ylabel('用户')
  19. pyplot.xticks(range(nUser))
  20. pyplot.yticks(range(nUser))
  21. pyplot.show()
  22. #使用默认的K-Means算法
  23. num_clusters = 2
  24. clf = KMeans(n_clusters=num_clusters, n_init=1, verbose=1)
  25. clf.fit(x)
  26. print(clf.labels_)
  27. #指定用户0与用户5作为初始化聚类中心
  28. init = np.vstack([ x[0], x[5] ])
  29. clf = KMeans(n_clusters=2, init=init)
  30. clf.fit(x)
  31. print(clf.labels_)

输出结果如下:

Initialization complete

Iteration 0, inertia 581.000
Iteration 1, inertia 417.643
Converged at iteration 1
[0 0 1 1 1 1 1 1 1]

[0 0 0 0 1 1 1 1 1]

可以看到,使用默认的K-Means算法将使用随机的初始值,因此每次执行的结果都不一样。

上面的输出中将0,1用户聚类到一起,效果并不理想。然而,如果我们可以确定用户0与用户5是有很大区别的,就可以指定用户0和用户5作为K-Means聚类算法的初始值。可以看到和我们的预期完全一致,这样效果就非常好了。

转载地址:http://moavx.baihongyu.com/

你可能感兴趣的文章
JS递归与二叉树的遍历
查看>>
基于HTML5的WebGL呈现A星算法的3D可视化
查看>>
Android Studio 1.5 RC1搭建NDK开发环境
查看>>
Apache JMeter 5.1.1 发布,压力测试工具
查看>>
2018届各大互联网公司校招薪资曝光汇总
查看>>
如何用 CSS 和 D3 创作一个无尽的六边形空间
查看>>
架构师必须要知道的阿里的中台战略与微服务
查看>>
快速体验 Sentinel 集群限流功能,只需简单几步
查看>>
手把手教你用RecyclerView实现猫眼电影选择效果
查看>>
《wireshark网络分析实践》1:wireshark简介
查看>>
实用贴:hadoop系统下载安装教程
查看>>
SAP使用BAPI创建物料主数据的最小输入
查看>>
腾瑞制药完成新一轮融资,君联资本、中金资本和IDG资本 ...
查看>>
携新一代车规级固态激光雷达而来,速腾聚创为助力自动驾驶量产有何新动作? ...
查看>>
idea 创建运行web项目时,报错: Can not issue executeUpdate() for SELECTs解决方案
查看>>
入门科普:Python、R、大数据、云计算最全学习资源都在这里
查看>>
如何用纯 CSS 创作一个过山车 loader
查看>>
分布式事务中间件 Fescar - 全局写排它锁解读
查看>>
阿里云服务器怎么选择合适CPU/内存和宽带配比?
查看>>
阿里云新发布ECS状态变化类事件
查看>>