【无监督学习】机器学习专项课程学习记录5——聚类

学习目标

七月的最后一次更新(1/2),坚持!学会无监督学习中的聚类。

笔记

1 K-means算法

主要思想:在给定K值和K个初始类簇中心点的情况下,把每个点(亦即数据记录)分到离其最近的类簇中心点所代表的类簇中,所有点分配完毕之后,根据一个类簇内的所有点重新计算该类簇的中心点(取平均值),然后再迭代的进行分配点和更新类簇中心点的步骤,直至类簇中心点的变化很小,或者达到指定的迭代次数。
参考: Kmeans聚类-K值以及簇中心点的选取

1.1 步骤

  1. 随机初始化K个聚类簇心 μ 1 \mu_{1} μ1 μ 2 \mu_{2} μ2 μ k \mu_{k} μk
  2. 重复以下两个步骤:
    (1)将所有数据点分配给最近的簇心(遍历m个数据点,建立一个列表,储存每个数据点的最近簇心索引);
    (2)移动簇心(遍历k个簇心,更新每个簇心的数值:分配的点的均值)。

1.2 优化目标

J ( c ( 1 ) , . . . , c ( m ) , μ 1 , . . . , μ k ) = 1 m ∑ i = 1 m ∣ ∣ x ( i ) − μ c ( i ) ∣ ∣ 2 J(c^{(1)},...,c^{(m)},\mu_{1},...,\mu_{k}) = \frac{1}{m}\sum_{i=1}^{m}{||x^{(i)}-\mu_{c(i) }||^2} J(c(1),...,c(m),μ1,...,μk)=m1i=1m∣∣x(i)μc(i)2
其中, c ( i ) c^{(i)} c(i) x ( i ) x^{(i)} x(i)对应的最近簇心的索引列表, μ k \mu_{k} μk是类k的均值点。

1.3 选择聚类数量K

选择能使损失函数最小的K不是一个好方法(K倾向于取最大值)。在实践中选择K,要结合实际需求,评估是否符合后续业务的开展。

注:有一种不太推荐的方法是:肘子法(elbow method)。建立K和损失函数的关系图,找到使得损失由陡峭到平坦的转折点,对应的K值就是我们想要的结果。
在这里插入图片描述

1.4 随机初始化簇心

K-Means算法对初始簇心的选择很敏感,不同的随机种子点得到的聚类结果完全不同。

选择簇心往往遵照下面的方法:

def kMeans_init_centroids(X, K):
    # 对X随机重排序,得到索引
    randidx = np.random.permutation(X.shape[0])
    # 取前K个当作簇心
    centroids = X[randidx[:K]]
    
    return centroids

将上述随机初始化过程重复50到1000次,将每一次随机初始化的簇心组合代入k-means中进行运算,并计算损失,选择使得损失最小的一组簇心作为最终结果。

1.5 K-means算法的python实现

# 计算每个X的最近簇心
def find_closest_centroids(X, centroids):
    K = centroids.shape[0]
    idx = np.zeros(X.shape[0], dtype=int)

    for i in range(X.shape[0]):
        distance = []         
        for j in range(centroids.shape[0]):
            norm_ij = np.linalg.norm(X[i] - centroids[j])
            distance.append(norm_ij)
        idx[i] = np.argmin(distance)
        
    return idx

# 计算每个簇心对应的数据点的均值
def compute_centroids(X, idx, K):
    m, n = X.shape
    centroids = np.zeros((K, n))
    
    for k in range(K):
        points = X[idx == k]
        centroids[k] = np.mean(points,axis=0)
    
    return centroids

# 调用上面两个函数,运行K-means
def run_kMeans(X, initial_centroids, max_iters=10, plot_progress=False):
    # 初始化值
    m, n = X.shape
    K = initial_centroids.shape[0]
    centroids = initial_centroids
    previous_centroids = centroids    
    idx = np.zeros(m)
    
    # 运行K-Means
    for i in range(max_iters):
        print("K-Means iteration %d/%d" % (i, max_iters-1)) 
        idx = find_closest_centroids(X, centroids)
        # 绘制过程
        if plot_progress:
            plot_progress_kMeans(X, centroids, previous_centroids, idx, K, i)
            previous_centroids = centroids
        # 计算新簇心
        centroids = compute_centroids(X, idx, K)
    plt.show() 
    return centroids, idx

在这里插入图片描述

2 K-means 应用

2.1 K-means用于图像压缩

在这里插入图片描述

总结

  1. K值需要预先给定,结合实际需求,设定合理的K值很困难;
  2. K-Means算法对初始簇心的选择很敏感;
  3. K均值算法并不是很所有的数据类型。它不能处理非球形簇、不同尺寸和不同密度的簇;
  4. 不适合直接对含有离群点的数据进行聚类;这种情况下,离群点检测和删除有很大的帮助。
    参考:
    链接: k-means基础

需要注意的地方

  1. 优化目标的视频部分还是不太懂;
  2. 聚类还有很多种变体,本文介绍的是常规的简单方法,之后再加以补充。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值