聚类

我怕爱的太早我们不能终老 提交于 2020-01-28 05:32:34

聚类

相关概念

1、无监督学习:
无监督学习是机器学习的一种方法,没有给定事先标记过的训练示例,自动对输入的数据进行分类或分群。无监督学习的主要运用包含:聚类分析、关系规则、维度缩减。它是监督式学习和强化学习等策略之外的一种选择。 一个常见的无监督学习是数据聚类。在人工神经网络中,生成对抗网络、自组织映射和适应性共振理论则是最常用的非监督式学习。
2、聚类:
聚类是一种无监督学习。聚类是把相似的对象通过静态分类的方法分成不同的组别或者更多的子集,这样让在同一个子集中的成员对象都有相似的一些属性,常见的包括在坐标系中更加短的空间距离等。

聚类和分类的区别

数据分类是分析已有的数据,寻找其共同的属性,并根据分类模型将这些数据划分成不同的类别,这些数据赋予类标号。这些类别是事先定义好的,并且类别数是已知的。相反,数据聚类则是将本没有类别参考的数据进行分析并划分为不同的组,即从这些数据导出类标号。聚类分析本身则是根据数据来发掘数据对象及其关系信息,并将这些数据分组。每个组内的对象之间是相似的,而各个组间的对象是不相关的。不难理解,组内相似性越高,组间相异性越高,则聚类越好。

K-means聚类算法

k-means算法以数据间的距离作为数据对象相似性度量的标准,因此选择计算数据间距离的计算方式对最后的聚类效果有显著的影响,常用计算距离的方式有:余弦距离、欧式距离、曼哈顿距离等
代码实现:

import numpy as np

"""
    任务要求:对平面上的 100 个点进行聚类,要求聚类为两类,其横坐标都为 0 到 99。
"""
x = np.linspace(0, 99, 100)
y = np.linspace(0, 99, 100)
k = 2
n = len(x)
dis = np.zeros([n, k+1])

# 1.选择初始聚类中心
center1 = np.array([x[0], y[0]])
center2 = np.array([x[1], y[1]])
iter_ = 100

while iter_ > 0:
    # 2.求各个点到两个聚类中心距离
    for i in range(n):
        dis[i, 0] = np.sqrt((x[i] - center1[0])**2 + (y[i] - center1[1])**2)
        dis[i, 1] = np.sqrt((x[i] - center2[0])**2 + (y[i] - center2[1])**2)
        # 3.归类
        dis[i, 2] = np.argmin(dis[i,:2])  # 将值较小的下标值赋值给dis[i, 2]

    # 4.求新的聚类中心
    index1 = dis[:, 2] == 0
    index2 = dis[:, 2] == 1
    center1_new = np.array([x[index1].mean(), y[index1].mean()])
    center2_new = np.array([x[index2].mean(), y[index2].mean()])

    # 5.判定聚类中心是否发生变换
    if all((center1 == center1_new) & (center2 == center2_new)):
       # 如果没发生变换则退出循环,表示已得到最终的聚类中心
       break

    center1 = center1_new
    center2 = center2_new

# 6.输出结果以验证
print(dis)

层次聚类(划分聚类)

