聚类分析的一些套路

栏目: 编程工具 · 发布时间: 5年前

聚类分析是一种比较常见算法,实际应用也很多,比如大家经常听到的RMF模型、分客群精准营销等都是聚类分析的应用。

我们可以用“物以类聚、人以群分”来简单理解,它是一种无监督的分类算法。但是这种“简单”的算法,在运用到实际工作中会遇到很多问题,比如:

①极端值的影响造成个别几个样本被聚为了一类,剩余绝大部分样本被聚为了一类,相当于没有聚类。

②指标太多,不知道选哪些指标,量纲该如何处理?

③聚出来的客群大的大小的小,无法营销。

④不知道聚类效果如何,是否使用了最好的聚类算法,得到了最佳的N个客群。

聚类算法是基于距离计算的,所以我们选择的指标一定是数值型变量,大部分情况下都需要消除量纲的影响。

聚类算法按照方式不同,可以分为凝聚式和分裂式两种。

凝聚式 Agglometative:顾名思义就是开始时将所有的样本(n个)都视为一类(n类),然后一步步的把距离近的聚为一类,最终所有样本聚为一类的方法。

分裂式 Divisive:开始时将所有样本视为一类,最终拆分到每个样本都是一类。

我们来看一下 Python 中聚类算法的实现。

1. 常见的聚类算法

skleaarn中展示了不同的聚类算法适用的数据分布及运行时间。 链接

可以看到不同的算法适合不同的数据分布,也有不同的时耗,具体使用哪种算法,需要根据数据情况来选择,甚至迭代不同算法不同参数来择优。

%pylab inline

from IPython.display import Image

Image('cluster methods.png')

聚类分析的一些套路

2. 聚类算法示例

我们使用内置的鸢尾花数据集来进行聚类。鸢尾花数据集:共150条记录,有花萼长度、花萼宽度、花瓣长度、花瓣宽度、品种5个变量,其中每个品种50条记录。

2.1 使用scipy进行层次聚类

import scipy.cluster.hierarchy as sch

import matplotlib.pyplot as plt



# 中文和负号的正常显示

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

plt.rcParams['axes.unicode_minus'] = False



plt.figure(figsize=[15,5])

dendrogram = sch.dendrogram(sch.linkage(iris.data, method='ward'))  #ward最小方差法(使用的是欧氏距离)

plt.title('鸢尾花聚类树状图')

plt.xlabel('鸢尾花数据')

plt.ylabel('欧式距离')

plt.show()

聚类分析的一些套路

根据树状图我们可以确定聚为几类及样本分类,这种方法非常直观,但是不适用于大样本。

2.2 凝聚聚类

from sklearn.cluster import AgglomerativeClustering

ac = AgglomerativeClustering(n_clusters=3, affinity='euclidean', linkage='ward')

y_ac = ac.fit_predict(iris.data)
# 查看聚类结果

# 我们使用鸢尾花的花瓣长度和花瓣宽度做散点图,用散点颜色来区分鸢尾花的品种

import matplotlib.pyplot as plt

%matplotlib inline



plt.figure(figsize=(12, 12))

plt.subplot(221)

color = {0:'r',1:'y',2:'b'}

plt.scatter(iris.data[:,2], iris.data[:,3], c=[color[_] for _ in y_ac])

plt.title('Cluster data')



color = {0:'y',1:'b',2:'r'}

plt.subplot(222)

plt.scatter(iris.data[:,2], iris.data[:,3], c=[color[_] for _ in iris.target])

plt.title('Original data')



plt.show()

聚类分析的一些套路

2.3 KMeans聚类

from sklearn.cluster import KMeans

model_kmeans = KMeans(n_clusters=3, init='k-means++', random_state=123)

y_pred = model_kmeans.fit_predict(iris.data)

model_kmeans.cluster_centers_  # 类中心
# 聚类效果可视化

colors = ['red', 'blue', 'green']

for i in range(3):

    plt.scatter(iris.data[y_pred == i, 2], iris.data[y_pred == i, 3], s = 100, c = colors[i], label = 'Cluster '+str(i+1))

plt.scatter(model_kmeans.cluster_centers_[:,2], model_kmeans.cluster_centers_[:,3], s = 200, c = 'yellow', label = 'Center')

