阅读 96

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算法将其聚类,给与不同的簇,观察其聚类效果。


原始数据
k = 2
k = 3
k = 4

代码实现

导入各种库

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


    1.jpg
  • 终止条件:

迭代次数、最小平方误差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:autofullelkan三种选择。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

文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