k-means聚类

k-means是一种无监督学习模型——聚类算法的一种算法。k-means算法可以在不带标签的多维数据集中寻找确定数量的簇。
最优的聚类结果需要符合一下两个假设

* “簇中心点“是属于该簇的所有数据点坐标的算术平均值
* 一个簇的每个点到该簇中心点的距离,比到其他簇中心点的距离短。 #简单演示k-means算法 %matplotlib inline import
matplotlib.pyplotas plt import seaborn as sns;sns.set() import numpy as np from
sklearn.datasets.samples_generatorimport make_blobs x, y = make_blobs(n_samples=
300, centers=4, cluster_std=0.60, random_state=0) from sklearn.cluster import
KMeans kmeans = KMeans(n_clusters=4) kmeans.fit(x) y_kmeans = kmeans.predict(x)
#可视化 plt.scatter(x[:, 0], x[:, 1], c=y_kmeans, cmap='viridis') centers =
kmeans.cluster_centers_ plt.scatter(centers[:,0], centers[:, 1], c='k', s=200,
alpha=0.5)


手动实现一个简单的k-means算法
from sklearn.metrics import pairwise_distances_argmin def find_clusters(x,
n_clusters, rseed=2): #1.随机选择簇中心点 rng = np.random.RandomState(rseed) i =
rng.permutation(x.shape[0])[:n_clusters] centers = x[i] while True: #
2a.给于最近的中心执行标签 labels = pairwise_distances_argmin(x, centers) #2b.根据点的平均值找到新的中心
new_centers =np.array([x[labels==i].mean(0) for i in range(n_clusters)])
#2c.确认收敛 if np.all(centers == new_centers): break centers = new_centers return
centers, labels center, labels = find_clusters(x,4) plt.scatter(x[:, 0], x[:, 1
], c=labels, s=50, cmap='viridis')


使用核k-means算法实现非线性聚类
#k-means算法遇到非线性边界时会失效 from sklearn.datasets import make_moons x, y =
make_moons(200, noise=.05, random_state=0) labels = KMmeans(2, random_state=0
).fit_predict(x) plt.scatter(x[:,0], x[:, 1], c=labels, s=50, cmap='viridis')

#通过一个核变换将数据投影到更高维空间,投影后的数据线性分离成为可能 from sklearn.cluster import
SpectralClustering model = SpectralClustering(n_clusters=2, affinity=
'nearest_neighbors',assign_labels='kmeans') labels = model.fit_predict(x)
plt.scatter(x[:,0], x[:, 1], c=labels, s=50, cmap='viridis')


用k-means算法处理手写数字
### 用k-means算法处理手写数字 from sklearn.datasets import load_digits digits =
load_digits() kmeans = KMeans(n_clusters=10, random_state=0) clusters =
kmeans.fit_predict(digits.data)#可视化10类中的中心点——最具有代表性的10个数字 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.set(xticks=[], yticks=[])
axi.imshow(center, interpolation='nearest', cmap=plt.cm.binary)

#将每个学习到的簇标签和真实标签进行匹配 from scipy.stats import mode labels =
np.zeros_like(clusters)for i in range(10): mask = (clusters == i) labels[mask]
= mode(digits.target[mask])[0] #计算分类的准确率 from sklearn.metrics import
accuracy_score accuracy_score(digits.target, labels)#输出结果: 0.7935447968836951
#可视化分类的混淆矩阵 from sklearn.metrics import confusion_matrix mat =
confusion_matrix(digits.target, labels) sns.heatmap(mat.T, square=True, annot=
True, fmt='d', cbar=False, yticklabels=digits.target_names,
xticklabels=digits.target_names) plt.xlabel('true label') plt.ylabel('predicted
label')


使用t-分布邻域算法对数据进行预处理
#使用t-分布邻域嵌入算法在执行k-means之前对数据进行预处理。t-SNE是一个非线性嵌入算法,特别擅长保留簇中的数据点 from
sklearn.manifoldimport TSNE #投影数据:这一步将要运行几秒钟 tsne = TSNE(n_components=2, init=
'pca', random_state=0) digits_proj = tsne.fit_transform(digits.data) #计算类
kmeans = KMeans(n_clusters=10, random_state=0) clusters =
kmeans.fit_predict(digits_proj)#排列标签 labels = np.zeros_like(clusters) for i in
range(10): mask = (clusters == i) labels[mask] = mode(digits.target[mask])[0]
#计算分类的准确率 from sklearn.metrics import accuracy_score
accuracy_score(digits.target, labels)#输出结果: 0.9371174179187535
将k-means用于色彩压缩
#将k-means用于色彩压缩 #需要安装pillow图像程序包 from sklearn.datasets import
load_sample_image china = load_sample_image("china.jpg") ax =
plt.axes(xticks=[], yticks=[]) ax.imshow(china)

#将像素数据转换成三维颜色空间中的一群数据点 data = china / 255.0 #转换为0~1区间 data = data.reshape(427*
640, 3) #在颜色空间中对这些像素进行可视化 def plot_pixels(data, title, colors=None, N=10000): if
colorsis None: colors = data #随机选择一个子集 rng = np.random.RandomState(0) i =
rng.permutation(data.shape[0])[:N] colors = colors[i] R, G, B = data[i].T fig,
ax = plt.subplots(1, 2, figsize=(16, 6)) ax[0].scatter(R, G, color=colors,
marker='.') ax[0].set(xlabel='Red', ylabel='Blue', xlim=(0, 1), ylim=(0, 1)) ax[
1].scatter(R, G, color=colors, marker='.') ax[1].set(xlabel='Red', ylabel='Blue'
, xlim=(0, 1), ylim=(0, 1)) fig.suptitle(title, size=20) plot_pixels(data,
title='Input color space: 16 million possible colors')

#对像素空间使用k-means聚类,将1600万种颜色(255x255x255=16581375)缩减到16种颜色。
#因为我们处理的是非常大的数据集,所以将使用MiniBatchKMeans算法,这种算法速度比k-means速度快 from sklearn.cluster
import MiniBatchKMeans kmeans = MiniBatchKMeans(16) kmeans.fit(data) new_colors
= kmeans.cluster_centers_[kmeans.predict(data)] plot_pixels(data,
colors=new_colors, title='Reduced color space:16 colors')

#用计算结果对原始像素重新着色,即每个像素被指定为距离其距离最近的簇中心点的颜色。 china_recolored =
new_colors.reshape(china.shape) fig, ax = plt.subplots(1, 2, figsize=(16, 6),
subplot_kw=dict(xticks=[], yticks=[])) fig.subplots_adjust(wspace=0.05) ax[0
].imshow(china) ax[0].set_title("Original Image", size=16) ax[1
].imshow(china_recolored) ax[1].set_title('16-color Image', size=16)