文章目录
前言
本文参照唐宇迪机器学习聚类算法入门教程,具体视频指路:唐宇迪机器学习python
详细构建了KMeans算法的建模过程,采用鸢尾花数据集进行训练及数据分类可视化
一、KMeans算法原理
可在以下网站进行KMeans算法可视化:
链接: link
二、KMeans算法代码流程
新建一个kmeans.py文件
1.引入库
代码如下:
import numpy as np
2.新建KMeans 类
Python代码定义了一个名为 KMeans 的类,用于执行K-均值聚类算法
2.1构造函数
代码如下:
class KMeans:
def __init__(self, data, num_clusters): # (数据样本,簇分类数)
self.data = data
self.num_clusters = num_clusters
self.num_examples = data.shape[0] # 赋值样本数
2.2 质心初始化
@staticmethod
def centroids_init(data, num_clustres): # 质心初始化
num_examples = data.shape[0]
random_ids = np.random.permutation(num_examples)
centroids = data[random_ids[:num_clustres], :]
return centroids
代码解析:
1 data.shape[0]
data: 这是一个 ndarray 对象,可以是任何形状的多维数组。
shape: 这是一个属性,它返回一个元组,表示数组在每个维度上的大小。
0: 这是 shape 元组的索引。在 Python 中,索引通常从 0 开始。所以 shape[0] 表示元组中的第一个元素,即数组的第一个维度的大小。
2 np.random.permutation(num_examples)
用于随机生成排列;与此用法相同的还有np.random.shuffle 会就地修改原数组,
而 np.random.permutation 返回的是一个新的数组,原数组不受影响。
3 centroids = data[random_ids[:num_clustres],:]
1 data 是一个二维数组,通常情况下,每一行代表一个数据点,每一列代表一个特征。
2 random_ids 是一个由 np.random.permutation 函数生成的数组,包含从 0 到 data.shape[0]-1(即数据集中的样本数量减一)的所有整数的随机排列。
3 random_ids[:num_clusters] 提取 random_ids 数组中的前 num_clusters 个元素。这些元素代表了随机选定的数据点的索引,用于作为聚类的初始质心。
4 data[random_ids[:num_clusters], :]这部分代码利用随机选定的索引从 data 数组中选取特定的行。data[random_ids[:num_clusters], :] 表示选择 data 数组中 random_ids[:num_clusters] 指定的行,其中 : 表示选择这些行的所有列。
5 返回结果是一个新的数组,其中包含了作为初始质心的随机选定的数据点
2.3 找到离每个点最近的质心
@staticmethod
def centroids_find_closest(data, centroids): # 找到离每个点最近的质心
num_examples = data.shape[0]
num_centroids = centroids.shape[0] # 中心点个数
# closest_centroids_ids = np.zeros((num_examples, 1))
closest_centroids_ids = np.zeros(num_examples)
# distance = np.zeros((num_centroids, 1)) # 每个点到质心距离数组初始化
distance = np.zeros(num_centroids)
for example_index in range(num_examples):
for centroid_index in range(num_centroids):
distance_diff = data[example_index, :] - centroids[centroid_index, :]
distance[centroid_index] = np.sum(distance_diff ** 2)
closest_centroids_ids[example_index] = np.argmin(distance)
return closest_centroids_ids
2.4 重新定义质心
@staticmethod
def centroids_compute(data, closest_centroids_ids, num_clusters):
num_features = data.shape[1]
centroids = np.zeros((num_clusters, num_features))
for centroid_id in range(num_clusters): # 遍历每个中心点,重新定义
closest_ids = closest_centroids_ids == centroid_id
# closest_ids = (closest_centroids_ids.flatten() == centroid_id)
centroids[centroid_id] = np.mean(data[closest_ids], axis=0)
return centroids
2.5 训练kmeans模型
def train(self, max_iterations): # 最大迭代次数
# self.max_iterations = max_iterations
# 1. 先随机选择K个中心点
centroids = KMeans.centroids_init(self.data, self.num_clusters)
# 2. 计算每个点到中心点的距离
closest_centroids_ids = np.empty((self.num_examples, 1)) # 每个点到质心的距离初始化
for _ in range(max_iterations):
# 3. 计算每个点最小距离的质心索引
closest_centroids_ids = KMeans.centroids_find_closest(self.data, centroids)
# 4. 中心点位置更新
centroids = KMeans.centroids_compute(self.data, closest_centroids_ids, self.num_clusters)
return centroids, closest_centroids_ids
三、鸢尾花数据集可视化
新建一个python文件,用于实例数据的训练
3.1 导入需要的python库
import pandas as pd
import matplotlib.pyplot as plt
from kmeans import KMeans
3.2 读取数据集
data = pd.read_csv('iris.csv')
iris_types = ['setosa', 'versicolor', 'virginica']
x_axis = 'Petal.Length'
y_axis = 'Petal.Width';
3.3 设置kmeans参数
num_examples = data.shape[0]
x_train = data[[x_axis, y_axis]].values
num_clusters = 3
max_iterations = 50
3.4 训练实例鸢尾花
k_means = KMeans(x_train, num_clusters)
centroids, closest_centroids_ids = k_means.train(max_iterations);
3.4 可视化聚类结果
plt.title('Iris Flower Classification - KMeans Clusters')
# 绘制聚类得到的质心
colors = ['blue', 'green', 'red'] # 不同的颜色用于不同的质心
for centroid_id, centroid in enumerate(centroids):
plt.scatter(*centroid, color=colors[centroid_id], marker='x', s=100,
label=f'Centroid {centroid_id}')
# 绘制根据KMeans分配的聚类结果
for i in range(len(x_train)):
plt.scatter(x_train[i, 0], x_train[i, 1], color=colors[int(closest_centroids_ids[i])], s=20)
plt.legend()
plt.xlabel(x_axis)
plt.ylabel(y_axis)
以标签分类可视化数据集做参考
plt.title('label known')
for iris_type in iris_types:
subset = data[data['Species'] == iris_type]
plt.scatter(subset[x_axis], subset[y_axis], label=iris_type)
plt.legend()
plt.xlabel(x_axis)
plt.ylabel(y_axis);
聚类结果如下,可以看到,聚类结果与原数据集的分类效果一致
总结
文章创作不易,点赞收藏可分享源码链接哦!