第七节机器学习--聚类

42 篇文章 0 订阅
19 篇文章 0 订阅

一、聚类第一个无监督的算法

1、无监督学习
有X
没有Y
利用X相似性
聚类
对大量未标注的数据集,按内在相似性划分为多个类别,类别内相似度大,类之间相似度小
2、距离的概念
2.1欧几里得距离(欧式距离)
假设超人要从A点到B点,可以直接飞过去,那飞过去的距离就是欧式距离。
在这里插入图片描述
在这里插入图片描述
2.2曼哈顿距离
假设普通人要从A点到B点,那只能绕着建筑物走,这个距离就是曼哈顿距离
在这里插入图片描述在这里插入图片描述
2.3闵可夫斯基距离
闵氏距离不是一种距离,而是一组距离的定义,其中的p是一个参数

当p=1时,就是曼哈顿距离
当p=2时,就是欧式距离
当p->∞时,就是切比雪夫距离
在这里插入图片描述
3、相似度
二维空间的公式在这里插入图片描述
三维空间的公式:
在这里插入图片描述
定义式:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
Jaccard相似系数

(Jarrcard Similarity Coefficient)用于比较有限样本集之间的相似性和差异性

Jarrcard系数值越大,样本相似度越高。
在这里插入图片描述
4、推荐系统
用户实际喜欢 [8, 9, 17, 25, 4]

给用户的推荐 [9, 10, 17, 24, 4, 8]、 [8, 9, 25]

哪两个推荐结果更好呢?

A集合和B集合相交的越多,它的相似性越强,当然要考虑它们并一起的大小,因为集合越大越可能相交的越多,这就有了Jaccard相似系数

度量集合,考虑热门商品

空间嵌入点的问题,有时候用欧式,有时候用余弦距离,度量文档相似性。
在这里插入图片描述
5、聚类

本质上,N个样本,映射到K个簇中

每个簇至少有一个样本

一般情况下,一个样本只属于一个簇(也有一个样样本属于多个簇的)

最基本:

先给定一个初始划分,迭代改变样本和簇的隶属关系,每次都比前一次好。
K-Means聚类
聚类是一种无监督的机器学习任务,它可以自动将数据划分成类cluster。因此聚类分组不需要提前被告知所划分的组应该是什么样子的。因为我们甚至可能都不知道我们再寻找什么,所以聚类是用于知识发现而不是预测。
在这里插入图片描述
6、聚类原则
聚类原则是一个组内的记录彼此必须非常相似,而与该组之外的记录截然不同。所有聚类做的就是遍历所有数据然后找到这些相似性。
使用距离来分配和更新类。
在这里插入图片描述
7、K-Means
选择K个初始的簇中心,随机的(拍脑袋给的),或者先验知识给的

某一个样本和某一个聚类中心的距离

计算所属聚类的样本均值。
8、二分K-Means
选择的初始值会对聚类结果有影响吗?如何调整

那么首先回答损失函数是什么?

MSE1, MSE2, MSE3, MSE4

两个簇里面的样本数量都很小

两个簇中心很近

两个MSE很小

合并

簇中心离的很远

MSE很大

分开
K-Means++
选择初始化簇中心稍微远一点

随机选择第一个

算每个样本到第一个样本距离,样本距离可以算成概率

概率化选择
9、K均值损失函数
假定数据点分布符合高斯分布
K个高斯分布混合得到的样本数据分布
最大似然估计!
似然函数取最大值
概率密度相乘, 再 各个族似然相乘
找到那些个miu可以使得取最大
这个就是K均值的损失函数,从机器学习角度重新看待,平方误差。
在这里插入图片描述
10、求偏导
在这里插入图片描述
公式化解释K均值

所以K均值假设了高斯混合模型,GMM,并且假设了方差sigma是一样的

K均值是在给定损失函数的情况下,梯度下降的一个应用

高斯混合分布不是线性回归凸函数,有多个极小值

K-means++或者多算几次
11、k的选择
K = N, MSE 为 0

K = 1, MSE就是原始数据的方差

选择一开始下降速度快,后来下降速度慢的

elbow method, 不止于K均值

