用python实现K-means算法

尝试了一下深夜模式, 感觉非常好,外界温度降低使得脑子不容易过载,就是有点饿。
OK,回归正题,花了一点时间实现了 K-Means 算法,以及改良版的 K-Means++

原理和算法都比较简单,这里不再过多赘述。
如果有不太懂的右转中文 wikiK-Means算法

这里主要讲一下使用 K-Means 时遇到的一些问题。
这是本周作业的 Githubhttps://github.com/hachiri/ML_Seminar/tree/master/2019.10.19

对于首次选取聚点时,K-Means 我使用了这种算法:
这是一个选取了随机中间值的简易方法。

def creat_random_centP(dataset, k):
    '''Take k random centers of mass'''
    dim = np.shape(dataset)[1]
    centP = np.zeros([k, dim])
    for i in range(dim):
        data_min = np.min(dataset[:,i])
        data_max = np.max(dataset[:,i])
        # Create random values between the maximum and minimum in each dimension
        centP[:,i] = (np.random.rand(k, 1).dot(data_max - data_min) + data_min)[:,0]
    return centP

在实测过程中,这种方法有一定的概率出现误差,最终会导致聚点无法收敛,产生 NA

于是有了改进版的 K-Means++

def creat_plusplusrandom_centP(dataset, k, calcu_dist=calculate_Euclidist):
    '''Take k random centers of mass from the existing data'''
    m = np.shape(dataset)[0]
    cent_numbers = []
    cent_numbers.append(np.random.randint(0, m-1))
    distance_M = np.zeros([m, m])
    for i in range(m):
        for j in range(i + 1, m):
            distance_M[i][j] = calcu_dist(dataset[i,:], dataset[j,:])
            distance_M[j][i] = distance_M[i][j].copy()
    while len(cent_numbers) < k:
        prob_sum = np.cumsum(distance_M[:,cent_numbers[-1]]) / np.sum(distance_M[:,cent_numbers[-1]])
        P = np.random.rand()
        random_number = np.nonzero(prob_sum <= P)[-1][-1]
        if random_number not in cent_numbers:
            cent_numbers.append(random_number)
    return dataset[cent_numbers]

相比 K-Means ,选取聚点是从已有点内通过计算概率获得,从而降低了误差

最终完成版的效果图:https://nbviewer.jupyter.org/github/hachiri/ML_Seminar/blob/master/2019.10.19/k-means.ipynb

PS:今天看到了Google Machine Learning Winter Camp 2020 Application Form,非常激动,特别激动,就想着能不能被选上。填空框起码有东西勉勉强强都能够凑进去,虽然奖项LEVEL太低了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值