一、释义

首先对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.首先导入相应的库和数据

import matplotlib.pyplot as plt

import numpy as np

from sklearn.cluster import KMeans

from sklearn import datasets

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score, precision_score, recall_score

2. 取部分特征作散点图

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

plt.scatter(iris_X[:50,2],iris_X[:50,3],label='setosa',marker='o')

plt.scatter(iris_X[50:100,2],iris_X[50:100,3],label='versicolor',marker='x')

plt.scatter(iris_X[100:,2],iris_X[100:,3],label='virginica',marker='+')

plt.xlabel('petal length')

plt.ylabel('petal width')

plt.title("actual result")

plt.legend()

plt.show()

 3.k均值聚类

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

estimator = KMeans(n_clusters=3) # 构造聚类器

estimator.fit(X) # 聚类

2.k-means代码细节

class KMeans(object):

def __init__(self, input_data, k):

# data是一个包含所有样本的numpy数组

# data示例,每行是一个坐标

# [[1 2],

# [2 3],

# [3 4]]

self.data = input_data

self.k = k

# 保存聚类中心的索引和类样本的索引

self.centers = []

self.clusters = []

self.capacity = len(input_data)

self.__pick_start_point()

def __pick_start_point(self):

# 随机确定初始簇心

self.centers = []

if self.k < 1 or self.k > self.capacity:

raise Exception("K值错误")

indexes = random.sample(np.arange(0, self.capacity, step=1).tolist(), self.k)

for index in indexes:

self.centers.append(self.data[index])

def __distance(self, i, center):

diff = self.data[i] - center

return np.sum(np.power(diff, 2))**0.5

def __calCenter(self, cluster):

# 计算该簇的中心

cluster = np.array(cluster)

if cluster.shape[0] == 0:

return False

return (cluster.T @ np.ones(cluster.shape[0])) / cluster.shape[0]

def cluster(self):

changed = True

while changed:

self.clusters = []

for i in range(self.k):

self.clusters.append([])

for i in range(self.capacity):

min_distance = sys.maxsize

center = -1

# 寻找簇

for j in range(self.k):

distance = self.__distance(i, self.centers[j])

if min_distance > distance:

min_distance = distance

center = j

# 加入簇

self.clusters[center].append(self.data[i])

newCenters = []

for cluster in self.clusters:

newCenters.append(self.__calCenter(cluster).tolist())

if (np.array(newCenters) == self.centers).all():

changed = False

else:

self.centers = np.array(newCenters)

4.绘制k-means结果

# 绘制k-means结果

x0 = X[label_pred == 0]

x1 = X[label_pred == 1]

x2 = X[label_pred == 2]

plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')

plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')

plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker='+', label='label2')

plt.xlabel('sepal length')

plt.ylabel('sepal width')

plt.legend(loc=2)

plt.show()

 5.看学习效果

print('准确率:', accuracy_score(y_test, y_pred))

print('精确率:', precision_score(y_test, y_pred, average='weighted'))

print('召回率:', recall_score(y_test, y_pred, average='weighted'))

 

 四、完整代码

import matplotlib.pyplot as plt

import numpy as np

from sklearn.cluster import KMeans

from sklearn import datasets

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score, precision_score, recall_score

iris = datasets.load_iris()

X = iris.data

Y = iris.target

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=100)

X = iris.data[:, :4] # #表示我们取特征空间中的4个维度

print(X.shape)

# 绘制数据分布图

plt.scatter(X[:, 0], X[:, 1], c="red", marker='o', label='see')

plt.xlabel('sepal length')

plt.ylabel('sepal width')

plt.legend(loc=2)

plt.show()

estimator = KMeans(n_clusters=3) # 构造聚类器

estimator.fit(X) # 聚类

y_pred = estimator.predict(x_test)

label_pred = estimator.labels_ # 获取聚类标签

# 绘制k-means结果

x0 = X[label_pred == 0]

x1 = X[label_pred == 1]

x2 = X[label_pred == 2]

plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')

plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')

plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker='+', label='label2')

plt.xlabel('sepal length')

plt.ylabel('sepal width')

plt.legend(loc=2)

plt.show()

print('准确率:', accuracy_score(y_test, y_pred))

print('精确率:', precision_score(y_test, y_pred, average='weighted'))

print('召回率:', recall_score(y_test, y_pred, average='weighted'))

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: