目录算法
1.聚类概念app
2.类似度或距离度量dom
2.1 闵可夫斯基距离(Minkowski distance)机器学习
2.2 欧式距离(Euclidean distance)ide
2.3 曼哈顿距离(Manhattan distance)函数
2.4 马哈拉诺比斯距离(Mahalanobis distance)学习
2.5 相关系数测试
2.6 夹角余弦优化
2.7 度量方式idea
1.聚类概念
聚类是指:把给定样本,依据它们之间的距离或类似度,划分为若干个“类”或“簇”。使得类似度较高的样本汇集在同一个类,不类似的样本分散在不一样的类。
聚类属于无监督学习,方法不少,最经常使用的是:层次聚类、K均值聚类(Kmeans)、模糊聚类(模糊Cmeans)。在聚类中十分重要的概念就是距离或者类似度度量。
2.类似度或距离度量
聚类的输入是样本数据,每一个样本又由m个属性的特征组成,因此输入能够定义为,其中,行数是维度的个数,列数是样本的个数。在计算距离或类似度的时候,有多种方法,通常是距离、相关系数夹角余弦。一般状况下:
距离越小,类似度越高;距离越大,类似度越低。
相关系数越接近1,类似度越高;相关系数越接近0,类似度越低。
夹角余弦越接近1,类似度越高;夹角余弦越接近0,类似度越低。
2.1 闵可夫斯基距离(Minkowski distance)
,其中(
)
2.2 欧式距离(Euclidean distance)
当p=2的时候,即为欧式距离:
2.3 曼哈顿距离(Manhattan distance)
当p=1的时候,即为曼哈顿距离:
2.4 马哈拉诺比斯距离(Mahalanobis distance)
马哈拉诺比斯距离简称为马氏距离,考虑各个份量之间的相关性与各个份量的尺度相关性。马氏距离越大,则类似度越小;马氏距离越小,则类似度越大。
定义输入样本的协方差矩阵为
,则样本
与
的马氏距离为:
,其中
即第i列特征值,
,即第j列特征值。
2.5 相关系数
样本之间的类似度除了用距离度量外,还可使用相关系数(correlation coefficient)来表示。与距离度量不一样,相关系数越接近1,则表示样本越类似;相关系数越接近于0,表示样本越不类似。
通常和
的相关系数定义为:
,其中
,
2.6 夹角余弦
样本之间的类似度还能够用夹角余弦表示,夹角余弦值越接近1,表示样本越类似;夹角预余弦值越接近0,表示样本越不类似。
夹角余弦能够定位为:
2.7 度量方式
不一样度量方式获得的结果不必定一致,具体采用哪一种度量方式,须要结合本身实际状况出发。例以下图
从距离上看,A与B的距离更近,所以A和B比A和C更类似;从夹角余弦上看,A和C比A和B更类似。
3. 类或簇的基本概念
经过聚类,能够获得类或簇,它是输入样本的子集。了解距离和类似度量的方式后,就须要了解聚类中经常使用的一些概念,这样在后续的计算中,可以不使得概念混淆。
3.1 聚类分类
硬聚类:假定一个样本智能属于一个类,或类的交集为空集,这种聚类属于硬聚类。本文中的层次聚类、K均值聚类和模糊聚类属于硬聚类。
软聚类:若是一个样本能够属于多个类,或类的交集不为空集,那么这种方法称为软聚类。
3.2 类或簇
用表示类或簇,
,
表示勒种的样本,
表示
中样本的个数。
表示
,
的距离。
哪怎样算是一个类或簇?
给定一个正数
,若
,则能够称
为一个类或簇
给定一个正数
,若
,能够称
为一个类或簇
给定一个正数
,若
能够称
为一个类或簇
因此,当某个集合中内,任意样本之间距离小于等于给定的正数,那么就能够认为这个集合是一个类或簇。
3.3 类的中心
类的中心指的就是类的均值,定义为:
3.4 类的直径
类的直径是指任意两个样本之间最大的距离,定义为:
3.5 类的散布矩阵
定义为:,衡量类中样本的分散状况,相似方差。
3.6 类的协方差
定义为:,衡量样本之间的相关性。
3.7 类之间最短距离或单链接
类与类
样本之间的最短距离定义为两个类之间的最短距离:
3.8 类之间最长距离或彻底链接
类与类
样本之间的最短距离定义为两个类之间的最短距离:
3.9 中心距离
类与类
的类中心
和
之间的距离为两个类之间的中心距离:
3.10 平均距离
类与类
的任意两个样本之间的平均距离为两个类之间的平均距离:
4 层次聚类
了解聚类的距离和类似度以及基础概念,就能够开始进行聚类分析。
所谓层次聚类,是指按照层次的方法找类之间的层次关系,有层次聚合(自下而上)、层次分裂(自上而下)两种方法。
以下图,层次聚合是指,初始的时候,每一个样本单独属于一个类,而后按照类之间距离最小合并的原则,迭代合并类,直至合并到指定类的个数,或者只有1个类。层次分裂聚类与层次聚合相反,咱们仅介绍聚合聚类。
4.1 层次聚合
输入:n个样本组成的样本集合
输出:对的一个层次化聚类
4.2 算法流程:
- 计算n个样本两两之间的欧式距离,记作距离矩阵
;
- 构造n个类,每个类只包含一个样本;
- 合并类间距离最小的两个类,构建一个新的类;
- 计算新的类与当前各种的距离。若类的个数为1,或者指定个数,则终止计算;不然回到3
4.3 案例
随机生成100个二维数据,按照层次聚类进行聚类。当K=4的时候,获得的聚类效果以下。
这100个样本的类标签:cluster labels:[1 0 0 1 3 0 0 3 0 0 1 0 0 0 0 0 0 0 0 0 0 1 3 0 1 3 1 0 0 0 3 0 0 0 3 0 2 0 1 1 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0]
代码以下:
import numpy as np import matplotlib.pyplot as plt from scipy.spatial.distance import pdist from scipy.cluster.hierarchy import linkage from scipy.cluster.hierarchy import dendrogram from sklearn.cluster import AgglomerativeClustering colo = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] # x = np.random.randint(0, 10, [100, 2]) x = 10 * np.random.rand(100, 2) shape = x.shape K = 4 # 簇个数 # 分析层次聚类 row_clusters = linkage(pdist(x, metric='canberra'), method='complete') ''' pdist:计算样本距离,其中参数metric表明样本距离计算方法 (euclidean:欧式距离、minkowski:明氏距离、chebyshev:切比雪夫距离、canberra:堪培拉距离) linkage:聚类,其中参数method表明簇间类似度计算方法 (single: MIN、ward:沃德方差最小化、average:UPGMA、complete:MAX) ''' row_dendr = dendrogram(row_clusters) plt.tight_layout() plt.title('canberra-complete') plt.show() # 层次聚类 clf = AgglomerativeClustering(n_clusters=K, affinity='canberra', linkage='complete') labels = clf.fit_predict(x) print('cluster labels:%s' % labels) for k, col in zip(range(0, K), colo): X = labels == k plt.plot(x[X, 0], x[X, -1], col + 'o') plt.xlabel('x') plt.ylabel('y') plt.title('hierarchical_clustering') plt.show()
5. K均值聚类(Kmeans)
K均值聚类是最经常使用的聚类方法,这是一种基于集合划分的聚类算法。
K均值聚类把样本集合划分为k个子集,构成k个类,将n个样本分配到k个类中,每一个样本到所属类的中心距离最小。
5.1 K均值的聚类策略
k均值聚类是经过最小化损失函数选取最优的划分或函数,即采用欧式距离做为样本之间的距离度量
,而后定义样本与述所类的中心的距离总和损失函数:
,其中
表明聚类的中心。因此K均值聚类就是最优化
的问题,在实现中,解决这类
问题的方法是经过迭代方法求解。
5.2 算法流程
输入:n个样本的集合
输出:样本的聚类
- 初始化,令t=0,随机选择k个样本做为初始类中心
;
- 样本聚类:计算每一个样本到每一个类中心的距离,将每一个样本指派到与其最近的类,构成聚类结果
;
- 计算新的类中心:对聚类结果
,计算类中全部样本的均值,做为新的聚类中心;
- 若是迭代收敛,或者符合中止条件,输出
;不然,令t=t+1,返回第2步。
5.3 实际案例
利用k均值聚算法求5个样本的二维数据集合
5.4 Kmeans的k值选择
K均值的类别数,一般状况下是人为指定的。在实际应用应用中,每每不知道K取多少是最合适,所以一般是使用尝试的方法,即令k=2到x(x本身设定,少于样本个数的一半便可)。可使用手肘法选择k值,即经过每一个k值下的均方差曲线的手肘点做为最优的k值。也能够选择使用轮廓系数法做为依据,选择使轮廓最大的值对应的k值为最优k值。
5.5 程序
下面程序实现的是,随机选择100个二维样本,对其进行聚类,k值的从2依次递增到7。
下图是k取不一样值时候的均方偏差曲线,从图中能够看出,手肘点在k=4的时候。要是以此为选择依据的话,K=4时有最优的聚类结果
下图是轮廓系数法求出的值,能够看出,当K=4的时候,轮廓系数最大。若以轮廓系数为选择依据,那么K=4的时候有最优的聚类结果。
代码以下:
import numpy as np from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score import matplotlib.pyplot as plt # colo = [[0, 0, 255], [0, 255, 0], [255, 0, 0], [0, 255, 255], [255, 255, 0], [255, 0, 255], [255, 255, 255]] colo = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] # x = np.random.randint(0, 10, [100, 2]) x = 10 * np.random.rand(100, 2) shape = x.shape sse = [] score = [] K = 8 for k in range(2, K): clf = KMeans(n_clusters=k) clf.fit(x) sse.append(clf.inertia_) lab = clf.fit_predict(x) score.append(silhouette_score(x, clf.labels_, metric='euclidean')) for i in range(shape[0]): plt.xlabel('x') plt.ylabel('y') plt.title('k=' + str(k)) plt.plot(x[i, 0], x[i, -1], colo[lab[i]] + 'o') plt.show() X = range(2, K) plt.xlabel('k') plt.ylabel('sse') plt.title('sum of the squared errors') plt.plot(X, sse, 'o-', ) plt.show() plt.xlabel('k') plt.ylabel('Score') plt.title('Silhouette Coefficient') plt.plot(X, score, 'o-', ) plt.show()
5.6 K均值聚类特性
- K均值聚类每每是事先指定k值,以欧式距离做为衡量样本距离的方法。以样本到所属类中心距离总和做为目标函数。算法是使用迭代计算,每每不能获得全局最优。
- K均值聚类属于启发式方法,初始中心的选择会直接影响到聚类的结果。
- K均值聚类如何选择K,一般须要尝试不一样的k值,经过手肘法或者轮廓系数法肯定最优k值。
6. 模糊聚类(FCM/模糊Cmeans)
模糊聚类是指模糊C均值聚类(Fuzzy Cmeans),简写为FCM或者模糊Cmeans,同Kmeans同样,是一种被普遍应用的聚类算法。经过测试,发现,模糊Cmeans的聚类效果比Kmeans要优秀。
模糊聚类引入一个隶属度矩阵,它是衡量当前样本属于某个类的可能性大小。当前样本可能属于类1,也可能属于累2,所以这种聚类成为模糊聚类。
若数据集被划分红c个类,那么有c个类中心,样本
与类中心
的隶属度为
,因而就有约束函数:
,其中m是隶属度因子。
接下来就是利用约束函数求解和
,采用的拉格朗日乘数法(具体推导,点击:聚类之详解FCM算法原理及应用,这里就不作详细介绍),获得
和
是相互关联的。在算法开始的时候,假设其中一个值(例如
),经过迭代计算,
和
经过对方得计算本身。
能够简单是样本属于摸个类的可能性大小,
是样本与贡献度乘积的结果。
6.1 算法流程
输入:样本,类的个数c,隶属度因子m(通常取2),迭代次数
输出:模糊Cmeans聚类结果
- 肯定分类个数c,指数m的值,肯定迭代次数(这是结束的条件,固然结束的条件能够有多种)。
- 初始化一个隶属度
(和为1);
- 根据
计算聚类中心
;
- 这个时候能够计算目标函数
了
- 根据
返回去计算
,回到步骤3,一直循环直到结束。
6.2 案例
随机取100个二维样本,分类样本个数为4,隶属度因子为2.
获得分类结果:cluster labels:[1 2 2 2 2 0 1 1 0 2 2 2 1 0 0 1 2 3 2 3 1 0 1 2 0 2 1 2 1 0 1 0 0 1 1 3 0 3 2 0 0 0 2 1 0 1 3 1 0 2 0 0 1 3 1 2 1 1 0 0 0 3 3 0 3 3 3 1 3 0 0 0 3 1 1 0 2 3 2 2 1 3 1 0 2 0 1 3 1 1 1 1 2 0 1 1 1 0 1 3]
代码:
import numpy as np import matplotlib.pyplot as plt colo = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] # x = np.random.randint(0, 10, [100, 2]) x = 10 * np.random.rand(100, 2) shape = x.shape K = 4 # 簇个数 def FCM(X, c_clusters=3, m=2, eps=10): membership_mat = np.random.random((len(X), c_clusters)) membership_mat = np.divide(membership_mat, np.sum(membership_mat, axis=1)[:, np.newaxis]) while True: working_membership_mat = membership_mat ** m Centroids = np.divide(np.dot(working_membership_mat.T, X), np.sum(working_membership_mat.T, axis=1)[:, np.newaxis]) n_c_distance_mat = np.zeros((len(X), c_clusters)) for i, x in enumerate(X): for j, c in enumerate(Centroids): n_c_distance_mat[i][j] = np.linalg.norm(x - c, 2) new_membership_mat = np.zeros((len(X), c_clusters)) for i, x in enumerate(X): for j, c in enumerate(Centroids): new_membership_mat[i][j] = 1. / np.sum((n_c_distance_mat[i][j] / n_c_distance_mat[i]) ** (2 / (m - 1))) if np.sum(abs(new_membership_mat - membership_mat)) < eps: break membership_mat = new_membership_mat return np.argmax(new_membership_mat, axis=1) labels = FCM(x, c_clusters=K, m=2, eps=10) print('cluster labels:%s' % labels) for k, col in zip(range(0, K), colo): X = labels == k plt.plot(x[X, 0], x[X, -1], col + 'o') plt.xlabel('x') plt.ylabel('y') plt.title('FCM') plt.show()
下面是使用机器学习库实现的模糊Cmeans算法,能够直观看出,在聚类效果上要比Kmeans要优秀些。
代码:
import numpy as np from skfuzzy.cluster import cmeans from sklearn.metrics import silhouette_score import matplotlib.pyplot as plt # colo = [[0, 0, 255], [0, 255, 0], [255, 0, 0], [0, 255, 255], [255, 255, 0], [255, 0, 255], [255, 255, 255]] colo = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] # x = np.random.randint(0, 10, [100, 2]) x = 10 * np.random.rand(100, 2) shape = x.shape FPC = [] K = 8 labels = [] for k in range(2, K): center, u, u0, d, jm, p, fpc = cmeans(x.T, m=2, c=k, error=0.5, maxiter=10000) ''' 注意输入数据是kemans数据的转置 center是聚类中心、u是最终的隶属度矩阵、u0是初始化隶属度矩阵 d是每一个数据到各个中心的欧式距离矩阵,jm是目标函数优化、p是迭代次数 fpc是评价指标,0最差,1最好 ''' label = np.argmax(u, axis=0) for i in range(shape[0]): plt.xlabel('x') plt.ylabel('y') plt.title('c=' + str(k)) plt.plot(x[i, 0], x[i, -1], colo[label[i]] + 'o') plt.show() print('%d c\'s FPC is:%0.2f' % (k, fpc)) FPC.append(fpc) X = range(2, K) plt.xlabel('c') plt.ylabel('FPC') plt.title('FCM-cmeans') plt.plot(X, FPC, 'o-', ) plt.show()
注意skfuzzy.cluster的安装方法pip install -U scikit-fuzzy