聚类算法
kmeans = KMeans(n_clusters=3) # n_clusters 分类数量
kmeans.fit(data.iloc[:,1:]) # 无监督,只需要给数据X就可以
dbscan = DBSCAN(eps = 0.2,min_samples=3)
dbscan.fit(X)
agg = AgglomerativeClustering(n_clusters=6,linkage='ward') # 最近的距离,作为标准
agg.fit(X)
数据间的距离类型:
将数据看做空间中的点的时候,评价远近可以用欧氏距离或者余弦距离。
计算过程如下:
基本思路:
算法步骤:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import pandas as pd
# 需要将亚洲国家队,分成三个类别
# 只有历年的统计数据,没有目标值(类别,等级)
data = pd.read_csv('./AsiaFootball.txt')
# 执行多次,分类结果会有所不同
kmeans = KMeans(n_clusters=3) # n_clusters 分类数量
# 无监督,只需要给数据X就可以
kmeans.fit(data.iloc[:,1:])
y_ = kmeans.predict(data.iloc[:,1:])# 聚类算法预测、划分的类别
c = data['国家'].values
for i in range(3):
cond = y_ == i#索引条件
print('类别是%d的国家有:'%(i),c[cond])
针对某个样本的轮廓系数s为:
聚类总的轮廓系数SC为:,所有样本的 的均值称为聚类结果的轮廓系数,是该聚类是否合理、有效的度量。
import numpy as np
from sklearn import datasets
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 聚类:轮廓系数,对聚类的评价指标,对应数学公式
from sklearn.metrics import silhouette_score
# 创建数据
# 假数据,数据X划分成3类
X,y = datasets.make_blobs(centers=3)
plt.scatter(X[:,0],X[:,1],c = y)
# 指定不同的k,寻找最佳聚类类别数目
# 可以画图,一目了然,数据简单,属性只有两个,所以可以画图
# 属性多,无法可视化,评价指标
# 轮廓系数
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['font.size'] = 18
plt.rcParams['axes.unicode_minus'] = False
score = []
for i in range(2,7):
kmeans = KMeans(n_clusters=i)
kmeans.fit(X)
y_ = kmeans.predict(X)# 预测类别 == 标签
# plt.scatter(X[:,0],X[:,1],c = y_)
score.append(silhouette_score(X,y_))
# print('当聚类类别是6的时候,评价指标轮廓系数: ',silhouette_score(X,y_))
plt.plot(range(2,7),score)
plt.xlabel('K值')
plt.ylabel('轮廓系数',c = 'red')
# 结论:,当k值是3的时候,轮廓系数最大,这个时候,说明划分效果最好!
import matplotlib.pyplot as plt # plt 用于显示图片
from sklearn.cluster import KMeans
import numpy as np
plt.figure(figsize=(8,4))
# 加载图片显示原图
pixel = plt.imread('11-bird.png')
plt.subplot(1,2,1)
plt.imshow(pixel)
# 聚类运算,压缩图片
pixel = pixel.reshape((128*128 , 3))
kmeans = KMeans(n_clusters=8).fit(pixel)
# 聚类结果合成新图片
newPixel = kmeans.cluster_centers_[kmeans.labels_].reshape(128,128,3)
plt.subplot(1,2,2)
plt.imshow(newPixel)
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的空间聚类算法。该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据库中发现任意形状的簇,它将簇定义为密度相连的点的最大集合。
基于密度这点有什么好处呢,我们知道Kmeans聚类算法只能处理球形的簇,也就是一个聚成实心的团(这是因为算法本身计算平均距离的局限)。但往往现实中还会有各种形状,这个时候,那些传统的聚类算法显然就悲剧了。于是就思考,样本密度大的成一类呗。这就是DBSCAN聚类算法 .
import numpy as np
from sklearn import datasets
from sklearn.cluster import KMeans,DBSCAN
import matplotlib.pyplot as plt
# y中是两类:0,1
X,y = datasets.make_circles(n_samples=1000,noise=0.05,factor = 0.5)
# 创建一个大圆包含小圆的样本集
# centers = [(1.5,1.5)] 元组,代表着,中心点的坐标值
# y1一类:0 + 2
X1,y1 = datasets.make_blobs(n_samples=500,n_features=2,
centers=[(1.5,1.5)],cluster_std=0.2)
# 将circle和散点进行了数据合并
X = np.concatenate([X,X1])
y = np.concatenate([y,y1 + 2])
plt.scatter(X[:,0],X[:,1],c = y)
# 根据距离,划分‘势力范围’
kmeans = KMeans(3)
kmeans.fit(X)
y_ = kmeans.labels_
plt.scatter(X[:,0],X[:,1],c = y_)
# 使用DBSCAN算法可以较好的区分
dbscan = DBSCAN(eps = 0.2,min_samples=3)
dbscan.fit(X)
y_ = dbscan.labels_
plt.scatter(X[:,0],X[:,1],c = y_)
分层聚类输出层次结构,这种结构比平面聚类返回的非结构化聚类集更具信息性。
分层聚类法(hierarchical cluster method)一译“系统聚类法”。聚类分析的一种方法。其做法是开始时把每个样品作为一类,然后把最靠近的样品(即距离最小的群品)首先聚为小类,再将已聚合的小类按其类间距离再合并,不断继续下去,最后把一切子类都聚合到一个大类。
层次聚类 (Hierarchical Clustering) 是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。创建聚类树有自下而上合并和自上而下分裂两种方法。
我们着重看一下自底向上的合并算法:
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_swiss_roll
# 创建数据
X,y = datasets.make_swiss_roll(n_samples=1500,noise = 0.05)
fig = plt.figure(figsize=(12,9))
a3 = fig.add_subplot(projection = '3d')
a3.scatter(X[:,0],X[:,1],X[:,2],c = y)
a3.view_init(10,-80)
# Kmeans只负责分类,随机性,类别是数字几,不固定
clf = KMeans(n_clusters=6)
clf.fit(X)
y_ = clf.labels_
fig = plt.figure(figsize=(12,9))
a3 = plt.subplot(projection = '3d')
a3.scatter(X[:,0],X[:,1],X[:,2],c = y_)
a3.view_init(10,-80)
# 分层聚类
agg = AgglomerativeClustering(n_clusters=6,linkage='ward') # 最近的距离为标准
agg.fit(X)
y_ = agg.labels_
fig = plt.figure(figsize=(12,9))
a3 = plt.subplot(projection = '3d')
a3.scatter(X[:,0],X[:,1],X[:,2],c = y_)
a3.view_init(10,-80)
对于这种非欧几何的数据下,可见如果没有设置连接性约束,将会忽视其数据本身的结构,强制在欧式空间下聚类,于是很容易形成了上图这种跨越流形的不同褶皱。
(连接性约束,对局部结构进行约束)
from sklearn.neighbors import kneighbors_graph# graph图形的意思
# 邻居数量变少,认为,条件宽松
conn = kneighbors_graph(X,n_neighbors=10) #采用邻居,进行约束
agg = AgglomerativeClustering(n_clusters=6,connectivity=conn,linkage='ward')
# 最近的距离,作为标准
agg.fit(X)
y_ = agg.labels_
fig = plt.figure(figsize=(12,9))
a3 = fig.add_subplot(projection = '3d')
a3.scatter(X[:,0],X[:,1],X[:,2],c = y_)
a3.view_init(10,-80)