python实现k-means聚类算法不调包

python实现k-means聚类算法不调包

这里是为了记录机器学习作业写的代码,只要放入二维数据即可运行代码
基本思想
举个例子:
1.假如有5个点要实现聚类:a,b,c,d,e
2.我们要选定聚几类(假设是聚两类)k=2
3.那么我们就随机选定5个点的2个点作为簇心
4.然后将每个点和簇心的欧式距离比较一遍,谁离哪个点进谁就属于哪一类
比如:(b点到A簇心的距离小于到B簇心的距离,则b属于A类)
5.然后算完距离归完类以后,再对每个类进行一次求平均值(x,y),以得到一个新的簇心,然后又回到了3(第三步)
判断条件:如果当前所有的簇心都没更新过,那么这个循环停止,代表聚类成功
6.画图封装成一个函数,和算法区分开来

import matplotlib.pyplot as plt
import csv
import random
import numpy as np


# 计算该簇的平均值得到新的簇点
def avg(x):
    """

    :param x:该簇所有的坐标点
    :return: 得出一个平均值的坐标
    """
    # 分别对x,y求和再求平均值
    sum1 = 0
    sum2 = 0
    for i in range(len(x)):
        sum1 = sum1 + x[i][0]
        sum2 = sum2 + x[i][1]
    sum1 = sum1 / (len(x))
    sum2 = sum2 / (len(x))
    return sum1, sum2


# 计算欧氏距离
def dis(x, y):
    """

    :param x: 第一个坐标
    :param y: 第二个坐标
    :return: 2个坐标之间的距离
    """
    dis1 = (x[0] - y[0]) ** 2
    dis2 = (x[1] - y[1]) ** 2
    dis = pow((dis1 + dis2), 0.5)
    return dis


# 随机生成k个簇心
def rand_heart(data, k):
    """

    :param data: 所有的数据
    :param k: 设置的k值
    :return: 随机返回k个数据坐标作为初始簇点
    """
    cluster_heart = []
    # 随机在data选一个元素作为簇心
    for i in range(k):
        a = random.choice(data)
        cluster_heart.append(a)
    return cluster_heart


# k-means
def k_means(data, k):
    """

    :param data:所有的数据
    :param k: 设置的k值
    :return: 每个的簇点坐标和每个点的一个数组,里面包含每个点属于哪个簇和离它自己簇的距离
    """
    # 数据行的数目
    m = len(data)

    # 生成 每个点的归属簇和离簇距离
    point_to_cluster = [[0 for i in range(2)] for i in range(m)]

    # 定义循环标志
    cluster_flag = True
    # 碎金生成k个簇心
    cluser_heart = rand_heart(data, k)

    # 如果当前所有点的簇心都没更新过,那么这个循环停止,代表聚类成功
    while cluster_flag:
        cluster_flag = False
        # 遍历所有的点(行数)
        for i in range(m):
            # 初始最小距离
            min_dist = 10000000.0
            # 初始簇心序号
            min_cluster_num = -1

            # 对于每个点,找到它当前最近的簇心
            for j in range(k):
                # 计算该点到质心的欧式距离
                distance = dis(cluser_heart[j], data[i])

                if distance < min_dist:
                    min_dist = distance
                    min_cluster_num = j
                point_to_cluster[i] = min_cluster_num, min_dist
            # 如果当前的点的簇心还有比之前距离更小的簇心的话
            if point_to_cluster[i][0] != min_cluster_num:
                cluster_flag = True
        # 更新簇心
        for j in range(k):
            sum = []
            for i in range(m):
                if point_to_cluster[i][0] == j:
                    sum.append(data[i])
            # 赋予新的簇心
            s1, s2 = avg(sum)
            cluser_heart[j][0] = s1
            cluser_heart[j][1] = s2

    return cluser_heart, point_to_cluster


