机器学习--无监督学习之K-means聚类方法
来源:互联网 发布:jsp无法import java类 编辑:程序博客网 时间:2024/06/16 20:13
一、引言
从上次SVM之后几节课讲的是学习理论,这块理论性比较深,我得好好消化一下。所以先总结一下第一个无监督的机器学习算法,K-means聚类方法。
所谓无监督学习,就是数据样本没有标签,要让学习算法自己去发现数据之间内在的一些结构和规律。就好比做题没有标准答案,所以训练效果自然比监督学习差。但是目前机器学习最大的问题还是在于大量标记样本的需求,掌握数据才能训练出好的算法,但是数据却不是人人都能轻易获得的。所以无监督学习算法的研究是必要的和长期的。
二、算法介绍
k-means算法是一种迭代算法,其思想很简单。就是找出样本所聚集的类个数并找出每一个样本点归属于哪个类。
分成两步:
先人工指定K个聚类中心,并采用一定规则初始化它们的位置;
(1) 簇分配:遍历样本分别找到与k个聚类中心的点,分别归类。
(2)移动中心:将聚类中心移到上一步归属于该中心的样本点的均值处
重复以上步骤直到收敛。给个图就是这样:
还有个动图地址:https://datasciencelab.files.wordpress.com/2013/12/p_n100_k7.gif
算法非常简单,下面给出几个需要注意的点:
(1)每次求取样本点到 各个聚类中心距离时,可以用一般的两点之间的距离,也可以有其余求取距离的方法:
①Euclidean Distance公式——欧几里得距离,就是最常见的二范数
②CityBlock Distance公式——城市街区距离,在图像中经常用到
这里有一些公式,说明算法的步骤:
①初始化k个聚类中心(通常不是很多,2,3,4,5个左右)
②把每个样本点(j=1,...m)分配给里它最近的聚类中心,t表示第t次迭代
③把聚类中心更新为属于它的样本点的平均值点
它的优化函数为:
参数部分分为两块,其中C是针对每个样本点的,m为,每一维表示了每一个样本点所属的聚类中心索引,μ是针对聚类中心的,有k维。优化的过程就是算法的迭代的过程,分为两部分。每一步固定一组参数,优化另一组参数。
那么,最重要的问题来了,如何选择k-means的初始聚类中心个数以及初始聚类中心位置?
①首先k<m,聚类中心个数肯定比样本点个数少。第二,可以用肘部法则选择k的个数,示意图如下:
针对不同的k个数绘制代价函数最后最优值曲线绘制,一般在k=1~10之间,找到类似于手肘的点对应的k个数,应该是最好的一个。但是这种方法也不是万能,最好的方法还是人工选择,结合k-means应用的场景来选。
②初始聚类中心的位置选择不同,最后收敛的结果和速度也可能不同。选择思路如下:
1、从输入的数据点集合(要求有k个聚类)中随机选择一个点作为第一个聚类中心
2、对于数据集中的每一个点x,计算它与最近聚类中心(指已选择的聚类中心)的距离D(x)
3、选择一个新的数据点作为新的聚类中心,选择的原则是:D(x)较大的点,被选取作为聚类中心的概率较大
4、重复2和3直到k个聚类中心被选出来
5、利用这k个初始的聚类中心来运行标准的k-means算法
三、代码实现
from math import pi, sin, cosfrom collections import namedtuplefrom random import random, choicefrom copy import copy try: import psyco psyco.full()except ImportError: pass FLOAT_MAX = 1e100 class Point: __slots__ = ["x", "y", "group"] def __init__(self, x=0.0, y=0.0, group=0): self.x, self.y, self.group = x, y, group def generate_points(npoints, radius): points = [Point() for _ in xrange(npoints)] # note: this is not a uniform 2-d distribution for p in points: r = random() * radius ang = random() * 2 * pi p.x = r * cos(ang) p.y = r * sin(ang) return points def nearest_cluster_center(point, cluster_centers): """Distance and index of the closest cluster center""" def sqr_distance_2D(a, b): return (a.x - b.x) ** 2 + (a.y - b.y) ** 2 min_index = point.group min_dist = FLOAT_MAX for i, cc in enumerate(cluster_centers): d = sqr_distance_2D(cc, point) if min_dist > d: min_dist = d min_index = i return (min_index, min_dist) def kpp(points, cluster_centers): cluster_centers[0] = copy(choice(points)) d = [0.0 for _ in xrange(len(points))] for i in xrange(1, len(cluster_centers)): sum = 0 for j, p in enumerate(points): d[j] = nearest_cluster_center(p, cluster_centers[:i])[1] sum += d[j] sum *= random() for j, di in enumerate(d): sum -= di if sum > 0: continue cluster_centers[i] = copy(points[j]) break for p in points: p.group = nearest_cluster_center(p, cluster_centers)[0] def lloyd(points, nclusters): cluster_centers = [Point() for _ in xrange(nclusters)] # call k++ init kpp(points, cluster_centers) lenpts10 = len(points) >> 10 changed = 0 while True: # group element for centroids are used as counters for cc in cluster_centers: cc.x = 0 cc.y = 0 cc.group = 0 for p in points: cluster_centers[p.group].group += 1 cluster_centers[p.group].x += p.x cluster_centers[p.group].y += p.y for cc in cluster_centers: cc.x /= cc.group cc.y /= cc.group # find closest centroid of each PointPtr changed = 0 for p in points: min_i = nearest_cluster_center(p, cluster_centers)[0] if min_i != p.group: changed += 1 p.group = min_i # stop when 99.9% of points are good if changed <= lenpts10: break for i, cc in enumerate(cluster_centers): cc.group = i return cluster_centers def print_eps(points, cluster_centers, W=400, H=400): Color = namedtuple("Color", "r g b"); colors = [] for i in xrange(len(cluster_centers)): colors.append(Color((3 * (i + 1) % 11) / 11.0, (7 * i % 11) / 11.0, (9 * i % 11) / 11.0)) max_x = max_y = -FLOAT_MAX min_x = min_y = FLOAT_MAX for p in points: if max_x < p.x: max_x = p.x if min_x > p.x: min_x = p.x if max_y < p.y: max_y = p.y if min_y > p.y: min_y = p.y scale = min(W / (max_x - min_x), H / (max_y - min_y)) cx = (max_x + min_x) / 2 cy = (max_y + min_y) / 2 print "%%!PS-Adobe-3.0\n%%%%BoundingBox: -5 -5 %d %d" % (W + 10, H + 10) print ("/l {rlineto} def /m {rmoveto} def\n" + "/c { .25 sub exch .25 sub exch .5 0 360 arc fill } def\n" + "/s { moveto -2 0 m 2 2 l 2 -2 l -2 -2 l closepath " + " gsave 1 setgray fill grestore gsave 3 setlinewidth" + " 1 setgray stroke grestore 0 setgray stroke }def") for i, cc in enumerate(cluster_centers): print ("%g %g %g setrgbcolor" % (colors[i].r, colors[i].g, colors[i].b)) for p in points: if p.group != i: continue print ("%.3f %.3f c" % ((p.x - cx) * scale + W / 2, (p.y - cy) * scale + H / 2)) print ("\n0 setgray %g %g s" % ((cc.x - cx) * scale + W / 2, (cc.y - cy) * scale + H / 2)) print "\n%%%%EOF" def main(): npoints = 30000 k = 7 # # clusters points = generate_points(npoints, 10) cluster_centers = lloyd(points, k) print_eps(points, cluster_centers) main()
- 机器学习--无监督学习之K-means聚类方法
- 机器学习笔记:K-Means无监督聚类算法
- 机器学习笔记11——无监督学习之k-means聚类算法
- 无监督学习之K-means算法
- 机器学习--K-means算法(聚类,无监督学习)
- 机器学习算法---无监督学习,k-means聚类
- K-means聚类算法(无监督学习算法)
- 无监督学习k-means简单实现
- 机器学习----聚类之k-means
- 非监督学习之k-means聚类算法——Andrew Ng机器学习笔记(九)
- 【机器学习算法-python实现】K-means无监督学习实现分类
- 王小草【机器学习】笔记--无监督算法之聚类
- 机器学习之无监督聚类问题
- 机器学习之无监督聚类问题
- 机器学习之聚类算法(K-Means)
- 机器学习之聚类算法k-means
- 机器学习之K-means聚类算法
- 机器学习(25)之K-Means聚类算法详解
- 程序员必备的几个图形制作工具
- 好玩的Python库tqdm
- leetcode编程记录1 #8 String to Integer (atoi)
- 阿里云服务器搭建SVN服务器
- 设计模式——单例模式
- 机器学习--无监督学习之K-means聚类方法
- Lua结合C#调用C++或者C的函数
- Weblogic三种部署方式
- 又来继续写博客了,搬家wuit.top
- 《大型网站技术架构》读书笔记(二)——大型网站系统架构图
- Windows 版 SourceTree 免登录跳过初始设置的方法
- 输入一个链表,反转链表后,输出链表的所有元素。
- 抽取Fragment 和对抽取的Fragment进行应用(心得用的时候稍微修改就可以了)
- 带你走进SAP项目实施过程——立项(1)