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

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

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

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

机器学习主要分为三类:

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

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

强化学习。

 

ml课程:聚类概述及K-means讲解(含代码实现)_第1张图片

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

ml课程:聚类概述及K-means讲解(含代码实现)_第2张图片

 

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

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

ml课程:聚类概述及K-means讲解(含代码实现)_第3张图片

 

聚类的应用主要包括:

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

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

输出:数据类别归属

聚类基本的三类算法:

下面重点说K-means。

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

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

先看几个特例:

  • K=1时的算法:

ml课程:聚类概述及K-means讲解(含代码实现)_第4张图片

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

ml课程:聚类概述及K-means讲解(含代码实现)_第5张图片

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

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

ml课程:聚类概述及K-means讲解(含代码实现)_第6张图片

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

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

ml课程:聚类概述及K-means讲解(含代码实现)_第7张图片

最后聚类得到:

ml课程:聚类概述及K-means讲解(含代码实现)_第8张图片

 

但是容易遇到这种问题:

ml课程:聚类概述及K-means讲解(含代码实现)_第9张图片

ml课程:聚类概述及K-means讲解(含代码实现)_第10张图片

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

ml课程:聚类概述及K-means讲解(含代码实现)_第11张图片

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

ml课程:聚类概述及K-means讲解(含代码实现)_第12张图片

但是最远点也有问题:

ml课程:聚类概述及K-means讲解(含代码实现)_第13张图片

 

ml课程:聚类概述及K-means讲解(含代码实现)_第14张图片

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

ml课程:聚类概述及K-means讲解(含代码实现)_第15张图片

ml课程:聚类概述及K-means讲解(含代码实现)_第16张图片

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

下面说说如何选择k值

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

ml课程:聚类概述及K-means讲解(含代码实现)_第17张图片

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

ml课程:聚类概述及K-means讲解(含代码实现)_第18张图片

ml课程:聚类概述及K-means讲解(含代码实现)_第19张图片

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

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

ml课程:聚类概述及K-means讲解(含代码实现)_第20张图片

ml课程:聚类概述及K-means讲解(含代码实现)_第21张图片

 

ml课程:聚类概述及K-means讲解(含代码实现)_第22张图片

这个算法的时间复杂度较高,为: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


未完,待续。

你可能感兴趣的:(课程笔记)