1、k-mean
来源:https://www.pianshen.com/article/7840142921/
算法步骤
欧氏距离
K-means的优缺点
优点:
1.算法快速、简单;
2.对大数据集有较高的效率并且是可伸缩性的;
3.时间复杂度近于线性,而且适合挖掘大规模数据集。K-Means聚类算法的时间复杂度是O(n×k×t) ,其中n代表数据集中对象的数量,t代表着算法迭代的次数,k代表着簇的数目
缺点:
1、在k-measn算法中K是事先给定的,但是K值的选定是非常难以估计的。
2、在 K-means 算法中,首先需要根据初始聚类中心来确定一个初始划分,然后对初始划分进行优化。这个初始聚类中心的选择对聚类结果有较大的影响,一旦初始值选择的不好,可能无法得到有效的聚类结果,这也成为 K-means算法的一个主要问题。
3、当数据量很大时,算法的开销是非常大的。
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.cluster import k_means
from sklearn.metrics import accuracy_score,precision_recall_curve,confusion_matrix
from sklearn.metrics import PrecisionRecallDisplay,ConfusionMatrixDisplay
import matplotlib.pyplot as plt
import numpy as np
from functools import partial
# iris = datasets.load_iris()
# print(dir(iris))
# print(iris.target_names)
# print=partial(print,sep='\n')
# X=iris.data
# y=iris.target
# print('X的特征名',iris.feature_names)
# print('x的size',X.shape,'y的size',y.shape,)
fig1,(ax1,ax2)=plt.subplots(2,1,sharex=True)
# #sepal length 和petal length两个特征
X=np.array([[1,1],[5,5],[6,6]])
y=np.array([0,1,1])
ax1.scatter(X[:,0],X[:,1],c=y)
"选random,n_init=1,预处理:将X中心化,x-=x.mean(),再根据随机种子选出一个样本作为质心"
pred= k_means(X,n_clusters=2, init='random',random_state=2,max_iter=10,n_init=1)
centroid,label,inertia=pred
print(pred)
# print("数据的簇中心",pred.cluster_centers_)
# print(pred)
ax2.scatter(X[:,0],X[:,1],c=labe
'''sklearn.cluster.KMeans参数介绍
n_clusters:int型,生成的聚类数,默认为8
max_iter:int型,执行一次k-means算法所进行的最大迭代数。 默认值为300
n_init:int型,用不同的聚类中心初始化值运行算法的次数,最终解是在inertia意义下选出的最优结果。 默认值为10
init:有三个可选值:‘k-means++’、‘random’、或者传递一个ndarray向量。
1)‘k-means++’ 用一种特殊的方法选定初始质心从而能加速迭代过程的收敛
2)‘random’ 随机从训练数据中选取初始质心。
3)如果传递的是一个ndarray,则应该形如 (n_clusters, n_features) 并给出初始质心。
默认值为‘k-means++’。
tol:float型,默认值= 1e-4 与inertia结合来确定收敛条件。
n_jobs:int型。指定计算所用的进程数。内部原理是同时进行n_init指定次数的计算。
(1)若值为 -1,则用所有的CPU进行运算。若值为1,则不进行并行运算,这样的话方便调试。
(2)若值小于-1,则用到的CPU数为(n_cpus + 1 + n_jobs)。因此如果 n_jobs值为-2,则用到的CPU数为总CPU数减1。
random_state:整形或 numpy.RandomState 类型,可选
用于初始化质心的生成器(generator)。如果值为一个整数,则确定一个seed。此参数默认值为numpy的随机数生成器。
主要属性
cluster_centers_:聚类中心
labels:每个样本所属的簇
inertial_:用来评估簇的个数是否合适,距离越小说明簇分的越好,选取临界点的簇个数
'''
2、层次聚类
来源:https://www.cnblogs.com/zongfa/p/9344769.html
西瓜书:https://zhuanlan.zhihu.com/p/70414047
层次聚类的合并算法通过计算两类数据点间的相似性,对所有数据点中最为相似的两个数据点进行组合,并反复迭代这一过程。简单的说层次聚类的合并算法是通过计算每一个类别的数据点与所有数据点之间的距离来确定它们之间的相似性,距离越小,相似度越高。并将距离最近的两个数据点或类别进行组合,生成聚类树。
相似度的计算
层次聚类使用欧式距离来计算不同类别数据点间的距离(相似度)。
分别计算欧式距离值(矩阵)
将数据点B与数据点C进行组合后,重新计算各类别数据点间的距离矩阵。数据点间的距离计算方式与之前的方法一样。这里需要说明的是组合数据点(B,C)与其他数据点间的计算方法。当我们计算(B,C)到A的距离时,需要分别计算B到A和C到A的距离均值。
经过计算数据点D到数据点E的距离在所有的距离值中最小,为1.20。这表示在当前的所有数据点中(包含组合数据点),D和E的相似度最高。因此我们将数据点D和数据点E进行组合。并再次计算其他数据点间的距离。
后面的工作就是不断的重复计算数据点与数据点,数据点与组合数据点间的距离。这个步骤应该由程序来完成。这里由于数据量较小,我们手工计算并列出每一步的距离计算和数据点组合的结果。
两个组合数据点间的距离
计算两个组合数据点间距离的方法有三种,分别为Single Linkage,Complete Linkage和Average Linkage。在开始计算之前,我们先来介绍下这三种计算方法以及各自的优缺点。
-
Single Linkage:方法是将两个组合数据点中距离最近的两个数据点间的距离作为这两个组合数据点的距离。这种方法容易受到极端值的影响。两个很相似的组合数据点可能由于其中的某个极端的数据点距离较近而组合在一起。
-
Complete Linkage:Complete Linkage的计算方法与Single Linkage相反,将两个组合数据点中距离最远的两个数据点间的距离作为这两个组合数据点的距离。Complete Linkage的问题也与Single Linkage相反,两个不相似的组合数据点可能由于其中的极端值距离较远而无法组合在一起。
-
Average Linkage:Average Linkage的计算方法是计算两个组合数据点中的每个数据点与其他所有数据点的距离。将所有距离的均值作为两个组合数据点间的距离。这种方法计算量比较大,但结果比前两种方法更合理。
我们使用Average Linkage计算组合数据点间的距离。下面是计算组合数据点(A,F)到(B,C)的距离,这里分别计算了(A,F)和(B,C)两两间距离的均值。
树状图
图和数据无关
缺点
传统的层次聚类算法的效率比较低O(tn**2) t:迭代次数 n:样本点数,最明显的一个缺点是不具有再分配能力,即如果样本点A在某次迭代过程中已经划分给类簇C1,那么在后面的迭代过程中A将永远属于类簇C1,这将影响聚类结果的准确性。
改进:
一般情况下,层次聚类通常和划分式聚类算法组合,这样既可以解决算法效率的问题,又能解决样本点再分配的问题,在后面将介绍BIRCH算法。
3、寻找最好的k
3.1肘部法则
肘部法则 elbow method是一个常用的方法,如下图所示,K = 3就是处于肘部的k值
下图2,3是比较好的k
那么该方法的原理是什么呢?
就是最小化点到聚类中心的距离
1 安装yellowbrick库
pip install yellowbrick
2 运行,其实就一行代码
来源:https://www.zhihu.com/question/279825061/answer/409613401
from sklearn.cluster import KMeans
from yellowbrick.cluster.elbow import kelbow_visualizer
from yellowbrick.datasets.loaders import load_nfl
X, y = load_nfl()
# Use the quick method and immediately show the figure
kelbow_visualizer(KMeans(random_state=4), X, k=(2,10))
自动选择k=4是最优的K值。
3.2轮廓系数
Silhouette Coefficient
论文来源:公式、图推
https://www.sciencedirect.com/science/article/pii/0377042787901257
详细讲解因子,举例,绘图
https://blog.csdn.net/weixin_44344462/article/details/89337770
b为该点与非本类点的平均距离,a是该点与本类其他点的平均距离
sklearn.metrics.silhouette_samples(X, labels, etric='euclidean')
参数 X:数组[n_samples_a,n_samples_a](如果metric ==“ precomputed”),否则为[n_samples_a,n_features] 样本之间的成对距离数组或特征数组。
labels:数组,形状= [n_samples] 每个样品的预测标签。
metric : 计算要素阵列中实例之间的距离时使用的度量。默认是euclidean(欧氏距离)。
如果metric是字符串,则必须是允许的选项之一metrics.pairwise.pairwise_distances。如果X是距离数组本身,请使用metric="precomputed"。
return 每个样本的轮廓系数
from sklearn.cluster import k_means
from sklearn.metrics import accuracy_score,precision_recall_curve,confusion_matrix,silhouette_samples
import matplotlib.pyplot as plt
import numpy as np
from functools import partial
X=np.array([[0,0],[1,1],[5,5],[6,6]])
y=np.array([1,1,0,0])
print(pred)
print(silhouette_samples(X,y))
#>>>[0.81818182 0.77777778 0.77777778 0.81818182]
'''
a=sse[(0,0)-(1,1)] / 1
b= [sse[(0,0)-(5,5)] +sse[(0,0)-(6,6)]] / 2
max(a,b)=b
out=0.8181
'''
sklearn.metrics.silhouette_score(X, labels, metric='euclidean', sample_size=None, random_state=None)
参数
X:数组[n_samples_a,n_samples_a](如果metric ==“ precomputed”),否则为[n_samples_a,n_features] 样本之间的成对距离数组或特征数组。
labels:数组,形状= [n_samples] 每个样品的预测标签。
metric : 计算要素阵列中实例之间的距离时使用的度量。默认是euclidean(欧氏距离)。
如果metric是字符串,则必须是允许的选项之一metrics.pairwise.pairwise_distances。如果X是距离数组本身,请使用metric="precomputed"。
return 样本平均轮廓系数