Kmeans 不调用包python代码

目录

简介:

1 算法步骤:

2 算法实战:

2.1 数据准备

2.2 数据处理

2.3 Kmeans运行过程图展示

3 总结:

3.1 kmeans算法的优缺点

3.2 kmeans 的运用场景

4 代码总汇:


简介:

        K-means聚类算法是一种无监督学习算法,主要用于将数据划分为K个预定义的簇或集群。这种算法的核心思想是通过迭代的方式,将数据点划分为K个集群,使得每个数据点与其所属集群的质心(即集群中所有点的平均值)的距离之和最小。

db2b7dcf19fa47a19d66b8fbaa6f7e9b.png

1 算法步骤:

       核心:最小化所有样本到所属类别中心的欧式距离和 d5e4ab7a7e504a4cb33d5a560a0fbb13.png

2 算法实战:

2.1 数据准备

数据来源:Iris - UCI 机器学习存储库

8c5ac1f922304e72af62322d39e99b93.png

2.2 数据处理

将鸢尾花数据集的4个特征数据转化到【0,1】区间内。

eq?x%3D%5Cfrac%7BX-X_%7Bmin%7D%7D%7BX_%7Bmax%7D-X_%7Bmin%7D%7D

2.3 Kmeans运行过程图展示

       初始化k=3(聚类个数)

48c90e1f567143409490d801c573eb8c.png

31bda50df7ec4faa9d7f7e9c82c7f88a.png

16134aba193f4aa8867af288f1685220.png

44f4b295b4624d6faddd04ca8795051b.png

96653b7e780a4877a93ae6ae0791650e.png

c6ae31e58ebd415d85b2fe59d4d0d037.png

       由上图可知每次迭代聚类中心得变化情况,并且该次运行是第4和5次的聚类中心没有发生改变故此停止迭代。

       我们再将所有数据点离各自聚类中心的距离求和作为聚类的误差从而可计算出每次迭代的误差值故可绘制出历史迭代的误差变化图如下图所示。

8e69fefa56b34b7189a9fa67189c7c52.png

3 总结:

3.1 kmeans算法的优缺点

优点

  1. 简单易懂:K-Means算法的原理相对简单,易于理解和实现。它基于距离度量进行数据点的聚类,直观且易于解释。

  2. 高效性:在大数据集上,K-Means算法通常具有较快的收敛速度,能够高效地处理大规模数据。

  3. 可伸缩性:K-Means算法能够处理不同规模的数据集,从较小的数据集到非常大的数据集都能适用。

  4. 只依赖一个参数:算法主要依赖K值的选择,即需要划分的簇的数量。相对于其他聚类算法,K-Means的参数调整相对简单。

缺点

  1. K值选择困难:K值的选择对于聚类结果至关重要,但确定合适的K值并不容易。过小的K值可能导致信息丢失,过大的K值则可能使得聚类结果过于琐碎。

  2. 对初始值敏感:K-Means算法的初始簇中心是随机选择的,这可能导致算法陷入局部最优解,而非全局最优解。

  3. 对异常值敏感:算法对噪音和异常值比较敏感,因为这些点可能会显著影响簇中心的计算,导致聚类结果不准确。

  4. 不适合非凸形状的数据:K-Means算法基于距离度量进行聚类,因此对于形状复杂或非凸的数据集,可能难以得到理想的聚类结果。

3.2 kmeans 的运用场景

  1. 市场细分:在市场营销中,K-Means算法可以用于客户细分,将客户按照购买行为、兴趣偏好等特征进行聚类,从而制定更精准的营销策略。

  2. 图像分割:在图像处理领域,K-Means算法可以用于图像分割,将图像中的像素按照颜色、纹理等特征进行聚类,实现图像的自动分割和识别。

  3. 文本聚类:在文本处理中,K-Means算法可以用于文档的自动聚类,将相似的文档归类在一起,便于信息检索和主题分析。

  4. 基因表达数据分析:在生物信息学中,K-Means算法可以用于基因表达数据的聚类分析,帮助科学家发现基因之间的关联性和功能模式。

       总之,K-Means算法在多个领域都有广泛的应用,尤其在需要基于特征相似性进行分组或分类的场景中表现出色。然而,在使用时需要注意其局限性,并根据实际情况进行参数调整和优化。

4 代码总汇:

