kmeans|手撕K-means聚类算法

一.数据集来源 本博客采用的数据集来源于uci公开数据集(wine数据)
http://archive.ics.uci.edu/ml/datasets/Wine
kmeans|手撕K-means聚类算法
文章图片

数据集属性:
【kmeans|手撕K-means聚类算法】1)酒精
2)苹果酸
3)灰分
4)灰分的藻盐度
5)镁
6)总酚
7)黄烷类化合物
8)非黄烷类酚
9)原花青素
10)颜色强度
11)色相
12)稀释葡萄酒的OD280 / OD315
13)脯氨酸

二.数据处理 从网站上下载的源文件格式是.data,我不知道怎么用python导入,参考另一个博主的文章https://blog.csdn.net/weixin_43860294/article/details/104687097?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_v31_ecpm-1-104687097.pc_agg_new_rank&utm_term=python%E8%AF%BB%E5%8F%96data%E6%96%87%E4%BB%B6&spm=1000.2123.3001.4430进行了一些调整,将数据保存在了excel中。

三.K-means算法的实现

# -*- coding: utf-8 -*- """ Created on Fri Apr1 14:14:15 2022@author: 21091 """#导入包 import pandas as pd import numpy as np from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt from sklearn.metrics import silhouette_score from sklearn.decomposition import PCA #读取数据 data=https://www.it610.com/article/pd.read_excel(r'C:\Users\21091\Downloads\wine.xlsx') #使用的是standardscalar规范化处理 scalar=StandardScaler() data=https://www.it610.com/article/scalar.fit(data).transform(data)scores=[]#存放轮廓系数 distortions=[]#簇内误差平方和SSE for i in range(2,10): Kmeans_model=KMeans(n_clusters=i) predict_=Kmeans_model.fit_predict(data) scores.append( silhouette_score(data,predict_)) distortions.append(Kmeans_model.inertia_) print("轮廓系数:",scores) print("簇内误差平方和:",distortions) #SSE手肘法 plt.figure(1) plt.plot(range(2,10),distortions,marker='x') plt.xlabel('Number of clusters') plt.ylabel('Distortion') plt.title('distortions') plt.savefig("手肘法") #轮廓系数法 plt.figure(2) plt.plot(range(2,10),scores,marker='x') plt.xlabel('Number of clusters') plt.ylabel('scores') plt.title('scores') plt.savefig("轮廓系数法")def random_k_point(number:int): """ 随机法确定初始点 """ #定义匿名函数在data[1,len(data)]中随机选择 k=lambda: data[np.random.randint(len(data)),:] #返回一个随机列表 return[np.array(k()) for i in range(number)] def Kmeans(data,k): """ 输入:data-数据集 k-聚类个数 输出:data后面新增一列表示类别""" p=len(data[0,:]) #数据维度 cluscenter= np.array(random_k_point(k)) lastcluscenter = np.array(random_k_point(k)) index_=np.zeros(len(data)) #初始化标签while 1: for i in range(len(data)): #从0到len(data)-1循环 sumsqure=np.zeros((k)) for j in range(k): sumsqure[j]=np.sqrt(sum(data[i,:]-cluscenter[j,:])**2)#欧式距离 s=pd.Series(sumsqure).sort_values() #升序排序 index_[i]=s.index[0] clusdata=https://www.it610.com/article/np.hstack((data,index_.reshape(len(data),1))) #更新聚类中心 for i in range(k): cluscenter[i,:]=np.mean(clusdata[clusdata[:,p]==i,:-1],0).reshape(1,p) t=abs(lastcluscenter-cluscenter) if sum(sum(t))==0:#对矩阵两次求和转为标量后与0比较 break else: for k in range(k): lastcluscenter[k,:]=cluscenter[k,:] return clusdata,cluscenter #这里的k是通过前面手肘法和轮廓系数法画图后观察得到的 k=3 #因为wine数据集是14维数据,直接画图不利于观察聚类效果,这里用PCA对r,s进行降维处理 #数据降维 pca=PCA(n_components=2) pca.fit(data) data=pca.transform(data)r,s=Kmeans(data,k) plt.figure(3) for i in range(k): x=r[r[:,-1]==i,0] y=r[r[:,-1]==i,1] plt.scatter(s[i,0],s[i,1],s=300) plt.scatter(x,y) plt.savefig("K-means实现红酒分类")

四.运行结果 kmeans|手撕K-means聚类算法
文章图片

kmeans|手撕K-means聚类算法
文章图片

kmeans|手撕K-means聚类算法
文章图片

kmeans|手撕K-means聚类算法
文章图片


上述代码的gitee地址:
https://gitee.com/bullu/bullu/blob/master/K-means/Kmeans_Wine

    推荐阅读