IT教程 ·

机械进修——聚类算法

谈谈Vue的递归组件

本文重要解说的聚类算法有:k均值算法、均值漂移算法、凝结条理算法、DBSCAN密度聚类算法,还引见了聚类算法机能目标——表面系数。

聚类(cluster)与分类(class)差别,分类是有监视进修模子,聚类属于无监视进修模子。聚类考究运用一些算法把样本离别为n个群落。平常状况下,这类算法都须要盘算欧几里得间隔

$$P(x_1) - Q(x_2): |x_1-x_2| = sqrt{(x_1-x_2)^2}
P(x_1,y_1) - Q(x_2,y_2): sqrt{(x_1-x_2)^2+(y_1-y_2)^2}
P(x_1,y_1,z_1) - Q(x_2,y_2,z_2): sqrt{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2} $$

欧氏间隔:用两个样本对应特性值之差的平方和的平方根,来示意这两个样本的相似性。

K均值算法

第一步:随机挑选k个样本作为k个聚类的中间,盘算每一个样本到各个聚类中间的欧氏间隔,将该样本分配到与之间隔近来的聚类中间地点的种别中。

第二步:根据第一步所获得的聚类离别,离别盘算每一个聚类的多少中间,将多少中间作为新的聚类中间,反复第一步,直到盘算所得多少中间聚类中间重合或靠近重合为止

注重:

  1. 聚类数$k$必需事前已知。借助某些评价目标(欧式间隔),优选最好的聚类数。
  2. 聚类中间的初始挑选会影响到终究聚类离别的结果。初始中间只管挑选间隔较远的样本。

K均值算法相干API:

import sklearn.cluster as sc

model = sc.KMeans(n_clusters=4)     # n_clusters: 聚类数
# 练习模子,不停调解聚类中间,直到终究聚类中间稳固章聚类完成
model.fit(x)
centers = model.cluster_centers_    # 猎取练习结果的聚类中间
labels = model.labels_              # 每一个样本的聚类的种别标签

案例:加载数据集,基于K均值算法完成样本的聚类。

import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as plt

x = np.loadtxt('../machine_learning_date/multiple3.txt', delimiter=',')
model = sc.KMeans(n_clusters=4)     # 构建质心数目为4的聚类模子
model.fit(x)                        # 练习模子
pred_y = model.labels_              # 返回每一个样本的聚类的种别标签: 0/1/2/3
centers = model.cluster_centers_    # 返回一切的聚类中间样本
print(centers)
# 绘制分类边界线
n = 500
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
# 生成网格坐标矩阵
grid_x = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
# 按列拼接数组
flat_x = np.column_stack((grid_x[0].ravel(), grid_x[1].ravel()))
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape)

plt.figure('K-Means Cluster', facecolor='lightgray')
plt.title('K-Means Cluster', fontsize=14)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
plt.scatter(x[:, 0], x[:, 1], c=pred_y, cmap='brg', s=80)
plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='+', s=500)

plt.show()

机械进修——聚类算法 IT教程 第1张

图象量化

K-Means聚类算法能够应用于图象量化范畴。经由历程K-Means算法能够把一张图象所包括的色彩值举行聚类离别,求每一种别的均匀值后再从新生成新的图象。能够到达图象降维的目标。这个历程称为图象量化。图象量化能够更好的保存图象的表面,下降机械辨认图象表面的难度。

import sklearn.cluster as sc
import matplotlib.pyplot as plt
import scipy.misc as sm


# 经由历程K均值聚类量化 图象中的"色彩"
def quant(image, n_clusters):
    # x代表一切图片像素点的亮度值数组
    x = image.reshape(-1, 1)
    model = sc.KMeans(n_clusters=n_clusters)
    model.fit(x)
    # 当n_clusters=2时,label含:0/1
    # 当n_clusters=3时,label含:0/1/2
    # 当n_clusters=4时,label含:0/1/2/3
    y = model.labels_
    # 猎取聚类中间 [30, 70, 110, 190]
    centers = model.cluster_centers_.ravel()        # 猎取质心并变成一维数组
    return centers[y].reshape(image.shape)

# 读取灰度图
original = sm.imread('../machine_learning_date/lily.jpg', True)
quant2 = quant(original, 2)
quant3 = quant(original, 3)
quant4 = quant(original, 4)
plt.figure('Image Quant', facecolor='lightgray')
plt.subplot(221)
plt.title('Original', fontsize=14)
plt.axis('off')
plt.imshow(original, cmap='gray')
plt.subplot(222)
plt.title('Quant-2', fontsize=14)
plt.axis('off')
plt.imshow(quant2, cmap='gray')
plt.subplot(223)
plt.title('Quant-3', fontsize=14)
plt.axis('off')
plt.imshow(quant3, cmap='gray')
plt.subplot(224)
plt.title('Quant-4', fontsize=14)
plt.axis('off')
plt.imshow(quant4, cmap='gray')
plt.tight_layout()
plt.show()

机械进修——聚类算法 IT教程 第2张

均值漂移算法

