#聚类算法是一种无监督学习算法,也就是只有特征而没有标签,我们要做的就是把特征相似的聚类到一起:实际应用可以做图片颜色特征的降维:
a.K-means聚类算法(无监督学习:):
①算法概念
KMeans算法是将N个样本的特征矩阵划分为K个无交集的簇;簇中的均值通常被称为这个簇的质心;随机/有选择的抽取K个质心-》开始循环-》将每个样本点分配到离他们最近的质心,生成K个簇-》对每个簇计算所有被分到该簇的样本点平均值作为新的质心-》当质心不再变化,迭代停止,聚类完成;
从上面可以看出,质心的选择及K的选择会影响最终的聚类效果。
②.算法思路:视频讲解
要求:组内差异小,组间差异大;欧式距离(质心均值),曼哈顿距离(质心中位数),余弦距离(质心均值);簇内平方和:inertia,KMeans追求的是求解能让inertia(簇内平方和)最小化的质心;我们一般使用欧氏距离,见下图:
#1.轮廓系数(主要使用的方式:越接近1越好):评价聚类的效果的方式:b簇外差异,a簇内差异:
#2.除轮廓系数还有很多评估指标,主要介绍卡林斯基-哈拉巴斯指数:越大越好,比轮廓系数的优势是计算快,缺点是无上限:
③优缺点:
优点:算法容易理解,聚类效果不错;具有出色的速度;当簇近似高斯分布时,效果比较好
缺点:需要自己确定K值,k值的选定是比较难确定;对初始中心点敏感
不适合发现非凸形状的簇或者大小差别较大的簇;特殊值/离群值对模型的影响比较大。
④.代码实例1(基于轮廓系数来寻找合适的质心个数):
#1.基于轮廓系数来选择质心个数:n_clusters
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples,silhouette_score
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
#首先设定我们要分的簇数:
n_clusters = 4
#创建一个画布,画布上面有一行两列:
fig,(ax1,ax2) = plt.subplots(1,2)
#画布尺寸:
fig.set_size_inches(18,7)
from sklearn.datasets import make_blobs
#a.自己创建数据集:
x,y = make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
#要做什么:
'''
第一个图是我们轮廓系数的图像,是由各个簇的轮廓系数组成的横向条形图;
横坐标是轮廓系数的值,纵坐标是我们每个样本
'''
#x轴取值[-0.1,1]
ax1.set_xlim([-0.1,1])
#y轴取值:[0,x.shape[0]],每个簇的间隔:(n_clusters+1)*10
ax1.set_ylim(0,x.shape[0]+(n_clusters+1)*10)
#建模:调整好聚类的标签:
clusterer = KMeans(n_clusters=n_clusters,random_state=10).fit(x)
cluster_labels = clusterer.labels_
#调整轮廓系数:
silhoustte_avg = silhouette_score(x,cluster_labels)
print("For n_clusters = ",n_clusters,"The average silhouette_score is:",silhoustte_avg)
#调用silhouette_samples,返回每个样本点的轮廓系数,这就是我们的横坐标:
sample_silhouette_values = silhouette_samples(x,cluster_labels)
#设定y轴上的初始值:
y_lower = 10
#接下来对每个簇进行循环:
for i in range(n_clusters):
#从每个样本的轮廓系数取出第i个簇的轮廓系数,并对他们进行排序
ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels==i]
#注意,.sort()这个命令会直接改变原数据顺序
ith_cluster_silhouette_values.sort()
#可以查看这个簇中究竟有多少个样本:
size_cluster_i = ith_cluster_silhouette_values.shape[0]
#这一个簇在y轴的取值,应该由y_lower开始,到初始值+这个簇中的样本数量结束y_upper
y_upper = y_lower + size_cluster_i
#每个簇生成不同的颜色:nipy_spectral中任意小数代表一个颜色
color = cm.nipy_spectral(float(i)/n_clusters)
# 开始填充子图1:参数:纵坐标下线,横坐标上线,柱状图颜色
ax1.fill_betweenx(np.arange(y_lower, y_upper)
, ith_cluster_silhouette_values
, facecolor=color
, alpha=0.7
)
#为每个簇的轮廓系数上写上簇的编号,并显示在坐标轴的中间位置
#text用法:显示编号位置的横坐标,显示编号位置的纵坐标,要显示的编号内容
ax1.text(-0.05
,y_lower+0.5*size_cluster_i
,str(i)
)
#保证每个簇之间存在空隙:
y_lower = y_upper + 10
#给图一加上标题,横坐标,纵坐标标签:
ax1.set_title("The silhouette plot for the various clusters.")
ax1.set_xlabel("The silhouette coefficient values")
ax1.set_ylabel("Cluster label")
#把整个数据集上的轮廓系数的均值以虚线的形式放入我们的图中:
ax1.axvline(x=silhoustte_avg,color="red",linestyle="--")
#让y轴不显示刻度:
ax1.set_yticks([])
#让x轴上的刻度显示为我们规定的列表:
ax1.set_xticks([-0.1,0,0.2,0.4,0.6,0.8,1.0])
#########开始处理第二个图:
#首先获取颜色:
colors = cm.nipy_spectral(cluster_labels.astype(float)/n_clusters)
#首先绘制点的分布:
ax2.scatter(x[:,0],x[:,1]
,marker="o"
,s=8
,c=colors
)
#把质心放入图片:
centers = clusterer.cluster_centers_
ax2.scatter(centers[:,0],centers[:,1]
,marker="x"
,c="red"
,alpha=1
,s=200
)
#为图二设置标题,横坐标,纵坐标标题:
ax2.set_title("The visualization of the clustered data.")
ax2.set_xlabel("Feature space for the 1st feature")
ax2.set_ylabel("Feature space for the 2nd feature")
#为整个图设置标题:
plt.suptitle(("Silhouette analysis for KMeans clustering on sample data"
"with n_clusters = %d"% n_clusters)
,fontsize=14,fontweight="bold")
plt.show()
#5,聚类算法用于降维:
#导库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
#对两个序列中的点进行距离匹配的函数
from sklearn.metrics import pairwise_distances_argmin
#导入图片数据所需要的类:
from sklearn.datasets import load_sample_image
#对数据尽心重新随机排列
from sklearn.utils import shuffle
#实例化,导入颐和园的图片
china = load_sample_image("china.jpg")
#uint8 (427, 640, 3):长度-宽度-像素; [174 201 231] :这里图像使用RGB编码,每个像素由三个数字定义。
# print(china.dtype,china.shape,china[0][0],china)
#包含多少种不同颜色呢,三维变成二维:
newimage = china.reshape((427*640,3))
#查看一下数据的个数:
import pandas as pd
'''
在pandas中如何使用drop_duplicates进行去重。
df.drop_duplicates(subset=['A','B'],keep='first',inplace=True)
subset: 输入要进行去重的列名,默认为None
keep: 可选参数有三个:‘first’、 ‘last’、 False, 默认值 ‘first’。其中,
first表示: 保留第一次出现的重复行,删除后面的重复行。
last表示: 删除重复项,保留最后一次出现。
False表示: 删除所有重复项。
inplace:布尔值,默认为False,是否直接在原数据上删除重复项或删除重复项后返回副本。
'''
newimage = pd.DataFrame(newimage).drop_duplicates().shape
# #图像可视化:
# plt.figure(figsize=(15,15))
# plt.imshow(china)
# plt.show()
# print(newimage)
# #查看另一张图片:
# flower = load_sample_image("flower.jpg")
# #图像可视化:
# plt.figure(figsize=(15,15))
# plt.imshow(flower)
# plt.show()
'''
目的:颐和园图片有9W种颜色,我们要做的事情,就是
通过聚类,把图片颜色缩减为64种,看图片是否能正确
显示。
'''
n_clusters = 64
#plt.imshow在浮点数上表现优异,我们先转换为浮点数;
#然后对浮点数进行压缩至[0-1]之间处理;
china = np.array(china,dtype=np.float64)/china.max()
#把China从图像格式转化为矩阵格式:
w,h,d = original_shape = tuple(china.shape)
assert d == 3 #要求必须等于3,如果不等于就报错
image_array = np.reshape(china,(w*h,d))
#可以训练数据了,先用1000个数据寻找质心
image_array_sample = shuffle(image_array,random_state=0)[:1000]
kmeans = KMeans(n_clusters=n_clusters,random_state=0).fit(image_array_sample)
# print(kmeans.cluster_centers_.shape)
#找出质心后,按照已存在的质心对所有数据进行聚类:
labels = kmeans.predict(image_array)
print(labels.shape)
#使用质心代替原来的样本:
image_kmeans = image_array.copy()
for i in range(w*h):
image_kmeans[i] = kmeans.cluster_centers_[labels[i]]
#数据还原为图片格式:
image_kmeans = image_kmeans.reshape(w,h,d)
print(image_kmeans.shape)
plt.figure(figsize=(15,15))
plt.imshow(image_kmeans)
plt.show()
#另一种方式实现随机矢量量化:
centroid_random = shuffle(image_array,random_state=0)[:n_clusters]
#pairwise_distances_argmin用来计算image_array中到centroid_random点的距离,并返回image_array形状相同的,centroid_random中最近样本点的值。
labels_random = pairwise_distances_argmin(centroid_random,image_array,axis=0)
#使用随机质心替换所有样本:
image_random = image_array.copy()
for i in range(w*h):
image_random[i] = centroid_random[labels_random[i]]
#恢复图片结构:
image_random = image_random.reshape(w,h,d)
plt.figure(figsize=(15,15))
plt.imshow(image_random)
plt.show()
原图:
K-Means聚类后的图片:颜色特征聚类后被压缩:
另一种方式聚类降维:
#对两个序列中的点进行距离匹配的函数
from sklearn.metrics import pairwise_distances_argmin
pairwise_distances_argmin用来计算image_array中到centroid_random点的距离,并返回image_array形状相同的,centroid_random中最近样本点的值:使用随机质心替换所有样本:可以看出K-Means聚类的效果还是不错的:
以上就介绍了聚类的实例及聚类的一些概念,相信看完之后会有一点点感觉了。
持续更新,,,