基于Python的人工智能应用案例系列(5):手写数字聚类
在本篇文章中,我们使用K-Means算法对手写数字数据集进行了无监督的聚类分析。尽管没有使用任何标签信息,K-Means仍然能够找到具有代表性的簇,并且通过调整簇标签后,我们可以获得较高的聚类准确率。进一步使用t-SNE进行降维后,聚类效果得到了进一步提升。这展示了无监督学习在模式发现和数据预处理中的强大应用。期待您继续关注本系列的更多案例!欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言
在本篇文章中,我们将使用K-Means聚类算法,尝试在没有标签信息的情况下,对手写数字数据集进行聚类。K-Means是一种无监督学习算法,可以自动将数据分成若干簇,而不需要事先知道每个数据点的类别。这种方法在面对新数据集时,特别是没有先验标签信息时,能够帮助我们发现数据中的潜在模式。
案例背景
我们将使用Scikit-Learn中的digits数据集。该数据集包含1,797个手写数字样本,每个样本为8×8像素的图像,被展平为64维的向量。目标是使用K-Means将这些手写数字分成10个簇(因为我们知道有10个数字类别),并观察模型在没有标签的情况下是否能识别出相似的数字。
1. 加载数据
首先,我们加载数据集并检查其形状。
from sklearn.datasets import load_digits
# 加载手写数字数据集
digits = load_digits()
print(digits.data.shape) # 输出 (1797, 64)
数据集包含1,797个样本,每个样本有64个特征,分别表示8x8图像中每个像素的亮度。
2. 使用K-Means进行聚类
接下来,我们使用K-Means聚类算法,将数据分成10个簇。
from sklearn.cluster import KMeans
# 使用K-Means聚类算法,设置簇的数量为10
kmeans = KMeans(n_clusters=10, random_state=0, n_init='auto')
clusters = kmeans.fit_predict(digits.data)
print(kmeans.cluster_centers_.shape) # 输出 (10, 64)
聚类完成后,结果是10个簇,每个簇的中心是一个64维的点。我们可以将这些簇中心视为聚类中“典型”的手写数字。
3. 可视化聚类中心
接下来,我们可视化K-Means算法得到的簇中心,这些簇中心可以看作每个簇中最具代表性的数字。
import matplotlib.pyplot as plt
# 可视化簇中心
fig, ax = plt.subplots(2, 5, figsize=(8, 3))
centers = kmeans.cluster_centers_.reshape(10, 8, 8)
for axi, center in zip(ax.flat, centers):
axi.imshow(center, cmap=plt.cm.binary)
从可视化中,我们可以看到,尽管没有标签信息,K-Means还是能够找到一些类似数字的簇中心。例如,某些簇中心看起来像“0”或“1”,但也有一些不太明显的,如“8”。
4. 匹配簇与真实标签
由于K-Means算法并不知道簇对应的是哪个具体的数字,因此簇标签与真实标签的顺序可能是打乱的。我们可以通过将每个簇的预测标签与真实标签对比,重新调整这些标签。
import numpy as np
from scipy.stats import mode
from sklearn.metrics import confusion_matrix, accuracy_score
import seaborn as sns
# 匹配聚类标签与真实标签
pred = np.zeros_like(clusters)
for i in range(10):
mask = (clusters == i)
pred[mask] = mode(digits.target[mask])[0]
# 计算准确率
print("Accuracy score: ", accuracy_score(digits.target, pred))
# 绘制混淆矩阵
mat = confusion_matrix(digits.target, pred)
plt.figure(figsize=(16, 5))
sns.heatmap(mat, square=True, annot=True, fmt='d', cbar=False)
plt.xlabel("Predicted")
plt.ylabel("True")
通过匹配标签后,我们可以观察到模型的准确率以及混淆矩阵。结果表明,K-Means能够很好地将数字进行聚类,尽管在某些数字(如“1”和“8”)上可能会产生混淆。
5. 使用t-SNE进行数据预处理
为了进一步提高聚类效果,我们可以尝试使用**t-SNE(t-分布随机邻域嵌入)**算法对数据进行降维。t-SNE是一种非线性降维技术,可以将高维数据映射到低维空间,从而使K-Means能够更好地识别数据中的模式。
from sklearn.manifold import TSNE
# 使用t-SNE进行降维
tsne = TSNE(n_components=2, random_state=0)
projected_X = tsne.fit_transform(digits.data)
# 再次使用K-Means进行聚类
kmeans = KMeans(n_clusters=10, random_state=0)
clusters = kmeans.fit_predict(projected_X)
# 匹配聚类标签与真实标签
pred = np.zeros_like(clusters)
for i in range(10):
mask = (clusters == i)
pred[mask] = mode(digits.target[mask])[0]
# 计算准确率
print("Accuracy score after t-SNE: ", accuracy_score(digits.target, pred))
经过t-SNE降维后,K-Means的聚类准确率有了进一步提高。t-SNE能够帮助我们去除数据中的噪声,从而让K-Means聚类更加准确。
结语
在本篇文章中,我们使用K-Means算法对手写数字数据集进行了无监督的聚类分析。尽管没有使用任何标签信息,K-Means仍然能够找到具有代表性的簇,并且通过调整簇标签后,我们可以获得较高的聚类准确率。进一步使用t-SNE进行降维后,聚类效果得到了进一步提升。这展示了无监督学习在模式发现和数据预处理中的强大应用。
期待您继续关注本系列的更多案例!
如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!
欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。
谢谢大家的支持!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)