代码案例:

# encoding: utf-8

import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as ds
import matplotlib.colors
from sklearn.cluster import KMeans

def expand(a, b):
    """
    为了扩展x,y轴的长度
    """
    d = (b - a) * 0.1
    return a-d, b+d

if __name__ == '__main__':
    # 创建400个样本
    N = 400
    # 准备分出4个类别
    centers = 4
    # 创建聚类的数据(按照4个正太分布创建点)【想看看方差一样的,数据量一样的,分类效果好不好】
    data, y = ds.make_blobs(N, n_features=2, centers=centers, random_state=2)
    print(data)
    # 方差和上面不一样,方差越大,数据集越分散;方差越小,数据集越密集【想看看方差不一样,数据量一样,分类效果好不好】
    data2, y2 = ds.make_blobs(N, n_features=2, centers=centers, cluster_std=(1, 2.5, 0.5, 2), random_state=2)
    # 从原来数据中选一部分的数据出来【想看看从每条数据里选不同的样本数量的分类效果好不好】
    data3 = np.vstack((data[y==0][:], data[y==1][:50], data[y==2][:20], data[y==3][:5]))
    # 按道理来说,聚类是不需要y值的,这里的y主要是为了看我们的聚类效果准不准
    y3 = np.array([0] * 100 + [1] * 50 + [2] * 20 + [3] * 5)
    print(y3)

    # k-means++是为了改变初始化的值,所以参数名称是init
    cls = KMeans(n_clusters=5, init='k-means++')


    y_hat = cls.fit_predict(data)
    y2_hat = cls.fit_predict(data2)
    y3_hat = cls.fit_predict(data3)

    # matplotlib.rcParams['font.sans-serif'] = [u'SimHei']
    cm = matplotlib.colors.ListedColormap(list('rgbm'))

    plt.figure(figsize=(9, 10), facecolor='w')
    # subplot用来画子表的 4行 2列 1第一个图
    plt.subplot(421)
    plt.title("Original Data")
    # scatter散点图
    plt.scatter(data[:, 0], data[:, 1], c=y, s=10, cmap=cm, edgecolors='none')
    x1_min, x2_min = np.min(data, axis=0)
    x1_max, x2_max = np.max(data, axis=0)

    x1_min, x1_max = expand(x1_min, x1_max)
    x2_min, x2_max = expand(x2_min, x2_max)

    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid(True)

    plt.subplot(422)
    plt.title("KMeans ++ Clusting")
    plt.scatter(data[:, 0], data[:, 1], c=y_hat, s=30, cmap=cm, edgecolors='none')
    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid(True)

    """
    对数据进行旋转
    """
    m = np.array(((1, 1), (1, 3)))
    data_r = data.dot(m)
    y_r_hat = cls.fit_predict(data_r)


    plt.subplot(423)
    plt.title('Rotation Data')
    plt.scatter(data_r[:, 0], data_r[:, 1], c=y, s=30, cmap=cm, edgecolors='none')
    x1_min, x2_min = np.min(data_r, axis=0)
    x1_max, x2_max = np.max(data_r, axis=0)

    x1_min, x1_max = expand(x1_min, x1_max)
    x2_min, x2_max = expand(x2_min, x2_max)

    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid(True)

    plt.subplot(424)
    plt.title('Rotated KMeans++ Clusting')
    plt.scatter(data_r[:, 0], data_r[:, 1], c=y_r_hat, s=30, cmap=cm, edgecolors='none')
    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid(True)


    plt.subplot(425)
    plt.title('Different Variance Data')
    plt.scatter(data2[:, 0], data2[:, 1], c=y2_hat, s=30, cmap=cm, edgecolors='none')
    x1_min, x2_min = np.min(data2, axis=0)
    x1_max, x2_max = np.max(data2, axis=0)

    x1_min, x1_max = expand(x1_min, x1_max)
    x2_min, x2_max = expand(x2_min, x2_max)

    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid(True)

    plt.subplot(426)
    plt.title('Different Variance Data KMeans++ Clusting')
    plt.scatter(data2[:, 0], data2[:, 1], c=y2_hat, s=30, cmap=cm, edgecolors='none')
    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid(True)

    plt.tight_layout(2, rect=(0, 0, 1, 0.97))
    plt.show()

