本文分享自华为云社区《基于Kmeans聚类算法进行客户人群分析云社区华为云》,作者:HWCloudAI。实验目标掌握如何通过机器学习算法进行用户群体分析;掌握如何使用pandas载入、查阅数据;掌握如何调节Kmeans算法的参数,来控制不同的聚类中心。案例内容介绍 在本案例中,我们使用人工智能技术的聚类算法去分析超市购物中心客户的一些基本数据,把客户分成不同的群体,供营销团队参考并相应地制定营销策略。 俗话说,物以类聚,人以群分,聚类算法其实就是将一些具有相同内在规律或属性的样本划分到一个类别中,算法的更多理论知识可参考此视频。 我们使用的数据集是超市用户会员卡的基本数据以及根据购物行为得出的消费指数,总共有5个字段,解释如下:CustomerID:客户IDGender:性别Age:年龄AnnualIncome(k):年收入SpendingScore(1100):消费指数注意事项如果你是第一次使用JupyterLab,请查看《ModelAtrsJupyterLab使用指导》了解使用方法;如果你在使用JupyterLab过程中碰到报错,请参考《ModelAtrsJupyterLab常见问题解决办法》尝试解决问题。实验步骤1。准备源代码和数据 这步准备案例所需的源代码和数据,相关资源已经保存在OBS中,我们通过ModelArtsSDK将资源下载到本地,并解压到当前目录下。解压后,当前目录包含data和src两个目录,分别存有数据集和源代码。importosfrommodelarts。sessionimportSessionifnotos。path。exists(kmeanscustomersegmentation):sessionSession()session。downloaddata(bucketpathmodelartslabsbj4v2courseaiinaction2021machinelearningkmeanscustomersegmentationkmeanscustomersegmentation。zip,path。kmeanscustomersegmentation。zip)使用tar命令解压资源包os。system(unzip。kmeanscustomersegmentation。zip)Successfullydownloadfilemodelartslabsbj4courseaiinaction2021machinelearningkmeanscustomersegmentationkmeanscustomersegmentation。zipfromOBStolocal。kmeanscustomersegmentation。zip2。导入工具库 matplotlib和seaborn是Python绘图工具,pandas和numpy是矩阵运算工具。 此段代码只是引入Python包,无回显(代码执行输出)。!pipinstallnumpy1。16。0importnumpyasnplinearalgebraimportpandasaspddataprocessing,CSVfileIO(e。g。pd。readcsv)importmatplotlib。pyplotaspltimportseabornassnsfromsklearn。clusterimportKMeansimportwarningsimportoswarnings。filterwarnings(ignore)Requirementalreadysatisfied:numpy1。16。0inhomemauseranaconda3envsXGBoostSklearnlibpython3。6sitepackages〔33mYouareusingpipversion9。0。1,howeverversion21。1。3isavailable。Youshouldconsiderupgradingviathepipinstallupgradepipcommand。〔0m3。数据读取 使用pandas。readexcel(filepath)方法读取notebook中的数据文件。filepath:数据文件路径dfpd。readcsv(。kmeanscustomersegmentationdataMallCustomers。csv)4。展示样本数据 执行这段代码可以看到数据集的5个样本数据df。head() 执行这段代码可以看到数据集的维度df。shape(200,5)5。展示各个字段的统计值信息 调用pandas。DataFrame。describe方法,可以看到各个特征的统计信息,包括样本数、均值、标准差、最小值、14分位数、12分位数、34分位数和最大值。df。describe() 6。展示各个字段的数据类型 pandas。DataFrame。dtypes()方法可以展示各个字段的类型信息。 可以看到每个字段的类型信息。df。dtypesCustomerIDint64GenderobjectAgeint64AnnualIncome(k)int64SpendingScore(1100)int64dtype:object 查看是否有数据缺失,如果有,则需要填补。 实验中使用的这份数据很完善,没有任何一个属性的值为null,因此统计下来,null值的数量都是0df。isnull()。sum()CustomerID0Gender0Age0AnnualIncome(k)0SpendingScore(1100)0dtype:int647。展示主要属性的数量分布 这段代码使用matplotlib绘制了数据中三个主要属性的统计直方图,包含年龄、收入、消费指数。 可以看到三张统计直方图,形状都与正态分布类似,说明数据量足够,数据抽样的分布也比较理想。plt。style。use(fivethirtyeight)plt。figure(1,figsize(15,6))n0forxin〔Age,AnnualIncome(k),SpendingScore(1100)〕:n1plt。subplot(1,3,n)plt。subplotsadjust(hspace0。5,wspace0。5)sns。distplot(df〔x〕,bins20)plt。title(Distplotof{}。format(x))plt。show() 8。展示男、女客户数量的分布 这段代码使用matplotlib绘制条状图,展示男、女样本数量的分布。 可以看到一张条状图。plt。figure(1,figsize(15,5))sns。countplot(yGender,datadf)plt。show() 9。观察不同属性之间的关系 展示任意两个属性之间的统计关系图。 此段代码执行后,会有9张统计图,展示了任意两个属性之间的统计关系。plt。figure(1,figsize(15,7))n0forxin〔Age,AnnualIncome(k),SpendingScore(1100)〕:foryin〔Age,AnnualIncome(k),SpendingScore(1100)〕:n1plt。subplot(3,3,n)plt。subplotsadjust(hspace0。5,wspace0。5)sns。regplot(xx,yy,datadf)plt。ylabel(y。split()〔0〕y。split()〔1〕iflen(y。split())1elsey)plt。show() 此段代码执行后,会有1张统计图,以性别为参照,展示了年龄和收入之间的对应统计关系plt。figure(1,figsize(15,6))forgenderin〔Male,Female〕:plt。scatter(xAge,yAnnualIncome(k),datadf〔df〔Gender〕gender〕,s200,alpha0。5,labelgender)plt。xlabel(Age),plt。ylabel(AnnualIncome(k))plt。title(AgevsAnnualIncomew。r。tGender)plt。legend()plt。show() 此段代码执行后,会有1张统计图,以性别为参照,展示了收入和消费指数之间的对应统计关系plt。figure(1,figsize(15,6))forgenderin〔Male,Female〕:plt。scatter(xAnnualIncome(k),ySpendingScore(1100),datadf〔df〔Gender〕gender〕,s200,alpha0。5,labelgender)plt。xlabel(AnnualIncome(k)),plt。ylabel(SpendingScore(1100))plt。title(AnnualIncomevsSpendingScorew。r。tGender)plt。legend()plt。show() 10。观察不同性别的客户的数据分布 观察不同性别的客户的数据,在年龄、年收入、消费指数上的分布。 此段代码执行后,会有六幅boxplot图像。plt。figure(1,figsize(15,7))n0forcolsin〔Age,AnnualIncome(k),SpendingScore(1100)〕:n1plt。subplot(1,3,n)plt。subplotsadjust(hspace0。5,wspace0。5)sns。violinplot(xcols,yGender,datadf,paletteBlues)sns。swarmplot(xcols,yGender,datadf)plt。ylabel(Genderifn1else)plt。title(BoxplotsSwarmplotsifn2else)plt。show() 11。使用Kmeans对数据进行聚类 根据年龄和消费指数进行聚类和区分客户。 我们使用110个聚类中心进行聚类。(此段代码无输出)AgeandspendingScoreX1df〔〔Age,SpendingScore(1100)〕〕。iloc〔:,:〕。valuesinertia〔〕forninrange(1,11):algorithm(KMeans(nclustersn,initkmeans,ninit10,maxiter300,tol0。0001,randomstate111,algorithmelkan))algorithm。fit(X1)inertia。append(algorithm。inertia) 观察10次聚类的inertias,并以如下折线图进行统计。 inertias是KMeans模型对象的属性,它作为没有真实分类结果标签下的非监督式评估指标。表示样本到最近的聚类中心的距离总和。值越小越好,越小表示样本在类间的分布越集中。 可以看到,当聚类中心大于等于4之后,inertias的变化幅度显著缩小了。plt。figure(1,figsize(15,6))plt。plot(np。arange(1,11),inertia,o)plt。plot(np。arange(1,11),inertia,,alpha0。5)plt。xlabel(NumberofClusters),plt。ylabel(Inertia)plt。show() 我们使用4个聚类中心再次进行聚类。(此段代码无输出)algorithm(KMeans(nclusters4,initkmeans,ninit10,maxiter300,tol0。0001,randomstate111,algorithmelkan))algorithm。fit(X1)labels1algorithm。labelscentroids1algorithm。clustercenters 我们把4个聚类中心的聚类结果,以下图进行展示。横坐标是年龄,纵坐标是消费指数,4个红点为4个聚类中心,4块不同颜色区域就是4个不同的用户群体。h0。02xmin,xmaxX1〔:,0〕。min()1,X1〔:,0〕。max()1ymin,ymaxX1〔:,1〕。min()1,X1〔:,1〕。max()1xx,yynp。meshgrid(np。arange(xmin,xmax,h),np。arange(ymin,ymax,h))Zalgorithm。predict(np。c〔xx。ravel(),yy。ravel()〕)plt。figure(1,figsize(15,7))plt。clf()ZZ。reshape(xx。shape)plt。imshow(Z,interpolationnearest,extent(xx。min(),xx。max(),yy。min(),yy。max()),cmapplt。cm。Pastel2,aspectauto,originlower)plt。scatter(xAge,ySpendingScore(1100),datadf,clabels1,s200)plt。scatter(xcentroids1〔:,0〕,ycentroids1〔:,1〕,s300,cred,alpha0。5)plt。ylabel(SpendingScore(1100)),plt。xlabel(Age)plt。show() 根据年收入和消费指数进行聚类和区分客户。 我们使用110个聚类中心进行聚类。(此段代码无输出)AnnualIncomeandspendingScoreX2df〔〔AnnualIncome(k),SpendingScore(1100)〕〕。iloc〔:,:〕。valuesinertia〔〕forninrange(1,11):algorithm(KMeans(nclustersn,initkmeans,ninit10,maxiter300,tol0。0001,randomstate111,algorithmelkan))algorithm。fit(X2)inertia。append(algorithm。inertia) 观察10次聚类的inertias,并以如下折线图进行统计。 可以看到,当聚类中心大于等于5之后,inertias的变化幅度显著缩小了。plt。figure(1,figsize(15,6))plt。plot(np。arange(1,11),inertia,o)plt。plot(np。arange(1,11),inertia,,alpha0。5)plt。xlabel(NumberofClusters),plt。ylabel(Inertia)plt。show() 我们使用5个聚类中心再次进行聚类。(此段代码无输出)algorithm(KMeans(nclusters5,initkmeans,ninit10,maxiter300,tol0。0001,randomstate111,algorithmelkan))algorithm。fit(X2)labels2algorithm。labelscentroids2algorithm。clustercenters 我们把5个聚类中心的聚类结果,以下图进行展示。横坐标是年收入,纵坐标是消费指数,5个红点为5个聚类中心,5块不同颜色区域就是5个不同的用户群体。h0。02xmin,xmaxX2〔:,0〕。min()1,X2〔:,0〕。max()1ymin,ymaxX2〔:,1〕。min()1,X2〔:,1〕。max()1xx,yynp。meshgrid(np。arange(xmin,xmax,h),np。arange(ymin,ymax,h))Z2algorithm。predict(np。c〔xx。ravel(),yy。ravel()〕)plt。figure(1,figsize(15,7))plt。clf()Z2Z2。reshape(xx。shape)plt。imshow(Z2,interpolationnearest,extent(xx。min(),xx。max(),yy。min(),yy。max()),cmapplt。cm。Pastel2,aspectauto,originlower)plt。scatter(xAnnualIncome(k),ySpendingScore(1100),datadf,clabels2,s200)plt。scatter(xcentroids2〔:,0〕,ycentroids2〔:,1〕,s300,cred,alpha0。5)plt。ylabel(SpendingScore(1100)),plt。xlabel(AnnualIncome(k))figplt。gcf()ifnotos。path。exists(results):os。mkdir(results)创建本地保存路径plt。savefig(resultsclusters。png)保存结果文件至本地plt。show() 至此,本案例完成。 点击下方,第一时间了解华为云新鲜技术 华为云博客大数据博客AI博客云计算博客开发者中心华为云