手写KMeans聚类

手写KMeans聚类,纯python实现(使用了numpy 库),具体见代码,注释都在代码中。

# -*- coding: utf-8 -*-
"""
Created on Sun Jun 21 16:46:52 2020

@author: Lenovo
"""

import numpy as np

#计算距离函数
def euclidean_distance(x1,x2):
    distance=0
    for i in range(len(x1)):
        distance+=pow((x1[i]-x2[i]),2)
    return np.sqrt(distance)


#定义初始化函数
def centroids_init(k,X):
    n_samples,n_features=X.shape

    centroids=np.zeros((k,n_features))
    #centroids用于储存每个聚类中心
    for i in range(k):
        #每一次循环随机选择一个类别中心
        centroid=X[np.random.choice(range(n_samples))] # 从 n_samples里面随机选一个作为聚类中心
        
        centroids[i]=centroid
        
    return centroids

#定义样本的最近质心点所属的类别索引
def closest_centroid(sample,centroids):
    closest_i=0
    #先把距离设为无穷大
    closest_dist=float('inf')
    for i,centroid in enumerate(centroids):
        distance=euclidean_distance(sample,centroid)
        if distance < closest_dist:
            closest_i=i
            closest_dist=distance
            
    return closest_i

#定义构建类别过程
def create_clusters(centroids,k,X):
    
    clusters=[[] for i in range(k)]
    #假如 K 为3,那么上面语句执行后,clusters为 [[],[],[]]
    for sample_i , sample in enumerate(X):
        #得到sample所属的聚类中心的标签
        centroid_i=closest_centroid(sample,centroids)
        clusters[centroid_i].append(sample_i)
        
    return clusters

#根据上一步的计算结果计算新的中心点
def calculate_centroids(clusters,k,X):
    n_features=np.shape(X)[1]
    centroids=np.zeros((k,n_features))
    for i,cluster in enumerate(clusters):
        #求平均值,这就是KMeans更新聚类中心的方法
        centroid=np.mean(X[cluster],axis=0)
        #更新聚类中心
        centroids[i]=centroid
        
    return centroids

#获取每个样本所属的聚类类别
def get_cluster_labels(clusters,X):
    y_pred=np.zeros(np.shape(X)[0])
    for cluster_i,cluster in enumerate(clusters):
        for sample_i in cluster:
            y_pred[sample_i]=cluster_i
            
    return y_pred


#封装整合 
def kmeans(X,k,max_iter):
    centroids=centroids_init(k,X)
    for i in range(max_iter):
        clusters=create_clusters(centroids,k,X)
        prev_centroids=centroids
        centroids=calculate_centroids(clusters,k,X)
        diff=centroids-prev_centroids
        #当聚类中心不再变化时,停止迭代
        if not diff.any():
            break
        
    return get_cluster_labels(clusters,X),centroids



X=np.array([[0,2],[0,0],[5,0],[4,5],[1,1]])
labels,centers=kmeans(X,2,10)
print(labels)
print(centers)

输出为:
[1. 1. 0. 0. 1.]
[[4.5 2.5 ]
[0.33333333 1. ]]

参考文献:

公众号“机器学习实验室”的原创文章“数学推导+纯Python实现机器学习算法25:kmeans聚类”

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值