plt.title('Clusters of Iris')

plt.xlabel('Petal.Length')

plt.ylabel('Petal.Width')

plt.legend()

plt.show()

聚类分析的一些套路

3. 聚类算法调优

3.1 极端值处理

从散点图来看:鸢尾花数据集中是没有特别极端的值的,但是实际数据中很可能存在离群点或极端值(如某个大客户的交易额),这些样本点会增加极差,聚类效果不佳(绝大部分聚为一类,个别样本聚为一类),但换个角度想,这些恰恰是我们的异常数据,可以做异常检查,比如说刷单客户识别,这样的场景下我们不要对数据分布进行处理。

3.2 聚类个数的确定

我们知道鸢尾花数据集中有setosa、versicolor、virginica三个品种,但实际上聚类算法是无监督学习算法,我们并不知道结果,那么如何确定聚类个数呢? 按照聚类算法“物以类聚,人以群分”的思想,自然是簇内距离最小,簇间距离最大为最好的分群标准。

# 使用inertia或silhouette_score来确定

from sklearn import metrics

plt.figure(figsize=[8, 2])

rng1 = range(1, 11)

rng2 = range(2, 11)

inertia = []

silhs = []

for k in rng1:

    model = KMeans(n_clusters=k)

    model.fit(iris.data)

    inertia.append(model.inertia_)

    

for k in rng2:

    model = KMeans(n_clusters=k)

    model.fit(iris.data)

    silhs.append(metrics.silhouette_score(iris.data, model.predict(iris.data)))  

    

plt.subplot(121)

plt.title('inertia')

plt.plot(rng1, inertia)



plt.subplot(122)

plt.title('silhouette_score')

plt.plot(rng2, silhs) 

plt.show()

聚类分析的一些套路

从上图可以看出:inertia在K=2时出现拐点,silhouette_score在K=2时最大,说明聚为2类比较合适。从鸢尾花花瓣的散点图来看,散点确实分布在两个区域。 这里只做算法演示,实际运用中还是要根据客观情况决定。比如本例中我们已知是三个品种的鸢尾花数据,那么肯定是要聚为三类的。

# 看一下聚为两类时各客群的样本量

import pandas as pd

model_kmeans = KMeans(n_clusters=2, init='k-means++', random_state=123)

y_pred = model_kmeans.fit_predict(iris.data)

df_y_pred = pd.DataFrame(y_pred, columns=['cluseter'])

df_y_pred['cluseter'].value_counts()

聚类分析的一些套路

可以看到聚为两类时一个客群97个样本,一个客群53个样本。

3.3 变量的选择

我们在对样本进行聚类时,通常有许多指标可供选择,但是选择哪些指标呢?我们可以从两个方面来选择:一是看数据分布,只选择我们看中的且特征明显的指标;二是对我们认为应该选中的指标进行降维,例如主成分分析(PCA)。

3.3.1 主观选择变量

# 看一下鸢尾花的四个指标的散点图分布

import seaborn as sns

df_iris = pd.concat([pd.DataFrame(iris.data, columns=iris.feature_names), pd.DataFrame(iris.target, columns=['species'])], axis=1)

sns.pairplot(df_iris,

            hue='species', kind='reg', diag_kind='kde', size=1.5)

plt.show()

聚类分析的一些套路

可以看到三个品种的花萼长度和花萼宽度散点图区别不大,而花瓣长度和花瓣宽度散点图区别较大,我们只选用花瓣数据进行聚类。

由于我们已知三个鸢尾花,我们使用模型的调整兰德指数来作为聚类效果的评判标准。(注:实际中并不知道分类结果,我们这里只做算法比较用)。 调整兰德指数 adjusted_rand_s:值介于0到1之间,值越大,聚类效果越好。

# 先来看一下使用四个变量聚为三类的模型得分

model_a = KMeans(n_clusters=3, init='k-means++', random_state=123)

y_pred_a = model_a.fit_predict(iris.data)

ARI_a = metrics.adjusted_rand_score(y_pred_a, iris.target)

ARI_a

得到:ARI_a=0.73

# 仅使用花瓣的两个变量聚为三类的模型得分

