【火炉炼AI】机器学习027-项目案例:用聚类算法建立客户细分模型
(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
客户细分是市场营销成功的前提,我们从市场中获取的数据一般都没有标记,要想对这些市场数据进行客户细分,将客户划分簇群,这也是一种典型的无监督学习问题。
本项目拟用各种不同的聚类算法来建立客户细分模型,并比较这些聚类算法在这一问题上的优虐。
1. 准备数据集
本项目案例所使用到的原始数据集来源于: UCI大学数据集,这个数据集来源于一个批发商,一共包含有440个样本数据,每个样本数据包含有8列,但是其中的6列作为features,此处由于是无监督学习,不需要标记,故而只需要其中的六列数据,这些数据的说明如下表所示。
对于这6个features,数据集已经告诉我们这6列的min,max mean等信息,我把它们整理成一个表格,如下所示:
数据集的加载可以采用pd.read_csv函数来完成,代码可以参考我的github,下面我们随便选择两个feature,将其绘制到二维平面图上,看看这些数据点的分布情况,比如下图:
2. 构建均值漂移聚类模型
本项目用均值漂移算法来构建模型,模型的构建和训练过程和我以前的文章【火炉炼AI】机器学习022-使用均值漂移聚类算法构建模型一样,如下代码,只不过该代码还打印出聚类后簇群的数量,并把每一种簇群的质心点位置打印出来。
# 构建均值漂移聚类模型
from sklearn.cluster import MeanShift, estimate_bandwidth
bandwidth=estimate_bandwidth(dataset,quantile=0.8,
n_samples=len(dataset))
meanshift=MeanShift(bandwidth=bandwidth,bin_seeding=True)
meanshift.fit(dataset) # 使用评估的带宽构建均值漂移模型,并进行训练
labels=meanshift.labels_
cluster_num=len(np.unique(labels))
centroids=meanshift.cluster_centers_
# 下面打印出簇群种类,和质心位置信息
print('Number of Clusters: {}'.format(cluster_num))
print('\t'.join([col_name[:5] for col_name in col_names]))
for centroid in centroids:
print('\t'.join(str(int(x)) for x in centroid))
-------------------------------------输---------出--------------------------------
Number of Clusters: 8
FreshMilkGroceFrozeDeterDelic
963246716593257022961248
4020446314575845518254364241
1611746197927801026408272944
22925734983211498720070903
11215129627181481674549488550
3684743950201703653423947943
3271716784136266086912725609
8565498067298131381021215
--------------------------------------------完-------------------------------------
由此可见,均值漂移算法自动将本项目的数据集划分为8个不同类别,那么怎么查看聚类算法的效果图了?我先自定义了一个显示函数,用于展示各种不同聚类算法在不同数据集上的聚类效果,这个函数有一定的通用性,不仅可以可以用于均值漂移算法,还可以用于其他的各种聚类算法。如下为代码和运行结果。
def visual_cluster_effect(cluster,dataset,title,col_id):
assert isinstance(col_id,list) and len(col_id)==2,'col_id must be list type and length must be 2'
labels=cluster.labels_ # 每一个样本对应的簇群号码
# print(labels.shape) # (440,) 440个样本
markers=['.',',','o','v','^','','1','2','3','4','8'
,'s','p','*','h','H','+','x','D','d','|']
colors=['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple',
'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
# 将数据集绘制到图表中
plt.figure()
for class_id in set(labels):
one_class=dataset[class_id==labels]
print('label: {}, smaple_num: {}'.format(class_id,len(one_class)))
plt.scatter(one_class[:,0],one_class[:,1],marker=markers[class_id%len(markers)],
c=colors[class_id%len(colors)],label='class_'+str(class_id))
plt.legend()
# 将中心点绘制到图中
centroids=meanshift.cluster_centers_
# print(centroids.shape)# eg (8, 6) 8个簇群,6个features
plt.scatter(centroids[:,col_id[0]],centroids[:,col_id[1]],marker='o',
s=100,linewidths=2,color='k',zorder=5,facecolors='b')
plt.title(title)
plt.xlabel('feature_0')
plt.ylabel('feature_1')
plt.show()
使用这个函数,我们可以看到本聚类算法在数据集上的表现,如下代码中,我们主要查看Fresh vs milk这一类产品的聚类效果。
visual_cluster_effect(meanshift,dataset,'MeanShift-X=fresh,y=milk',[0,1]) # X=fresh, y=milk
-------------------------------------输---------出--------------------------------
label: 0, smaple_num: 428
label: 1, smaple_num: 3
label: 2, smaple_num: 1
label: 3, smaple_num: 1
label: 4, smaple_num: 3
label: 5, smaple_num: 1
label: 6, smaple_num: 1
label: 7, smaple_num: 2
--------------------------------------------完-------------------------------------
visual_cluster_effect(meanshift,dataset,'MeanShift-X=grocery,y=delica',[2,5]) # X=grocery, y=delicassen
从上面的图中我们很难看出模型到底是好还是坏,那我们就用指标来判断吧,前面我们学习过轮廓系数,可以用来评估模型的优虐,如下是评价代码。
# 使用轮廓系数评估模型的优虐
from sklearn.metrics import silhouette_score
si_score=silhouette_score(dataset,meanshift.labels_,
metric='euclidean',sample_size=len(dataset))
print('si_score: {:.4f}'.format(si_score))
-------------------------------------输---------出--------------------------------
si_score: 0.6548
--------------------------------------------完-------------------------------------
########################小**********结###############################
1,本文的数据集基本上都是已经处理过的,我们只需要加载后即可使用。
2,构建均值漂移算法的模型和训练该模型非常简单,但是里面额quantile参数可能需要进行优化才能得到最佳值。
3,为了查看本聚类算法在数据集上的表现优虐,我们先通过数据可视化,将聚类之后的簇群以及簇群质心绘制到图标中,这是一个多features数据集,故而数据的可视化只能一次取其中的两列来查看。
4,另外,我们还用轮廓系数来评估模型的好坏,此处模型的轮廓系数为0.6548,貌似不是太差,但也不是太好,看来还有优化空间,或者,我们可以采用其他算法来构建模型,比如前面我们学习到的K-means,DBSCAN,凝聚层次聚类等,看看其轮廓系数。
#################################################################
注:本部分代码已经全部上传到(我的github)上,欢迎下载。
参考资料:
1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译