坤气学习实验五

import numpy as np
from numpy import random
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

# 定义欧几里得距离计算函数
def dist_euclidean(vec_a, vec_b):
return np.linalg.norm(vec_a - vec_b, ord=2)

# 实现 K-Means 聚类算法
def k_means(dataset, k):
# 获取数据点的个数
m = dataset.shape[0]
# 创建一个 m x 2 的数组,用于存储每个数据点的聚类结果和距离
cluster_dist = np.zeros((m, 2))
# 取前 k 个数据点作为初始质心
centroids = dataset[:k]
# 标记聚类是否发生变化
cluster_changed = True

# 迭代直到聚类不再发生变化
while cluster_changed:
# 重置聚类变化标记
cluster_changed = False
# 遍历每个数据点
for i in range(m):
# 计算当前数据点到每个质心的距离
dist_list = [dist_euclidean(dataset[i], centroids[j]) for j in range(k)]
# 找到距离最小的质心
min_dist = min(dist_list)
min_index = dist_list.index(min_dist)
# 如果数据点的聚类结果发生变化,更新聚类变化标记
if cluster_dist[i, 0] != min_index:
cluster_changed = True
# 更新数据点的聚类结果和距离
cluster_dist[i] = min_index, min_dist

# 更新每个质心的位置
for j in range(k):
# 找到属于第 j 个聚类的所有数据点
points_in_cluster = dataset[np.nonzero(cluster_dist[:, 0] == j)[0]]
# 计算第 j 个聚类的新质心
centroids[j] = np.mean(points_in_cluster, axis=0)

# 返回最终的质心和聚类结果
return centroids, cluster_dist

# 生成 500 个随机数据点
numbers = [[random.randint(100), random.randint(100)] for _ in range(500)]
numbers = np.array(numbers)

# 对不同数量的聚类进行可视化
for k in [2, 3, 4, 5]:
# 进行 K-Means 聚类
centroids, cluster_dist = k_means(numbers, k)
# 定义不同聚类的颜色
colors = ['red', 'blue', 'cyan', 'green', 'black']

# 绘制数据点和质心
for i in range(len(cluster_dist)):
plt.scatter(numbers[i, 0], numbers[i, 1], c=colors[int(cluster_dist[i, 0])], marker='o')
plt.scatter([c[0] for c in centroids], [c[1] for c in centroids], s=80, c='black', marker='+')
plt.title(f'K-Means (k={k})')
plt.show()

# 计算 inertia 随 k 变化的情况
distortions = []
for i in range(1, 10):
# 创建 K-Means 模型,并进行训练
model = KMeans(n_clusters=i, init='k-means++', n_init=10, max_iter=300, tol=1e-04, random_state=0)
model.fit(numbers)
# 记录 inertia 值
distortions.append(model.inertia_)

# 绘制 inertia 随 k 变化的曲线
plt.plot(range(1, 10), distortions, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Distortion')
plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值