假设在一个有N个样本点的特性空间,初始一个中间点,盘算在设置的半径圆形空间内的一切点与中间点的向量,盘算全部圆形空间内一切向量的均匀值,获得一个偏移均值,将中间点挪动到偏移值位置,反复挪动,直到满足肯定前提完毕,终究挪动的中间点就是聚类的中间,再根据每一个样本间隔各个中间的间隔,挑选近来聚类中间所属的种别作为该样本的种别。

机械进修——聚类算法 IT教程 第3张

均值漂移算法的特性:

  1. 聚类数没必要事前已知,算法会自动辨认出统计直方图的中间数目。
  2. 聚类中间不根据于最初假定,聚类离别的结果相对稳固。
  3. 样本空间应当恪守某种几率散布划定规矩,不然算法的准确性会大打折扣。

均值漂移算法相干API:

# n_samples:样本数目
# quantile:量化宽度
# 盘算出半径(带宽)
bw = sc.estimate_bandwidth(x, n_samples=len(x), quantile=0.1) 
# 均值漂移聚类器
model = sc.MeanShift(bandwidth=bw, bin_seeding=True)
model.fit(x)

案例:加载,运用均值漂移算法对样本完成聚类离别。

"""均值漂移"""
import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as plt

x = np.loadtxt('../machine_learning_date/multiple3.txt', delimiter=',')
# 构建聚类模子
bw = sc.estimate_bandwidth(x, n_samples=len(x), quantile=0.2)   # 盘算出半径(带宽)
model = sc.MeanShift(bandwidth=bw, bin_seeding=True)
model.fit(x)
# 返回每一个样本的聚类的种别标签: 0/1/2/3
pred_y = model.labels_
# 返回一切的聚类中间样本
centers = model.cluster_centers_
print(centers)
# 绘制分类边界线
n = 500
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
grid_x = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
flat_x = np.column_stack((grid_x[0].ravel(), grid_x[1].ravel()))
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape)

plt.figure('K-Means Cluster')
plt.title('K-Means Cluster', fontsize=14)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
plt.scatter(x[:, 0], x[:, 1], c=pred_y, cmap='brg', s=80)
plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='+', s=500)

plt.show()

机械进修——聚类算法 IT教程 第4张

凝结条理算法

起首假定每一个样本都是一个自力的聚类,假如统计出来的聚类数大于希冀的聚类数,则从每一个样本动身寻觅离本身近来的另一个样本,与之群集,构成更大的聚类,同时令总聚类数削减,不停反复以上历程,直到统计出来的聚类数到达希冀值为止。

凝结条理算法的特性:

  1. 聚类数必需事前已知。借助某些评价目标,优选最好的聚类数。
  2. 没有聚类中间的观点,因而只能在练习集合离别聚类,但不能对练习集之外的未知样本肯定其聚类归属。
  3. 在肯定被凝结的样本时,除了以间隔作为前提之外,还能够根据连续性来肯定被群集的样本。

凝结条理算法相干API:

# 凝结条理聚类器
model = sc.AgglomerativeClustering(n_clusters=4)
pred_y = model.fit_predict(x)

案例:从新加载,运用凝结条理算法举行聚类离别。

import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as plt

x = np.loadtxt('../machine_learning_date/multiple3.txt', delimiter=',')
# 凝结条理聚类器
model = sc.AgglomerativeClustering(n_clusters=4)
pred_y = model.fit_predict(x)        # pred_y为x的种别
plt.figure('Agglomerative Cluster', facecolor='lightgray')
plt.title('Agglomerative Cluster', fontsize=14)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.scatter(x[:, 0], x[:, 1], c=pred_y, cmap='brg', s=80)
plt.show()

在肯定被凝结的样本时,除了以间隔作为前提之外,还能够根据连续性来肯定被群集的样本

"""
基于连续性近邻挑选器的凝结条理算法
"""
import numpy as np
import sklearn.cluster as sc
import sklearn.neighbors as nb
import matplotlib.pyplot as plt

n_samples = 500
x = np.linspace(-1, 1, n_samples)
y = np.sin(x * 2 * np.pi)
n = 0.3 * np.random.rand(n_samples, 2)
x = np.column_stack((x, y)) + n     # 按列拼接
# 无连续性的凝结条理聚类器
model_nonc = sc.AgglomerativeClustering(linkage='average', n_clusters=3)
pred_y_nonc = model_nonc.fit_predict(x)
# 近邻挑选器
conn = nb.kneighbors_graph(x, 10, include_self=False)
# 有连续性的凝结条理聚类器
model_conn = sc.AgglomerativeClustering(
    linkage='average', n_clusters=3, connectivity=conn)
pred_y_conn = model_conn.fit_predict(x)
plt.figure('Nonconnectivity', facecolor='lightgray')
plt.title('Nonconnectivity', fontsize=14)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.scatter(x[:, 0], x[:, 1], c=pred_y_nonc, cmap='brg', alpha=0.5, s=30)
plt.figure('Connectivity', facecolor='lightgray')
plt.title('Connectivity', fontsize=14)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.scatter(x[:, 0], x[:, 1], c=pred_y_conn, cmap='brg', alpha=0.5, s=30)
plt.show()