效果图:

在这里插入图片描述

二、聚类(二)

1、Canopy聚类
T1和T2不同聚类结果
在这里插入图片描述
2、聚类的评估 – Given Label
均一性,一个簇中只包含一个类别样本, Precision

完整性,同类别样本被归到同一个簇中, Recall

Trade Off

V-Measure, F-Measure

二者加权平均在这里插入图片描述
c:完整性
h:均一性
3、聚类的评估 – No Label – 轮廓系数
计算同簇内每一个样本到同簇内样本的平均距离,可以度量这个样本和其他同簇样本的相似性

计算一个簇内每一个样本到不同簇内所有样本的距离,不同簇的那些样本距离求平均,然后求最小的那个距离,是不相似性

第一个值很小,第二个值很大,那就簇内很典型性的样本

如果相反,按道理应该属于另外一个簇了

Si接近1说明样本i聚类合理,Si接近-1说明样本更应该分到其他簇

Si接近0说明在簇分界上
在这里插入图片描述
4、层次聚类
理解起来有点像无监督的决策树

分裂的层次聚类: DIANA

把原始数据集去不断的分裂,然后去计算每个子数据集里面的相似性,然后不断的分裂,把数据集分为很多的类别

凝聚的层次聚类: AGNES

把一个个样本,不断的自底向上的聚类,然后一层一层的来聚,最后聚成一个完整的数据集,这种用的更多一些。
如果我们只关心结果的话,那么在某一时刻是要停止聚类的,在一些数据集中做层次聚类是合适的,包含层次的数据集! 地域!
在这里插入图片描述
如果两个样本,可以很好的度量距离,如果已经聚了一层,如何度量簇之间的相似性

最小距离:两个簇中,最接近样本的距离,城市和城市边界最短距离,成链状一条直线了

最大距离:两个簇中,最远的样本的距离,某一个簇存在异常值就很麻烦,簇本身比较狭长

平均距离:

两两样本距离的平均

两两样本距离的平方和
5、密度聚类
统计样本周边的密度,把密度给定一个阈值,不断的把样本添加到最近的簇

人口密度,根据密度,聚类出城市

解决类似圆形的K-Means聚类的缺点,密度聚类缺点计算复杂度大,空间索引来降低计算时间,降低查找速度。
在这里插入图片描述

6、DBSCAN
Density Based Spatial Clustering of Application with Noise

对象邻域:给定对象的半径内的区域

如果给定5为阈值,那么q是7, p是3, 那么q是核心对象

而p是在q这个范围(制定一个半径)内的,那么说q到p是核心密度可达

q密度可达p1, p1密度可达p, 那么q到p是密度可达。
密度可达
从o点能密度可达q,也能密度可达p

P和q叫密度相连

簇就是密度相连的最大的点的集合

即最大的密度相连构成的集合就是簇

如何一个点不是核心对象,也不能被别的点密度可达,就是噪声。
代码案例:

import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as ds
import matplotlib.colors
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler


def expand(a, b):
    d = (b - a) * 0.1
    return a-d, b+d