AGNES算法==>采用自底向上的策略。
代码:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
# 调用AGNES
from sklearn.cluster import AgglomerativeClustering
from sklearn.neighbors import kneighbors_graph  ## KNN的K近邻计算
import sklearn.datasets as ds
# 拦截异常信息
import warnings
​
warnings.filterwarnings('ignore')
# 设置属性防止中文乱码
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
# 模拟数据产生: 产生600条数据
np.random.seed(0)
n_clusters = 4
N = 1000
data1, y1 = ds.make_blobs(n_samples=N, n_features=2, centers=((-1, 1), (1, 1), (1, -1), (-1, -1)), random_state=0)
​
n_noise = int(0.1 * N)
r = np.random.rand(n_noise, 2)
min1, min2 = np.min(data1, axis=0)
max1, max2 = np.max(data1, axis=0)
r[:, 0] = r[:, 0] * (max1 - min1) + min1
r[:, 1] = r[:, 1] * (max2 - min2) + min2
​
data1_noise = np.concatenate((data1, r), axis=0)
y1_noise = np.concatenate((y1, [4] * n_noise))
# 拟合月牙形数据
data2, y2 = ds.make_moons(n_samples=N, noise=.05)
data2 = np.array(data2)
n_noise = int(0.1 * N)
r = np.random.rand(n_noise, 2)
min1, min2 = np.min(data2, axis=0)
max1, max2 = np.max(data2, axis=0)
r[:, 0] = r[:, 0] * (max1 - min1) + min1
r[:, 1] = r[:, 1] * (max2 - min2) + min2
data2_noise = np.concatenate((data2, r), axis=0)
y2_noise = np.concatenate((y2, [3] * n_noise))
​
​
def expandBorder(a, b):
    d = (b - a) * 0.1
    return a - d, b + d
​
​
## 画图
# 给定画图的颜色
cm = mpl.colors.ListedColormap(['#FF0000', '#00FF00', '#0000FF', '#d8e507', '#F0F0F0'])
plt.figure(figsize=(14, 12), facecolor='w')
linkages = ("ward", "complete", "average")  # 把几种距离方法,放到list里,后面直接循环取值
for index, (n_clusters, data, y) in enumerate(((4, data1, y1), (4, data1_noise, y1_noise),
                                               (2, data2, y2), (2, data2_noise, y2_noise))):
    # 前面的两个4表示几行几列,第三个参数表示第几个子图(从1开始,从左往右数)
    plt.subplot(4, 4, 4 * index + 1)
    plt.scatter(data[:, 0], data[:, 1], c=y, cmap=cm)
    plt.title(u'原始数据', fontsize=17)
    plt.grid(b=True, ls=':')
    min1, min2 = np.min(data, axis=0)
    max1, max2 = np.max(data, axis=0)
    plt.xlim(expandBorder(min1, max1))
    plt.ylim(expandBorder(min2, max2))
​
    # 计算类别与类别的距离(只计算最接近的七个样本的距离) -- 希望在agens算法中,在计算过程中不需要重复性的计算点与点之间的距离
    connectivity = kneighbors_graph(data, n_neighbors=7, mode='distance', metric='minkowski', p=2, include_self=True)
    connectivity = (connectivity + connectivity.T)
    for i, linkage in enumerate(linkages):
        ##进行建模,并传值
        ac = AgglomerativeClustering(n_clusters=n_clusters, affinity='euclidean',
                                     connectivity=connectivity, linkage=linkage)
        ac.fit(data)
        y = ac.labels_
​
        plt.subplot(4, 4, i + 2 + 4 * index)
        plt.scatter(data[:, 0], data[:, 1], c=y, cmap=cm)
        plt.title(linkage, fontsize=17)
        plt.grid(b=True, ls=':')
        plt.xlim(expandBorder(min1, max1))
        plt.ylim(expandBorder(min2, max2))
​
plt.tight_layout(0.5, rect=(0, 0, 1, 0.95))
plt.show()

密度聚类

DBSCAN算法流程
在这里插入图片描述
DBSCAN算法优点:

不需要事先指定聚类个数,且可以发现任意形状的聚类;
对异常点不敏感,在聚类过程中能自动识别出异常点;
聚类结果不依赖于节点的遍历顺序;

DBSCAN缺点:

对于密度不均匀,聚类间分布差异大的数据集,聚类质量变差;
样本集较大时,算法收敛时间较长;
调参较复杂,要同时考虑两个参数;

参考文献:
1.https://www.ibm.com/developerworks/cn/analytics/library/ba-1607-clustering-algorithm/index.html
2.https://zhuanlan.zhihu.com/p/38668500
3.https://github.com/datawhalechina/team-learning
4.https://blog.csdn.net/hanxia159357/article/details/81530361
5.https://www.jianshu.com/p/3963928d38de

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!