from sklearn import preprocessing
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = "SimHei"#汉字乱码的解决方法
class kmeans:
    def __init__(self,k):
        self.k=k
    def distance(self,point1,point2):
        return np.sqrt(np.sum((point1 - point2) ** 2))

    #类别的计算
    def fit(self,x,centers):
        #随机选取k个聚类中心
        n,m=np.shape(x)
        Dis=[]#存储个点到聚类中心的距离
        cluster=[]#存储类别
        #计算点到聚类中心的距离
        for i in range (n):
            dis=[]
            for j in range(self.k):
                L=self.distance(x[i,:],centers[j,:])
                dis.append(L)
            cluster.append(np.argmin(dis))
            Dis.append(dis)
        Dis=np.array(Dis)
        return cluster
    #更新聚类中心
    def renewcenters(self,x,cluster):
        n,m=np.shape(x)
        renew = np.zeros((self.k, m))
        renew=np.array(renew)
        for i in range(self.k):
            c=0#记录同类的个数
            for j in range(n):
                if cluster[j]==i:
                    renew[i,:]=renew[i,:]+x[j,:]
                    c=c+1;
            renew[i,:]=renew[i,:]/c
        return renew
    #类别预测
    def predict(self,x1,centers):
        cids=[]
        for i in range(self.k):
            t=self.distance(x1,centers[i,:])
            cids.append()
        return np.argmin(cids)
    
    #计算点到各自中心的距离的误差总计
    def Errors(self,x,centers,cluster):
        n,m=np.shape(x)
        errors=0
        for i in range(self.k):
            for j in range(n):
                if cluster[j]==i:
                    errors=errors+self.distance(centers[i,:],x[j,:])
        return errors
    #分类图绘制
    def pictureshow(self,x,cluster,centers,_):
        cluster=np.array(cluster)
        x=np.array(x)
        centers=np.array(centers)
        colors = ['red', 'green', 'orange']  # 建立颜色列表
        labels = ['Zero', 'One', 'two']
        for i in range(k):
            #将不同类的点找出来(cluster=i)并绘制图像
            plt.scatter(x[cluster == i, 0], x[cluster == i, 1], c=colors[i], label=labels[i])
            #绘制聚类中心
            plt.scatter(centers[i,0],centers[i,1],c=colors[i],s=500,marker='*')
        #注意为了使每个类别的散点图在同一副图上故要在for循环外
        plt.title("第{}次迭代的分类图".format(_))
        plt.xlabel("第一个特征向量")
        plt.ylabel("第二个特征向量")
        plt.show()


shuju2 = pd.read_excel(r'C://Users//86182//Desktop//iris.xlsx', sheet_name='Sheet1')
x=np.array(shuju2)[:,0:4]
min_max_scaler = preprocessing.MinMaxScaler()
x = min_max_scaler.fit_transform(x)
k=3
kmeans=kmeans(k)
iters=6
historyerrors=[]#存储不同聚类中心得聚类误差值
bestcenters=[]#记录最好的聚类中心
bestcluster=[]#记录最好的聚类分类
besterrors=10000
#聚类中心的初选
centers=x[np.random.choice(range(len(x)), k, replace=False)]
for _ in range (iters):
    print("第{}次聚类中心:{}".format(_,centers))
    #类别计算
    cluster=kmeans.fit(x,centers)
    #绘制散点图
    kmeans.pictureshow(x,cluster,centers,_)
    #误差计算
    errors=kmeans.Errors(x,centers,cluster)
    print("第{}次聚类的误差:{}".format(_, errors))
    if errors<=besterrors:
        bestcenters=centers.copy()
        bestcluster=cluster.copy()
        besterrors=errors.copy()
    historyerrors.append(errors)
    #更新聚类中心
    centers1=kmeans.renewcenters(x,cluster)
    #会出现反常情况比如误差增加了但下一次聚类中心也没改变就停止了故找到的并不是全局最优
    if kmeans.distance(centers,centers1)==0:
        print("迭代{}次提前结束".format(_))
        break
    else:
        centers=centers1.copy()
print("全局最好的聚类中心:{}".format(bestcenters))
print("全局最好的聚类分类:{}".format(bestcluster))
print("全局最小的聚类误差:{}".format(besterrors))
#将最终的聚类效果存储在excle中
df = pd.DataFrame({'类别': cluster})
df.to_excel("C://Users//86182//Desktop//pythonsjdc.xlsx",sheet_name='sheet1', index=False)
#画出历史迭代的误差图
l=[i for i in range(len(historyerrors))]
plt.plot(l,historyerrors,color="g",marker="o")
plt.xlabel("迭代次数")
plt.ylabel("误差")
plt.show()

  • 14
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值