【机器学习】K-means算法学习

K-means聚类算法:

之前在实习面试的时候被问到这个算法,今天就总结一下对这个算法的一些理解,参考了一些博主的文章,附在了下端。

假设:数据之间的相似度可以使用欧式距离进行度量,并且欧式距离越小,两个数据相似度越高。

牧师-牧民模型:
伪代码

function K-Means(输入数据,K个聚类中心)
                  获取输入数据的纬度D和个数N
                  随机生成K个Dim纬的点
                  while(算法未收敛)
                              对N个点:计算每个点属于哪一类
                              对于K个中心点:
                                  1.找到所以属于自己这一类的所以数据点
                                  2.把坐标修改到数据中心
                     end
                     输出;
end

算法思路:
随机生成K个聚类中心点(尽量不要生成在一起),计算没一个数据点到这K个中心点的距离,把到中心点距离最短的当正自己的类别。然后这K中心点开始向属于这一类的所有数据的中心点移动(这一类所有点坐标的平均值即为移动后的中心点坐标),知道这K个中心点的坐标都固定了无法移动,算法就收敛,结束。

对于图像来说:
1.从图像中随机取K个聚类中心
2.彩色距离计算方法:
distance=sqt((r-r’)**2 + (g-g’)**2
+(b-b’)**2)
3.计算K类中每一类像素的平均值,并将该值作为新的K个类的中心
4.判断聚类中心是否移动,移动继续迭代;不移动终止迭代。
5.将原图中各个像素分配到彩色距离最小的类别中去

import cv2 as cv 
import numpy as np
import matplotlib.pyplot as plt
from glob import glob

def k_means(img, Class=5):
    # get shape
    H, W, C = img.shape

    # initiate random seed
    np.random.seed(0)

    # reshape image
    img = np.reshape(img, (H * W, -1))

    # get index randomly
    i = np.random.choice(np.arange(H * W), Class, replace=False)
    Cs = img[i].copy()
    print(Cs)

    while True:
        # prepare pixel class label
        clss = np.zeros((H * W), dtype=int)
        
        # each pixel
        for i in range(H * W):
            # get distance from index pixel
            dis = np.sqrt(np.sum((Cs - img[i])**2, axis=1))
            # get argmin distance
            clss[i] = np.argmin(dis)

        # selected pixel values
        Cs_tmp = np.zeros((Class, 3))
        
        # each class label
        for i in range(Class):
            Cs_tmp[i] = np.mean(img[clss == i], axis=0)

        # if not any change
        if (Cs == Cs_tmp).all():
            break
        else:
            Cs = Cs_tmp.copy()

    # prepare out image
    out = np.zeros((H * W, 3), dtype=np.float32)

    # assign selected pixel values  
    for i in range(Class):
        out[clss == i] = Cs[i]

    print(Cs)
        
    out = np.clip(out, 0, 255)

    # reshape out image
    out = np.reshape(out, (H, W, 3))
    out = out.astype(np.uint8)

    return out

# read image
img = cv.imread("../paojie.jpg").astype(np.float32)

# K-means
out = k_means(img,Class=3)

cv.imwrite("out.jpg", out)
cv.imshow("result", out)
cv.waitKey(0)
cv.destroyAllWindows()

参考文章:
https://www.cnblogs.com/wojianxin/p/12580771.html
https://zhuanlan.zhihu.com/p/20432322

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值