# 画图
def show(data, k, cluster_heart, point_to_cluster):
    """

    :param data:全部的数据
    :param k: 设置的k值
    :param cluster_heart:所有簇点的数组
    :param point_to_cluster: 每个的簇点坐标和每个点的一个数组,里面包含每个点属于哪个簇和离它自己簇的距离
    :return: 没有返回值
    """
    # 计算行数
    m = len(data)
    # 给数据点设置样式
    mark = ['or', 'ob', 'og', 'ok', 'oy', 'om']

    # 绘制所有的点
    for i in range(m):
        markIndex = int(point_to_cluster[i][0])
        plt.plot(data[i][0], data[i][1], mark[markIndex])

    theta = np.arange(0, 2 * np.pi, 0.01)
    # 给簇点设置样式
    mark = ['Dr', 'Db', 'Dg', 'Dk', 'Dy', 'Dm']
    # 给半径设置颜色
    color = ['r', 'b', 'g', 'k', 'y']
    # 绘制簇心
    for i in range(k):
        r = 0
        plt.plot(cluster_heart[i][0], cluster_heart[i][1], mark[i])
        for x in range(len(point_to_cluster)):
            if i == point_to_cluster[x][0]:
                if r < point_to_cluster[x][1]:
                    r = point_to_cluster[x][1]
        r = pow(r, 0.5)
        plt.plot(cluster_heart[i][0] + r * np.cos(theta), cluster_heart[i][1] + r * np.sin(theta), color[i])
    png_name = "测试数据:k等于%i的聚类.png" % k
    # plt.savefig(png_name, format='png')
    plt.show()


if __name__ == '__main__':
    # 声明一个列表存入归一化二维矩阵
    normal_list = []
    # 这里面再读取一次文件再存入新的文件的目的是,由于一开始存入文件的数据类型为string,这里转换为float了再存入新的文件后读取
with open('测试数据.csv', 'r') as f:
    reader = csv.reader(f)
    for row in reader:
        # string 转换 float
        temp1 = float(row[0])
        temp2 = float(row[1])
        temp = [temp1, temp2]
        normal_list.append(temp)

# 设置K值
k = 5
# 聚类算法
cluser_heart, point_to_cluster = k_means(normal_list, k)
# 画图函数
show(normal_list, k, cluser_heart, point_to_cluster)

# 问题:找到聚类中心后,判断(2,6)是属于哪一类?
dot = [2.0, 6.0]
s = 100000.0
index = 100
for i in range(len(cluser_heart)):
    dist = dis(cluser_heart[i], dot)
    if dist < s:
        s = dist
        index = i
color = ['红色', '蓝色', '绿色', '黑色', '黄色']
print("当k等于%i时" % k)
print("离坐标[2,6]最近的簇点是", index)
print("所属簇的颜色为%s" % color[index])
print("该簇点的坐标为:", cluser_heart[index])