if __name__ == '__main__':
    N = 1000
    centers = [[1, 2], [-1, -1], [1, -1], [-1, 1]]
    # make_blobs模拟生成聚类的数据 centers:给定的中心点,根据中心点模拟生成数据 cluster_std生成数据的方差
    data, y = ds.make_blobs(N, n_features=2, centers=centers, cluster_std=[0.5, 0.25, 0.7, 0.5], random_state=0)
    # StandardScaler 做归一化的:先做均值归一化,再说方差归一化
    data = StandardScaler().fit_transform(data)
    # 数据的参数 (epsilon, min_sample)第一个是r,第二个是阈值
    params = ((0.2, 5), (0.2, 10), (0.2, 15), (0.3, 5), (0.3, 10), (0.3, 15))

    plt.figure(figsize=(12, 8), facecolor='w')
    # plt.suptitle('DBSCAN Clusting', fontsize=20)

    for i in range(6):
        eps, min_samples = params[i]
        model = DBSCAN(eps=eps, min_samples=min_samples)
        model.fit(data)
        y_hat = model.labels_
        # print(y_hat)
        core_indices = np.zeros_like(y_hat, dtype=bool)

        core_indices[model.core_sample_indices_] = True
        # print(core_indices)
        y_unique = np.unique(y_hat)
        # print(y_hat)
        # 假设有离群点 n_cluster - 1
        n_clusters = y_unique.size - (1 if -1 in y_hat else 0)
        print(y_unique, "聚类簇的个数为:", n_clusters)

        plt.subplot(2, 3, i+1)
        # 谱: 提取更好的特征(特征提取的作用)
        clrs = plt.cm.Spectral(np.linspace(0, 0.8, y_unique.size))
        # print(clrs)
        for k, clr in zip(y_unique, clrs):
            cur = (y_hat == k)
            if k == -1:
                plt.scatter(data[cur, 0], data[cur, 1], s=20)
                continue
            # 把我们分类好的类别,一个点一个点画出来(画离群点)
            plt.scatter(data[cur, 0], data[cur, 1], s=30, c=clr, edgecolors='k')
            # 把我们分类好的类别,一个点一个点画出来(画非离群点)
            plt.scatter(data[cur & core_indices][:, 0], data[cur & core_indices][:, 1], s=60, c=clr, marker='o', edgecolors='k')
        x1_min, x2_min = np.min(data, axis=0)
        x1_max, x2_max = np.max(data, axis=0)
        x1_min, x1_max = expand(x1_min, x1_max)
        x2_min, x2_max = expand(x2_min, x2_max)
        plt.xlim((x1_min, x1_max))
        plt.ylim((x2_min, x2_max))
        plt.grid(True)
        plt.title(u'epsilon = %.1f  m = %d CA:%d' % (eps, min_samples, n_clusters), fontsize=16)


    plt.tight_layout()
    plt.subplots_adjust(top=0.9)
    plt.show()

效果图:
在这里插入图片描述
r(半径)=0.1 m(阈值)=5,3,2
一个点在半径为0.1的范围内,如果其他的点的数量没有到m,那么它就不能当成一个核心对象。
不同的r半径,太大会都聚集在一起。
7、谱和谱聚类
谱: Y = A*X, 矩阵X乘以A等于对矩阵X做了空间线性变换,那么Y=map[X], A就是map这个线性算子,它的所有特征值的全体,称之为方阵的谱

方阵的谱半径为最大的特征值

谱聚类是一种基于图论的聚类方式,通过对样本数据的拉普拉斯矩阵的特征向量进行聚类,从而达到对样本数据进行聚类的目的。
谱聚类
解决区域重叠的问题,密度聚类对应区域重叠问题不太好办

我们有一堆样本,可以构建成全连接图,并且两两样本之间总是可以去求相似度的

两两样本之间构建邻接矩阵来表示图

邻接矩阵上面的值,是用高斯相似度计算得来

然后对角线都是0,可以根据告诉相似度看出来,这样有了矩阵W

除了对角线都有相似度的值,然后把它们按行或列加和得对角阵D

L=D-W, 这样的L矩阵叫做Laplace矩阵。
L矩阵是N*N的,N是样本个数,实数形成的对数矩阵,求特征值和特征向量

Lui = lambda iui, lambda是特征值,ui是特征向量,一组lambda有从大到小可以排序

每个对应的lambda都对应一个ui,每个ui是一个个的列向量,比如u11, u21, u31, un1

根据排序默认从小到大,逆序之后我们就取前面的几个ui列向量就可以了,其实这是一种降维

然后我们的前面的这几个列向量ui就成了新的对应每个样本的几个重要的特征

最后我们用K-Means聚类算法对样本进行聚类就好了

谱聚类和PCA的关系

就是Laplace矩阵做了一个主成分分析PCA,然后做K均值聚类。

8、PCA降维
盲目减少指标会损失很多信息

容易产生错误的结论

各变量间存在一定的相关关系

先均值归一化,映射到原点

协方差矩阵

协方差(Covariance)

用于衡量两个变量的总体误差

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值