机械进修——聚类算法 IT教程 第5张

机械进修——聚类算法 IT教程 第6张

表面系数

聚类机能的目标:统一个聚类内部的样本要充足麋集,差别聚类之间样本要充足冷淡。

表面系数盘算划定规矩:针对样本空间中的一个特定样本,盘算它与地点聚类别的样本的均匀间隔a,以及该样本与间隔近来的另一个聚类中一切样本的均匀间隔b,该样本的表面系数为(b-a)/max(a, b),将全部样本空间中一切样本的表面系数取算数均匀值,作为聚类离别的机能目标。

表面系数的区间为:[-1, 1]。 -1代表分类结果差,1代表分类结果好。0代表聚类堆叠,没有很好的离别聚类。

表面系数相干API:

import sklearn.metrics as sm
# v:均匀表面系数
# metric:间隔算法:运用欧几里得间隔(euclidean)
v = sm.silhouette_score(输入集, 输出集, sample_size=样本数, metric=间隔算法)

案例:输出KMeans算法聚类离别后的表面系数。

# 打印均匀表面系数
print(sm.silhouette_score( x, pred_y, sample_size=len(x), metric='euclidean'))

DBSCAN密度聚类算法

DBSCAN是基于密度的聚类算法,经由历程将严密相连的样本划为一类,如许就获得了一个聚类种别。经由历程将一切各组严密相连的样本划为各个差别的种别,则我们就获得了终究的一切聚类种别结果。把具有充足高密度的地区离别为镞(统一种别的样本他们之间严密相连,也就是说在该种别恣意样本四周不远处肯定有同种别的样本存在)。并可在噪声的空间数据库中发现外形的聚类。

DBSCAN算法的特性:

  1. 密度聚类算法平常假定种别能够经由历程样本散布的严密水平决议
  2. 事前给定的半径会影响末了的聚类结果,能够借助表面系数挑选较优的计划。
  3. 根据聚类的构成历程,把样本细分为以下三类:

    外周样本:被别的样本群集到某个聚类中,但没法再引入新样本的样本。

    伶仃样本:聚类中的样本数低于所设定的下限,则不称其为聚类,反之称其为伶仃样本。

    中心样本:除了外周样本和伶仃样本之外的样本。

DBSCAN聚类算法相干API:

# DBSCAN聚类器
# eps:半径
# min_samples:聚类样本数的下限,若低于该数值,则称为伶仃样本
model = sc.DBSCAN(eps=epsilon, min_samples=5)
model.fit(x)
# 猎取练习后一切聚类的中心样本的索引数组  
# 能够以此作为掩码,猎取一切的中心样本
indices = model.core_sample_indices_
# 每一个样本的聚类种别标签  [0,1,2,3,0,1,2,3,0,1,2,3,-1]
labels = model.labels_  # 会涌现-1的状况,label=-1的样本就是伶仃样本

案例:修正凝结条理聚类案例,基于DBSCAN聚类算法举行聚类离别,挑选最优半径。

import numpy as np
import sklearn.cluster as sc
import sklearn.metrics as sm
import matplotlib.pyplot as plt

x = np.loadtxt('../machine_learning_date/perf.txt', delimiter=',')
epsilons, scores, models = np.linspace(0.3, 1.2, 10), [], []
for epsilon in epsilons:
    # DBSCAN聚类器
    model = sc.DBSCAN(eps=epsilon, min_samples=5)
    model.fit(x)
    # 盘算表面系数
    score = sm.silhouette_score(
        x, model.labels_, sample_size=len(x), metric='euclidean')
    scores.append(score)
    models.append(model)
scores = np.array(scores)
best_index = scores.argmax()  # 求出最大值的索引
best_epsilon = epsilons[best_index]  # 最优半径
best_score = scores[best_index]  # 最优表面系数
best_model = models[best_index]
print("最优半径", best_epsilon)   # 最优半径 0.7999999999999999
print("最优表面系数", best_score)  # 最优表面系数 0.6366395861050828

猎取中心样本、外周样本、伶仃样本。而且运用差别的点型画图。

core_mask = np.zeros(len(x), dtype=bool)
core_mask[best_model.core_sample_indices_] = True
offset_mask = best_model.labels_ == -1
periphery_mask = ~(core_mask | offset_mask)
plt.figure('DBSCAN Cluster', facecolor='lightgray')
plt.title('DBSCAN Cluster', fontsize=14)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
labels = best_model.labels_
# 中心样本
plt.scatter(x[core_mask][:, 0], x[core_mask][:, 1], c=labels[core_mask],
            cmap='brg', s=80, label='Core')
# 外周样本
plt.scatter(x[periphery_mask][:, 0], x[periphery_mask][:, 1], alpha=0.5,
            c=labels[periphery_mask], cmap='brg', marker='s', s=80, label='Periphery')
# 伶仃样本
plt.scatter(x[offset_mask][:, 0], x[offset_mask][:, 1],
            c=labels[offset_mask], cmap='brg', marker='x', s=80, label='Offset')
plt.legend()
plt.show()

 

记录一下自己写PHP程序时走过的一些坑

参与评论