sklearn学习之聚类
1、算法简介
1、认识聚类算法
- 对鲨鱼、羊、猫、狗、青蛙、金鱼、麻雀进行分类
- 按照繁衍后代的方式:
- 鲨鱼 羊 猫 狗
- 青蛙 金鱼 麻雀
- 按照呼吸方式
- 羊 猫 狗 青蛙 麻雀
- 金鱼 鲨鱼
- 按照生活环境
- 羊 猫 狗 麻雀
- 金鱼 鲨鱼
- 青蛙
使用不同的聚类准则,产生的聚类结果不同。
1.2 聚类算法在现实中的应用
- 用户画像, 广告推荐, 收索引擎的流量推荐, 恶意流量识别
- 基于位置信息的商业推送, 新闻聚类, 筛选排序
- 图像分割, 降维, 识别
聚类算法的概念
一种典型的无监督学习算法,主要用于将相近的样本自动归于一个类中。
聚类试图将训练集中的样本数据划分为若干个(k个)通常互不相交的子集,每个子集称为一个“簇”(cluster)。
达到“物以类聚”效果,即簇与簇之间的相似度低(low intra-cluster similarity),簇内相似度高(high inter-cluster similarity)。
可以按照数据的相似度(similarity)和距离(disctance)来聚类(clustering)划分成不同的簇,这样每个簇可能会对应一些潜在的概念或类别,如“浅色瓜”、“深色瓜”、“无籽瓜"、“有籽瓜”,甚至“本地瓜”、“外地瓜”等。
簇的特征总结:
簇不是事先给定的,而是根据数据的相似性和距离来划分
簇的数目和结构都没有事先假定
与分类的区别
无监督的学习方法和有监督的学习算法
2、聚类算法API的初步使用
sklearn.cluster.KMeans(n_clusters = 8)
- n_clusters :聚类的中心数量
- 方法:
- fit(x)
- predict(x)
- fit_predict(x)
案例
随机创建不同的二维数据集作为训练集,结合K_means算法将其聚类,给与不同的簇,观察其聚类效果。
代码实现
导入各种库
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
创建数据集
- 四个
- 簇中心在[-1,-1], [0,0],[1,1],[2,2]
- 簇方差分别为.4, .2, .2, .2
x, y = make_blobs(n_samples= 100,
centers = [[-1,-1],[0,0],[1,1],[2,2]], n_features= 2,random_state= 9,
cluster_std = [0.4,0.2,0.2,0.2])
plt.scatter(x[:,0],x[:,1],marker = 'o')
使用kmeans进行聚类
y_pred = KMeans(n_clusters=4,random_state=9).fit_predict(x)
使用CH方法进行评估
from sklearn.metrics import calinski_harabaz_score
print(calinski_harabaz_score(x,y_pred))
肘方法进行k选择(找拐点)
下面看不同的k值下的聚类效果
"""
score_all=[]
list1=range(2,6)
#其中i不能为0,也不能为1
for i in range(2,6):
y_pred = KMeans(n_clusters=i, random_state=9).fit_predict(x)
#画出结果的散点图
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
plt.show()
score=metrics.calinski_harabaz_score(x, y_pred)
score_all.append(score)
print(score)
"""
画出不同k值对应的聚类效果
"""
plt.plt(list1,score_all)
plt.show()
3、聚类算法的实现流程
- Kmeans包含两层内容
- k: 初始中心点个数 = 计划聚类数
- means: 求中心点到其他数据点的距离平均值
K-means聚类步骤
随机设置k个特征空间内的点作为初始的聚类中心
对于其他每个点计算到k个中心点的距离,选择最近的一个聚类中心点作为标记类别
重新计算每个聚类的新中心点(求平均值)
-
如果终止条件满足,结束,否则,重复2
终止条件:
迭代次数、最小平方误差MSE、簇中心点变化率。
4、模型评估
K-means算法的优缺点
-
缺点:
K值是用户给定的,在进行数据处理前,K值是未知的,不同的K值得到的结果也不一样。
对初始簇中心是敏感的。
不适合发现非凸形状的簇或大小差别较大的簇。
特殊值(离群值)对模型的影响比较大。
-
优点:
容易理解,聚类效果不错。
处理大数据集的时候,该算法可证较好的伸缩性和高效率。
当簇近似高斯分布时,效果非常不错。
5、参数
-
主要参数:
n_clusters:即K值,一般需要多试一些值以获得较好的聚类效果。
init: 初始质心的选择方式,可以为完全随机选择random、优化过的K-means++或者自己指定初始化的K个质心。一般建议使用默认的K-means++。
n_init:用不同的初始化质心(init进行初始化)运行,由于K-means是结果受初始质心影响的局部最优迭代算法。因此,需要多运行几次以选择一个较好的聚类效果,默认值是10,一般不需要改。如果K值较大,则可适当增大这个值。
max_iter:最大迭代次数,一般如果是凸数据可以不用管这个值,如果数据不是凸的,可能很难收敛,此时可以指定最大迭代次数让算法可以及时退出循环。
algorithm:有auto、full和elkan三种选择。full就是传统的K-means算法,elkan是elkan K-means算法。默认是auto,则会根据数据是否稀疏,来决定如何选择full和elkan。一般数据是稠密的,那么就是elkan,否则就是full。一般建议直接使用默认的auto。
-
主要属性:
- cluster_centers_:每个簇质心的坐标。
- labels_: 簇标签。
- inertia_: 每个点到其簇质心的距离之和。
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn import metrics
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans, MiniBatchKMeans
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
make_blobs函数示例
用make_blobs()函数生成三类数据用于聚类(100个样本,每个样本2个特征):
data, target = make_blobs(n_samples=100, n_features=2, centers=3)
画出该样本并标记不同颜色:
# 使用matplotlib作图
plt.figure(figsize=(12, 6))
plt.gca().set_facecolor('whitesmoke')
plt.scatter(data[:, 0], data[:, 1], s=50, c=target, marker='^')
plt.xticks(fontsize=13)
plt.yticks(fontsize=13)
plt.grid(linestyle='--', linewidth=1, alpha=0.5)
plt.show()
K-means算法
数据分布对K-means聚类的影响
产生模拟数据
# 样本数量
N = 1500
# 簇的数量
centers = 4
# 生成聚类数据
data, y = make_blobs(n_samples=N, n_features=2, centers=centers, random_state=28)
data1, y1 = make_blobs(n_samples=N, n_features=2, centers=centers,
cluster_std=[1.0, 1.5, 2.0, 2.5],random_state=28)
data2 = np.vstack((data[y==0][:200], data[y==1][:100], data[y==2][:10], data[y==3][:50]))
y2 = np.array([0]*200 + [1]*100 + [2]*10 + [3]*50)
观察data样本数据所属簇的构成
发现1500个样本,被四个簇均分。data2样本数据的构成为:
0簇前200个样本
1簇前100个样本
2簇前10个样本
3簇前50个样本
而其标签数据则用numpy数组手动生成。
# 初始化模型对象
km = KMeans(n_clusters=centers, init='k-means++', n_init=10, random_state=28)
# 训练模型
km.fit(data, y)
# 使用模型进行自身预测
y_pre = km.predict(data)
print('所有样本距离簇质心的总距离:', km.inertia_)
print('所有样本距离族质心的平均距离:', (km.inertia_/N))
print('簇质心坐标:', km.cluster_centers_)
# 训练并预测data1
y_pre1 = km.fit_predict(data1)
# 训练并预测data2
y_pre2 = km.fit_predict(data2)
# 设置画布
plt.figure(figsize=(12, 6))
plt.subplots_adjust(left=0, bottom=0, right=1, top=0.85, hspace=0.3, wspace=0.3)
cm = mpl.colors.ListedColormap(list('rgbmyc'))
# 原始数据
plt.subplot(241)
plt.gca().set_facecolor('whitesmoke')
plt.scatter(data[:, 0], data[:,1], c=y, s=5, cmap=cm)
plt.title('原始数据')
# K-means算法聚类结果
plt.subplot(242)
plt.gca().set_facecolor('whitesmoke')
plt.scatter(data[:, 0], data[:, 1], c=y_pre, s=5, cmap=cm)
plt.title('K-means算法聚类结果')
6、层次聚类
- 凝聚:
从下到上。首先将每个对象作为一个簇,然后合并簇,直到所有的对象都在一个簇内。
- 分裂:
从上到下。首先将所有对象置于同一簇内,然后细分,直到每个对象自成一簇。
- API
- AgglomerativeClustering()
- 参数:
- n_cluster : 聚类数目
- affinity: 样本距离定义
- linkage: 类间距离定义
- ward:最小距离
- average:平均距离
- complete:最大距离
from sklearn.datasets import make_blobs
from sklearn.cluster import AgglomerativeClustering
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle #python自带的迭代器模块
#产生随机数据的中心
centers = [[1, 1], [-1, -1], [1, -1]]
#产生的数据个数
n_samples = 3000
#生产数据
X, lables_true = make_blobs(n_samples = n_samples, centers= centers, cluster_std = 0.6,random_state = 0)
#设置分层聚类函数
linkages = ['ward', 'average', 'complete']
n_clusters_ = 3
ac = AgglomerativeClustering(linkage = linkages[2],n_clusters = n_clusters_)
#训练数据
ac.fit(X)
#每个数据的分类
lables = ac.labels_
plt.figure(1) #绘图
plt.clf()
colors = cycle('bgrcmykbgrcmykbgrcmykbgrcmyk')
for k, col in zip(range(n_clusters_), colors):
#根据lables中的值是否等于k,重新组成一个True、False的数组
my_members = lables == k
#X[my_members, 0]取出my_members对应位置为True的值的横坐标
plt.plot(X[my_members, 0], X[my_members, 1], col + '.')
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
7、案例
作者:托尔金的昨日幻想
原文链接:https://www.jianshu.com/p/9aae738a25a9