model_b = KMeans(n_clusters=3, init='k-means++', random_state=123)

y_pred_b = model_a.fit_predict(iris.data[:,2:4])

ARI_b = metrics.adjusted_rand_score(y_pred_b, iris.target)

ARI_b

得到:ARI_b=0.89

3.3. 2 对多变量降维

from sklearn.decomposition import PCA

pca = PCA(n_components=4)

pca.fit(iris.data)

pca.explained_variance_ratio_

得到主成分的方差解释比例:array([0.92461621, 0.05301557, 0.01718514, 0.00518309]), 可以看到第一个主成分就能解释92%的方差(一般前n个主成分累计超过80%即可),所以我们可以选择一个主成分,但是为了数据展示需要,这里我们选择两个主成分。

pca = PCA(n_components=2)

pca.fit(iris.data)



iris_data_pca = pca.transform(iris.data)
# 先看一下得到的降维数据三种鸢尾花散点图

plt.scatter(iris_data_pca[:, 0], iris_data_pca[:, 1],c=iris.target)

plt.title('pca iris data')

plt.show()

聚类分析的一些套路

# 使用降维后的数据进行聚类

model_c = KMeans(n_clusters=3, init='k-means++', random_state=123)

y_pred_c = model_c.fit_predict(iris_data_pca)

ARI_c = metrics.adjusted_rand_score(y_pred_c, iris.target)

ARI_c

得到:ARI_c=0.72, 略低于ARI_a的0.73。本例中聚类效果没有提升,但使用PCA可以解决高维变量的聚类问题。

3.4 变量分布处理

当我们需要将全部样本数据较均匀的拆分为N个客群时,样本数据的分布会造成较大的影响,为此我们可以改变样本数据的分布形态,来达到均衡客群量的问题。

# 先正态化后再聚类

from sklearn.preprocessing import StandardScaler, Normalizer



iris_norm = Normalizer().fit_transform(iris.data)

model_d = KMeans(n_clusters=3)

y_pred_d = model_d.fit_predict(iris_norm)

ARI_d = metrics.adjusted_rand_score(y_pred_d, iris.target)

ARI_d

ARI_d提升到了0.90!

# 正态+降维后再聚类

iris_norm_pca = PCA(n_components=2).fit_transform(iris_norm)

model_e = KMeans(n_clusters=3).fit(iris_norm_pca)

y_pred_e = model_e.fit_predict(iris_norm)

ARI_e = metrics.adjusted_rand_score(y_pred_e, iris.target)

ARI_e

本例中ARI_e并没有提升。

4. 总结

综上,我们总结一下开篇提到的四个问题:

①极端值问题:若是识别异常客户,极端值是不需要处理的;若是分群,可以对数据进行标准化、正态化处理。

②指标太多、量纲处理:首先可以主观判断,其次可以使用主成分分析。比如使用销售额、利润额和毛利率三个指标直接聚类显然是不合适的。

③客群大小:可以正态化处理让客群大小更加均衡,有时可以调整客群数来满足客群量的问题。

④聚为几类:如果是明确的,就直接聚为几类;也可以通过树状图、inertia、silhouette来确定。

以上,如有不妥之处还请多多指正。

聚类分析的一些套路

本文由okajun 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。

转载、引用前需联系作者,并署名作者且注明文章出处。

本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。


以上所述就是小编给大家介绍的《聚类分析的一些套路》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机网络(第5版)

计算机网络(第5版)

Andrew S. Tanenbaum、David J. Wetherall / 严伟、潘爱民 / 清华大学出版社 / 2012-3-1 / 89.50元

本书是国内外使用最广泛、最权威的计算机网络经典教材。全书按照网络协议模型自下而上(物理层、数据链路层、介质访问控制层、网络层、传输层和应用层)有系统地介绍了计算机网络的基本原理,并结合Internet给出了大量的协议实例。在讲述网络各层次内容的同时,还与时俱进地引入了最新的网络技术,包括无线网络、3G蜂窝网络、RFID与传感器网络、内容分发与P2P网络、流媒体传输与IP语音,以及延迟容忍网络等。另......一起来看看 《计算机网络(第5版)》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试