Kmeans -- 简单手写

Kmeans是一种基于欧式距离的聚类算法,判断两个样本点的距离,距离越近,相似度越高。

步骤为:
1.在一个n簇样本点下,随机选取n个质心点。
2.每个样本点计算它到质心点的距离,并将其分到距离最小的质心点所对应的类中
3.保持类别不变,计算类别的中心点,得到新的n个质心点
4.重复以上步骤,迭代多次(SSE最小时终止)

生成数据集

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import make_blobs

X,y = make_blobs(n_samples=300,
                cluster_std=[0.3,0.3,0.3],
                centers=[[-1,1],[0,0],[1,1]],
                random_state=100)

绘制散点图

plt.style.use("seaborn")
plt.rc("font",family = "YouYuan")
plt.rcParams["axes.unicode_minus"] = False
plt.scatter(data.x1,data.x2)

在这里插入图片描述

随机初始化N个质心点

def initial_centers(datasets,N):
    #提取数据集中所有特征的最小值和最大值
    info_range = datasets.describe().loc[["min","max"],:]
    #遍历数据集中所有的特征,从info_range中随机生成N个
    N_randoms = [np.random.uniform(info_range.loc["min",i],info_range.loc["max",i],N) for i in data.columns]
    #将列表转为Dataframe 并进行转置
    centers = pd.DataFrame(N_randoms,index = datasets.columns).T
    return centers

计算数据集中所有点到质心点的距离(这里是距离平方)

#计算数据集中所有的点到质心点距离的平方
def cal_distance(datasets,centers):
	#存放n个质心点到样本点的距离平方
    d_list = []
    for i in centers.index:
        d_list.append(np.power(datasets-centers.loc[i,:],2).sum(axis = 1))
        #将列表转换为Dataframe,columns为质心点的类别
        data_dis = pd.concat(d_list,axis = 1)
    return data_dis

单次迭代

def iterate(datasets,centers):
    #保持质心点不变,更新y值
    data_dis = cal_distance(datasets,centers)
    y_temp = data_dis.idxmin(axis = 1)
    
    #计算当前y值下的SSE
    SSE = data_dis.min(axis = 1).sum()
    
    #得到新的y值之和,保持y不变,更新质心点
    centers = datasets.groupby(y_temp).mean()
    
    return y_temp ,SSE,centers

运行多次,可以观测到SSE在减小。

迭代多次

#创建一个SSE_list,存放每次迭代的SSE
SSE_list = [0]

#初始化质心点
centers = initial_centers(data,3)

#开始迭代
while True:
    y_temp ,SSE,centers = iterate(data,centers)
    
    #判断当前SSE值是否与最后一个SSE值同
    if SSE ==SSE_list[-1]:
        break;
    SSE_list.append(SSE)
SSE_list

最终得到的SSE_list 为:

[0,
533.248514452687,
173.4974240812278,
136.09880601267884,
91.02446700337498,
58.622219118691156,
57.73097424985825,
57.71670209312117]

最小的SSE约为57.71,总共迭代了7次。

以上仅是我个人的对于Kmeans算法步骤的一个简单学习,还有很多缺点和不足,日后我会对其进行进一步的学习和改进。

AI 编写的K-means迭代 :

# Number of clusters (K)
K = 3
# Maximum number of iterations
max_iterations = 100

# Initialize cluster centers
cluster_centers = np.array([[point_1_x1, point_1_x2],
                            [point_2_x1, point_2_x2],
                            [point_3_x1, point_3_x2]])

for iteration in range(max_iterations):
    # Assignment step
    #np.linalg.norm 直接计算了L2范数,np.argmin 展平取得最小下标值
    distances = np.array([np.linalg.norm(data_set.values - center, axis=1) for center in cluster_centers])
    cluster_assignments = np.argmin(distances, axis=0)

    # Update step
    new_centers = [data_set[cluster_assignments == i].mean(axis=0) for i in range(K)]
    new_cluster_centers = np.vstack(new_centers)

    # Check for convergence
    if np.all(cluster_centers == new_cluster_centers):
        break

    cluster_centers = new_cluster_centers
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值