本文仅供参考,希望对大家有帮助!

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: K-means聚类算法是一种常见的无监督学习算法,用于将数据集分成k个不同的簇。Python中可以使用scikit-learn库中的KMeans类来实现K-means聚类算法。具体步骤如下: 1. 导入KMeans类和数据集 ```python from sklearn.cluster import KMeans from sklearn.datasets import make_blobs ``` 2. 生成数据集 ```python X, y = make_blobs(n_samples=100, centers=3, random_state=42) ``` 3. 创建KMeans对象并进行拟合 ```python kmeans = KMeans(n_clusters=3, random_state=42) kmeans.fit(X) ``` 4. 获取聚类结果 ```python labels = kmeans.labels_ ``` 5. 可视化聚类结果 ```python import matplotlib.pyplot as plt plt.scatter(X[:, ], X[:, 1], c=labels) plt.show() ``` 以上就是Python实现K-means聚类算法的基本步骤。 ### 回答2: K-means聚类算法是一种常见的无监督学习算法,它将n个样本分成k个簇,每个簇对应着一些数据点,使得同一簇内的数据点之间的相似度尽可能高,而不同簇的数据点之间的相似度尽可能低。Python是一种广泛使用的编程语言,也是进行K-means聚类的好选择。 以下是Python实现K-means聚类算法的步骤: 1. 导入数据集:将要聚类的数据集导入,可以是csv文件或者Excel文件,也可以是Python中自带的sklearn.datasets等数据集模块中的数据集。 2. 选择K值:决定将数据分成几个簇。可以通过手肘法或者轮廓系数法找到最优的K值,手肘法就是将数据集按照K值分割成K个簇并计算每个簇的误差平方和,一般来说误差平方和随簇数量的增加而减小,随着簇数量增加,在某个点后,曲线的下降趋势会减缓。轮廓系数法可以直观地描述每个数据点与其所处簇的相似程度和不同簇的相似程度,即同一簇内的相似度高,与其他簇的相似度低。 3. 初始化聚类中心:从数据集中随机选择K个点作为聚类中心。 4. 簇分配:对于每个数据点,计算其与每个聚类中心的距离,将其分配到距离最近的簇中。 5. 聚类中心更新:重新计算每个簇的聚类中心,即将簇内所有数据点的坐标进行平均,得到新的聚类中心。 6. 重复步骤4-5,直到聚类中心不再改变或达到最大迭代次数。 7. 输出簇:输出每个簇包含的数据点。 Python实现K-means聚类算法的示例代码: ```python from sklearn.cluster import KMeans from sklearn.datasets import make_blobs # 生成数据集 X, y = make_blobs(n_samples=500, centers=3, random_state=42) # 初始化KMeans聚类模型 model = KMeans(n_clusters=3, random_state=42) # 训练模型 model.fit(X) # 输出每个簇的聚类中心坐标 print("Cluster centers:", model.cluster_centers_) # 输出每个数据点所属的簇 print("Cluster labels:", model.labels_) ``` 以上就是Python实现K-means聚类算法的基本步骤和示例代码。在实际应用中,我们可以根据数据集的特点和需求对算法进行改进和优化,使得聚类效果更加准确和高效。 ### 回答3: K-means聚类算法机器学习中常用的无监督学习方法之一,可以将一组数据集划分为K个簇(cluster),簇与簇之间的差异最小。Python提供了很多库,如sklearn、scipy.cluster.vq、numpy等可以实现K-means聚类算法,这里以sklearn库为例进行讲解。 首先,需要导入sklearn库中的KMeans模块,代码如下: ``` from sklearn.cluster import KMeans ``` 接着,需要确定K值,即簇的数量。可以通过手肘法(Elbow Method)来选择最优K值。手肘法是通过绘制不同K值对应的聚类误差值(即SSE,Sum of Squared Errors)与K值的折线图,确定最优的K值。代码如下: ``` import matplotlib.pyplot as plt from scipy.spatial.distance import cdist import numpy as np # 生成数据集 X = np.random.uniform(low=-10, high=10, size=(100, 2)) # 计算不同K值对应的SSE K_range = range(1, 10) sse = [] for k in K_range: kmeans = KMeans(n_clusters=k, random_state=0).fit(X) sse.append(sum(np.min(cdist(X, kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0]) # 绘制折线图 plt.plot(K_range, sse, 'bx-') plt.xlabel('Number of clusters') plt.ylabel('SSE') plt.title('Elbow Method For Optimal k') plt.show() ``` 在绘制的折线图中,选择拐点处的K值作为最优的簇数。 选择完簇数后,就可以利用KMeans模块进行聚类了。代码如下: ``` # 将数据集聚类为3个簇 kmeans = KMeans(n_clusters=3, random_state=0).fit(X) # 绘制聚类结果图 plt.scatter(X[:, 0], X[:, 1], c=kmeans.labels_) plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], marker='x', color='black', s=100, linewidths=3) plt.title('K-means Clustering') plt.show() ``` 其中,kmeans.labels_为数据点所被聚到的簇的标号,kmeans.cluster_centers_为聚类中心。 以上就是利用Python实现K-means聚类算法的基本步骤,通过手肘法选择最优簇数,然后利用KMeans模块进行聚类,最后绘制聚类结果图。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值