使用sk-learn库实现k-means算法对iris数据分类
一、释义
首先对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'))
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgheibi
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13