ml课程:聚类概述及K-means讲解(含代码实现)

以下是我的学习笔记,以及总结,如有错误之处请不吝赐教。

本文主要介绍聚类以及K均值算法的推倒过程,最后有相关代码案例。

说到聚类就不得不先说说机器学习的分类。

机器学习主要分为三类:

监督学习:分类、回归...

无监督学习:聚类、降维...

强化学习。

 

下面这张图是机器学习python库sklearn的一个分类:

 

聚类的作用主要分为三个:

  1. 组织数据
  2. 降维
  3. 数据预处理,为下部数据的处理做准备

 

聚类的应用主要包括:

  • 网页搜索
  • 生物技术
  • 社交网络(如facebook、twitter等等)
  • 商品推荐系统(划重点)
  • 天文
  • 等等

输入:两个点之间的距离d(x)

输出:数据类别归属

聚类基本的三类算法:

下面重点说K-means。

目标函数:最小化点到中心点的距离平方。公式如下:

时间复杂度:属于NP hard(在非确定图灵机上无法解决(量子计算机))

先看几个特例:

  • K=1时的算法:

  • d=1时:需要用到动态规划来计算。

K-means实现常用的几种算法:

  • 通用的The Lloyd‘s算法,即通过两个迭代循环,第一层循环:求得到中心点的距离最近的点,第二层循环:求点到中心点的均值,不断循环迭代。

    但是对于这种算法,初始点的选择是需要重点考虑的,初始化的方法主要有以下几点:

  •     随机初始化,即随机挑选点:

最后聚类得到:

 

但是容易遇到这种问题:

我们假设数据分布是随机独立分布,那么所有数据被分到正确的类的概率为:\frac{k!}{k^{k}},约等于:\frac{1}{_e{k}},概率随着k的增大呈指数级别减小。

  • 最远点初始化,即找到距离前一个点最远点作为初始化点:

但是最远点也有问题:

 

  • D2sampling:是目前最好的初始化方法,即加权重的最远点,也就是常说的K-means++,这个方法既可以保证随机初始化无法找到所有类的问题,又可以避免最远点的问题。具体的公式如下:

最关键的是,这个算法的时间复杂度并没有增加为:线性O(nkd),其中n为数据点个数,k为聚类中心点个数,d为数据集的维度。即初始化的复杂度可以忽略。

下面说说如何选择k值

  • cross_validation  将数据集分为训练集和测试集,选择在训练集效果最好的k值即可。
  • elbow's method  找到k值下降斜率的拐点。

  • 层次聚类,是聚类的另一个方法,他的不同类别有不同层次,类似于树状。他主要分为以下两类:
  1. 自上而下
  2. 自下而上

自下而上有三种计算两个类距离的方法:

  1. single linkage
  2. complete linkage
  3. average linkage

 

这个算法的时间复杂度较高,为:O(n3),当然通过优先队列的数据结构可以降到O(n2logn)。

最重点的来了,K-means代码实现如下:

import os, sys
import argparse
import numpy as np
import time

# Vanilla K-means clustering.
samples = np.vstack([samples1, samples2, samples3])
rorder = np.arange(num_pts * 3)
rorder = np.random.shuffle(rorder)
samples = samples[rorder, :].squeeze()
# Lloyd's algorithm, with random initialization.
k = 3
centers = np.random.rand(k, 2)
num_iters = 10
losses = []
# Save for repeated use.
xdist = np.sum(samples * samples, axis=1)
for _ in xrange(num_iters):
    # Compute distance to each center.
    cdist = np.sum(centers * centers, axis=1) 
    consts = xdist[:, np.newaxis] + cdist
    dists = consts - 2 * np.dot(samples, centers.T)  #计算到中心点距离
    # Compute cluster assignment.
    ids = np.argmin(dists, axis=1)  #新的中心点迭代
    losses.append(np.sum(np.min(dists, axis=1)))
    for i in xrange(k):
        centers[i, :] = np.mean(samples[ids == i], axis=0)

具体可以看这里:欢迎关注我的github


未完,待续。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值