• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

使用sk-learn库实现k-means算法对iris数据分类

武飞扬头像
想要上岸的小李
帮助1

一、释义

首先对Iris数据集(鸢尾花数据集)进行简单介绍:

1.它分为三个类别,即Iris setosa(山鸢尾)、Iris versicolor(变色鸢尾)和Iris virginica(弗吉尼亚鸢尾),每个类别各有50个实例。

2.数据集定义了五个属性:sepal length(花萼长)、sepal width(花萼宽)、petal length(花瓣长)、petal width(花瓣宽)、class(类别)。

3.最后一个属性一般作为类别属性,其余属性为数值,单位为厘米。

注:鸢尾花数据集在sklearn中有保存,我们可以直接使用库中的数据集

二、k-means代码原理

        K-means算法是典型的基于距离(欧式距离、曼哈顿距离)的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

1.K-mean算法步骤如下:

   1. 先定义总共有多少个簇类,随机选取K个样本为簇中⼼。
   2.分别计算所有样本到随机选取的K个簇中⼼的距离。
   3.样本离哪个中⼼近就被分到哪个簇中⼼。
   4.计算各个中⼼样本的均值(最简单的⽅法就是求样本每个点的平均值)作为新的簇心。
   5.重复2、3、4直到新的中⼼和原来的中⼼基本不变化的时候,算法结束。

算法结束条件:

    1.当每个簇的质心,不再改变时就可以停止k-menas
    2.当循环次数达到事先规定的次数时,停止k-means

三、解释代码

1.首先导入相应的库和数据

  1.  
    import matplotlib.pyplot as plt
  2.  
    import numpy as np
  3.  
    from sklearn.cluster import KMeans
  4.  
    from sklearn import datasets
  5.  
    from sklearn.model_selection import train_test_split
  6.  
    from sklearn.metrics import accuracy_score, precision_score, recall_score

2. 取部分特征作散点图

取它的petal length(花瓣长)、petal width(花瓣宽)作为特征作图

  1.  
    plt.scatter(iris_X[:50,2],iris_X[:50,3],label='setosa',marker='o')
  2.  
    plt.scatter(iris_X[50:100,2],iris_X[50:100,3],label='versicolor',marker='x')
  3.  
    plt.scatter(iris_X[100:,2],iris_X[100:,3],label='virginica',marker=' ')
  4.  
    plt.xlabel('petal length')
  5.  
    plt.ylabel('petal width')
  6.  
    plt.title("actual result")
  7.  
    plt.legend()
  8.  
    plt.show()

学新通

 3.k均值聚类

1.jupyter notebook已经把k-means方法封装好了 只需要调用即可(这里我们选着k值为3)

  1.  
    estimator = KMeans(n_clusters=3) # 构造聚类器
  2.  
    estimator.fit(X) # 聚类

2.k-means代码细节

  1.  
    class KMeans(object):
  2.  
    def __init__(self, input_data, k):
  3.  
    # data是一个包含所有样本的numpy数组
  4.  
    # data示例,每行是一个坐标
  5.  
    # [[1 2],
  6.  
    # [2 3],
  7.  
    # [3 4]]
  8.  
    self.data = input_data
  9.  
    self.k = k
  10.  
    # 保存聚类中心的索引和类样本的索引
  11.  
    self.centers = []
  12.  
    self.clusters = []
  13.  
    self.capacity = len(input_data)
  14.  
    self.__pick_start_point()
  15.  
     
  16.  
    def __pick_start_point(self):
  17.  
    # 随机确定初始簇心
  18.  
    self.centers = []
  19.  
    if self.k < 1 or self.k > self.capacity:
  20.  
    raise Exception("K值错误")
  21.  
    indexes = random.sample(np.arange(0, self.capacity, step=1).tolist(), self.k)
  22.  
    for index in indexes:
  23.  
    self.centers.append(self.data[index])
  24.  
     
  25.  
    def __distance(self, i, center):
  26.  
    diff = self.data[i] - center
  27.  
    return np.sum(np.power(diff, 2))**0.5
  28.  
     
  29.  
    def __calCenter(self, cluster):
  30.  
    # 计算该簇的中心
  31.  
    cluster = np.array(cluster)
  32.  
    if cluster.shape[0] == 0:
  33.  
    return False
  34.  
    return (cluster.T @ np.ones(cluster.shape[0])) / cluster.shape[0]
  35.  
     
  36.  
    def cluster(self):
  37.  
    changed = True
  38.  
    while changed:
  39.  
    self.clusters = []
  40.  
    for i in range(self.k):
  41.  
    self.clusters.append([])
  42.  
    for i in range(self.capacity):
  43.  
    min_distance = sys.maxsize
  44.  
    center = -1
  45.  
    # 寻找簇
  46.  
    for j in range(self.k):
  47.  
    distance = self.__distance(i, self.centers[j])
  48.  
    if min_distance > distance:
  49.  
    min_distance = distance
  50.  
    center = j
  51.  
    # 加入簇
  52.  
    self.clusters[center].append(self.data[i])
  53.  
    newCenters = []
  54.  
    for cluster in self.clusters:
  55.  
    newCenters.append(self.__calCenter(cluster).tolist())
  56.  
    if (np.array(newCenters) == self.centers).all():
  57.  
    changed = False
  58.  
    else:
  59.  
    self.centers = np.array(newCenters)
学新通

4.绘制k-means结果

  1.  
    # 绘制k-means结果
  2.  
    x0 = X[label_pred == 0]
  3.  
    x1 = X[label_pred == 1]
  4.  
    x2 = X[label_pred == 2]
  5.  
    plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')
  6.  
    plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')
  7.  
    plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker=' ', label='label2')
  8.  
    plt.xlabel('sepal length')
  9.  
    plt.ylabel('sepal width')
  10.  
    plt.legend(loc=2)
  11.  
    plt.show()

学新通

 5.看学习效果

  1.  
    print('准确率:', accuracy_score(y_test, y_pred))
  2.  
    print('精确率:', precision_score(y_test, y_pred, average='weighted'))
  3.  
    print('召回率:', recall_score(y_test, y_pred, average='weighted'))

 学新通

 四、完整代码

  1.  
    import matplotlib.pyplot as plt
  2.  
    import numpy as np
  3.  
    from sklearn.cluster import KMeans
  4.  
    from sklearn import datasets
  5.  
    from sklearn.model_selection import train_test_split
  6.  
    from sklearn.metrics import accuracy_score, precision_score, recall_score
  7.  
     
  8.  
    iris = datasets.load_iris()
  9.  
     
  10.  
    X = iris.data
  11.  
    Y = iris.target
  12.  
    x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=100)
  13.  
     
  14.  
    X = iris.data[:, :4] # #表示我们取特征空间中的4个维度
  15.  
    print(X.shape)
  16.  
    # 绘制数据分布图
  17.  
    plt.scatter(X[:, 0], X[:, 1], c="red", marker='o', label='see')
  18.  
    plt.xlabel('sepal length')
  19.  
    plt.ylabel('sepal width')
  20.  
    plt.legend(loc=2)
  21.  
    plt.show()
  22.  
     
  23.  
    estimator = KMeans(n_clusters=3) # 构造聚类器
  24.  
    estimator.fit(X) # 聚类
  25.  
     
  26.  
    y_pred = estimator.predict(x_test)
  27.  
     
  28.  
    label_pred = estimator.labels_ # 获取聚类标签
  29.  
    # 绘制k-means结果
  30.  
    x0 = X[label_pred == 0]
  31.  
    x1 = X[label_pred == 1]
  32.  
    x2 = X[label_pred == 2]
  33.  
    plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')
  34.  
    plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')
  35.  
    plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker=' ', label='label2')
  36.  
    plt.xlabel('sepal length')
  37.  
    plt.ylabel('sepal width')
  38.  
    plt.legend(loc=2)
  39.  
    plt.show()
  40.  
     
  41.  
    print('准确率:', accuracy_score(y_test, y_pred))
  42.  
    print('精确率:', precision_score(y_test, y_pred, average='weighted'))
  43.  
    print('召回率:', recall_score(y_test, y_pred, average='weighted'))
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgheibi
系列文章
更多 icon
同类精品
更多 icon
继续加载