赞
踩
一、导入库
- import plotly as py
- from sklearn.cluster import KMeans
- import warnings
- import os
- warnings.filterwarnings("ignore")
- py.offline.init_notebook_mode(connected = True)
- # for basic mathematics operation
- import numpy as np
- import pandas as pd
- from pandas import plotting
-
- # for visualizations
- import matplotlib.pyplot as plt
- import seaborn as sns
- plt.style.use('fivethirtyeight')
-
- # for interactive visualizations
- #镜像安装pip install xxx -i https://pypi.tuna.tsinghua.edu.cn/simple
- import plotly.offline as py
- #upyter 中实时输出plotly.offline.iplot函数可在jupyter中内嵌显示plotly交互式图表,只需要在jupyter notebook开头写入plotly.offline.init_notebook_mode(connected=True)即可:
- from plotly.offline import init_notebook_mode, iplot
- import plotly.graph_objs as go
- from plotly import tools
- init_notebook_mode(connected = True)
- import plotly.figure_factory as ff
使用plotly显示数据详细信息
- #解决不显示问题
- #在cmd中输入:jupyter notebook --generate-config,可以看到生成一个路径
- # 找到对应路径下的文件,从中找到iopub_data_rate_limit,在去掉注释后多加好多0
- #jupyter notebook --NotebookApp.iopub_data_rate_limit=2147483647
- df=pd.read_excel(r'D:pythondatakmeans.xlsx')
- dat=ff.create_table(df.head())
- #py.plot会生成一个离线的html文件,里面放置图片。而py.iplot则直接在ipython notebook 里面生成图片。
- py.iplot(dat)
- desc = ff.create_table(df.describe())
- py.iplot(desc)
df.describe()
查看是否存在空值
- df.isnull().any().any() --Flase
- df.isnull().sum()
- #pylot使用rc配置文件来自定义图形的各种默认属性,称之为rc配置或rc参数。通过rc参数可以修改默认的属性,包括窗体大小、每英寸的点数、线条宽度、颜色、样式、坐标轴、坐标和网络属性、文本、字体等
- plt.rcParams['figure.figsize'] = (15, 10)
- #第0轴沿着行的方向垂直向下,第1轴沿着列的方向水平延申。
- plotting.andrews_curves(df.drop('CustomerID',axis=1),'Genre')
- plt.title('Andrew Curves for Gender', fontsize = 20)
- plt.show()
已经证明,安德鲁斯曲线能够保留均值,距离(最大为常数)和方差。 这意味着用函数表示的安德鲁斯曲线靠得很近,这表明相应的数据点也将靠得很近。
- import warnings
- warnings.filterwarnings('ignore')
-
- plt.rcParams['figure.figsize'] = (18, 8)
-
- plt.subplot(1, 2, 1)
- sns.set(style = 'whitegrid')
- sns.distplot(df['Annual Income (k$)'])
- plt.title('Distribution of Annual Income', fontsize = 20)
- plt.xlabel('Range of Annual Income')
- plt.ylabel('Count')
-
-
- plt.subplot(1, 2, 2)
- sns.set(style = 'whitegrid')
- sns.distplot(df['Age'], color = 'red')
- plt.title('Distribution of Age', fontsize = 20)
- plt.xlabel('Range of Age')
- plt.ylabel('Count')
- plt.show()
在上面的图中,我们可以看到年收入和年龄的分布模式,通过查看这些图,
我们可以推断出一件事情,就是收入很少超过100美元的人很少。 大多数人的收入约为50-75美元。 另外,我们可以说收入最少的是20美元左右。
对客户进行推断。
购物中心的最常客年龄在30-35岁左右。 老年人年龄段是购物中心中访问频率最低的人群。 与中年人相比,青少年的人数较少。
- labels = ['Female', 'Male']
- size = df['Genre'].value_counts()
- colors = ['lightgreen', 'orange']
- #explode : 每一块饼图 离开中心距离,默认值为(0,0),就是不离开中心;
- explode = [0, 0.1]
-
- plt.rcParams['figure.figsize'] = (9, 9)
- #autopct = '%.2f%%':控制饼图内百分比设置,'%1.1f':指小数点后保留一位有效数值;
- plt.pie(size, colors = colors, explode = explode, labels = labels, shadow = True, autopct = '%.2f%%')
- plt.title('Gender', fontsize = 20)
- plt.axis('off')
- plt.legend()
- plt.show()
通过查看上面的饼图,该饼图说明了购物中心中性别的分布
有趣的是,女性以56%的份额居于领先地位,而男性则占44%的份额,尤其是当男性人口相对高于女性时,这是一个巨大的差距。
- plt.rcParams['figure.figsize'] = (15, 8)
- #调色板palette = 'hsv'
- #countplot对输入的数据分类,条形图显示各个分类的数量
- sns.countplot(df['Age'], palette = 'hsv')
- plt.title('Distribution of Age', fontsize = 20)
- plt.show()
此图显示了有关购物中心中每个年龄段分布的更具交互性的图表,以更加了解购物中心中的访客年龄组。
通过查看上面的图表,可以看到27至39岁的年龄段非常频繁,但没有明确的模式,我们只能找到一些群体明智的模式,例如,相比之下,年龄较大的年龄段人群的频率较低 。 有趣的事实,没有相等。 年龄分别为18岁和67岁的购物中心中的访客数量。年龄在55、56、69、64岁的人们在购物中心中的访问频率非常低。 32岁的人们是购物广场中最常来的游客。
- plt.rcParams['figure.figsize'] = (20, 8)
- sns.countplot(df['Annual Income (k$)'], palette = 'rainbow')
- plt.title('Distribution of Annual Income', fontsize = 20)
- plt.show()
可以更好地解释每个收入水平的分布,有趣的是,购物中心的顾客的频率与他们的年收入从15美元到137K美元不等,非常相似。 购物中心中有更多的客户,他们的年收入分别为54k美元或78美元。
- plt.rcParams['figure.figsize'] = (20, 8)
- sns.countplot(df['Spending Score (1-100)'], palette = 'copper')
- plt.title('Distribution of Spending Score', fontsize = 20)
- plt.show()
这是从购物中心的角度来看最重要的图表,因为对访问购物中心的顾客的消费分数有一些直觉和想法非常重要。
从总体上讲,我们可以得出结论,大多数客户的支出得分在35-60之间。 有趣的是,有些顾客的I消费得分也达到了99,这表明该购物中心可以满足各种顾客的需求,这些顾客在购物中心中的需求和要求各不相同。
- #pairplot多变量图
- sns.pairplot(df)
- plt.title('Pairplot for the Data', fontsize = 20)
- plt.show()
- plt.rcParams['figure.figsize'] = (15, 8)
- #cmap : matplotlib颜色表名称或对象,或颜色列表,可选从数据值到色彩空间的映射。
- #annot : 如果为True,则将数据值写入每个单元格中
- sns.heatmap(df.corr(), cmap = 'Wistia', annot = True)
- plt.title('Heatmap for the Data', fontsize = 20)
- plt.show()
上面的图表显示了商城客户细分数据集的不同属性之间的相关性,该热图反映了橙色的关联性最高的颜色和黄色的关联性最低的特征。
我们可以清楚地看到这些属性之间没有很好的相关性,这就是为什么我们将继续使用所有功能。
- # Gender vs Spendscore性别vs支出得分
- #pip --default-timeout=100 install --upgrade seaborn==0.9.0 升级seaborn版本
- #pip install --upgrade seaborn==0.9.0 scipy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
- #pip install --upgrade numpy==1.13.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
- #pip install --upgrade scipy==0.19.1 scipy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
- plt.rcParams['figure.figsize'] = (18, 7)
- sns.boxenplot(df['Genre'], df['Spending Score (1-100)'], palette = 'Blues')
- plt.title('Gender vs Spending Score', fontsize = 20)
- plt.show()
性别与支出得分之间的双变量分析,
显而易见,大多数男性的消费得分约为25,000美元至7万美元,而女性的消费得分约为35,000美元至75,000美元。 这再次表明女性是购物领袖。
- plt.rcParams['figure.figsize']=(18,7)
- sns.violinplot(df['Genre'],df['Annual Income (k$)'],palette='rainbow')
- plt.title('Gender vs Spending Score',fontsize=20)
- plt.show()
再次进行性别和年收入之间的双变量分析,以更好地可视化不同性别的收入。
报酬高于女性的男性人数更多。 但是,当年收入较低时,男性和女性人数相等。
- plt.rcParams['figure.figsize']=(18,7)
- #stripplot:分布散点图,按照x属性所对应的类别分别展示y属性的值,适用于分类数据。
- sns.stripplot(df['Genre'],df['Age'],palette='Purples',size=10)
- plt.title('Gender vs Spending Score',fontsize=20)
- plt.show()
- x = df['Annual Income (k$)']
- y = df['Age']
- z = df['Spending Score (1-100)']
- sns.lineplot(x,y,color='cyan')
- sns.lineplot(x,z,color='pink')
- plt.title('Annual Income vs Age and Spending Score',fontsize=20)
- plt.show()
上面的年收入和年龄之间的图用蓝色线表示,年收入和支出得分之间的图用粉红色表示。 显示年龄和支出如何随年收入变化。
- x=df.iloc[:,[3,4]].values
- print(x.shape)
K均值算法
肘部法寻找最佳聚类数
K_means参数的最优解是以成本函数最小化为目标
成本函数为各个类畸变程度之和
每个类的畸变程度等于该类重心与其内部成员位置距离的平方和
但是平均畸变程度会随着K的增大先减小后增大,所以可以求出最小的平均畸变程度
- from sklearn.cluster import KMeans
- wcss=[]
- for i in range(1,11):
- km=KMeans(n_clusters=i,init='k-means++',max_iter=300,n_init=10,random_state=0)
- km.fit(x)
- wcss.append(km.inertia_)
- plt.plot(range(1,11),wcss)
- plt.title('The Elbow Method',fontsize=20)
- plt.xlabel('No.of Clusters')
- plt.ylabel('wcss')
- plt.show()
可视化集群
- km=KMeans(n_clusters=5,init='k-means++',max_iter=300,n_init=10,random_state=0)
- y_means=km.fit_predict(x)
- plt.scatter(x[y_means == 0, 0], x[y_means == 0, 1], s = 100, c = 'pink', label = 'miser')
- plt.scatter(x[y_means == 1, 0], x[y_means == 1, 1], s = 100, c = 'yellow', label = 'general')
- plt.scatter(x[y_means == 2, 0], x[y_means == 2, 1], s = 100, c = 'cyan', label = 'target')
- plt.scatter(x[y_means == 3, 0], x[y_means == 3, 1], s = 100, c = 'magenta', label = 'spendthrift')
- plt.scatter(x[y_means == 4, 0], x[y_means == 4, 1], s = 100, c = 'orange', label = 'careful')
- plt.scatter(km.cluster_centers_[:,0], km.cluster_centers_[:, 1], s = 50, c = 'blue' , label = 'centeroid')
-
- plt.style.use('fivethirtyeight')
- plt.title('K Means Clustering', fontsize = 20)
- plt.xlabel('Annual Income')
- plt.ylabel('Spending Score')
- plt.legend()
- plt.grid()
- plt.show()
该聚类分析使我们对购物中心中不同客户群有了非常清晰的了解。 根据他们的年收入和支出得分,显然有五个细分客户,即轻度客户,一般客户,目标客户,节俭客户,谨慎客户,据报这是确定购物中心客户群的最佳因素/属性。
层次聚类
层次聚类,也称为层次聚类分析,是一种将相似对象分组为聚类的算法。 端点是一组群集,其中每个群集彼此不同,并且每个群集中的对象彼此大致相似
使用树状图查找编号。 最佳集群
- import scipy.cluster.hierarchy as sch
- dendrogram = sch.dendrogram(sch.linkage(x, method = 'ward'))
- plt.title('Dendrogam', fontsize = 20)
- plt.xlabel('Customers')
- plt.ylabel('Ecuclidean Distance')
- plt.show()
可视化分层聚类的聚类
- from sklearn.cluster import AgglomerativeClustering
- #最初将每个对象看成一个簇,然后将这些簇根据某种规则被一步步合并,就这样不断合并直到达到预设的簇类个数。
- #n_clusters:一个整数,指定分类簇的数量
- #affinity:一个字符串或者可调用对象,用于计算距离。可以为:’euclidean’,’l1’,’l2’,’mantattan’,’cosine’,’precomputed’,如果linkage=’ward’,则affinity必须为’euclidean’
- #linkage:一个字符串,用于指定链接算法
- #ward:单链接single-linkage,采用dmin,两个簇的样本对之间距离的最小值。
- #‘complete’:全链接complete-linkage算法,采用dmax,两个簇的样本对之间距离的最大值。
- #‘average’:均连接average-linkage算法,采用davg,两个簇的样本对之间距离的平均值。
- hc = AgglomerativeClustering(n_clusters = 5, affinity = 'euclidean', linkage = 'ward')
- #方法:
- #fit(X[,y]):训练样本
- #fit_predict(X[,y]):训练模型并预测每个样本的簇标记
- y_hc = hc.fit_predict(x)
-
- plt.scatter(x[y_hc == 0, 0], x[y_hc == 0, 1], s = 100, c = 'pink', label = 'miser')
- plt.scatter(x[y_hc == 1, 0], x[y_hc == 1, 1], s = 100, c = 'yellow', label = 'general')
- plt.scatter(x[y_hc == 2, 0], x[y_hc == 2, 1], s = 100, c = 'cyan', label = 'target')
- plt.scatter(x[y_hc == 3, 0], x[y_hc == 3, 1], s = 100, c = 'magenta', label = 'spendthrift')
- plt.scatter(x[y_hc == 4, 0], x[y_hc == 4, 1], s = 100, c = 'orange', label = 'careful')
- plt.scatter(km.cluster_centers_[:,0], km.cluster_centers_[:, 1], s = 50, c = 'blue' , label = 'centeroid')
-
- plt.style.use('fivethirtyeight')
- plt.title('Hierarchial Clustering', fontsize = 20)
- plt.xlabel('Annual Income')
- plt.ylabel('Spending Score')
- plt.legend()
- plt.grid()
- plt.show()
基于年龄的客户群
- x = df.iloc[:, [2, 4]].values
- x.shape
- from sklearn.cluster import KMeans
-
- wcss = []
- for i in range(1, 11):
- kmeans = KMeans(n_clusters = i, init = 'k-means++', max_iter = 300, n_init = 10, random_state = 0)
- kmeans.fit(x)
- wcss.append(kmeans.inertia_)
-
- plt.rcParams['figure.figsize'] = (15, 5)
- plt.plot(range(1, 11), wcss)
- plt.title('K-Means Clustering(The Elbow Method)', fontsize = 20)
- plt.xlabel('Age')
- plt.ylabel('Count')
- plt.grid()
- plt.show()
- kmeans = KMeans(n_clusters = 4, init = 'k-means++', max_iter = 300, n_init = 10, random_state = 0)
- ymeans = kmeans.fit_predict(x)
-
- plt.rcParams['figure.figsize'] = (10, 10)
- plt.title('Cluster of Ages', fontsize = 30)
-
- plt.scatter(x[ymeans == 0, 0], x[ymeans == 0, 1], s = 100, c = 'pink', label = 'Usual Customers' )
- plt.scatter(x[ymeans == 1, 0], x[ymeans == 1, 1], s = 100, c = 'orange', label = 'Priority Customers')
- plt.scatter(x[ymeans == 2, 0], x[ymeans == 2, 1], s = 100, c = 'lightgreen', label = 'Target Customers(Young)')
- plt.scatter(x[ymeans == 3, 0], x[ymeans == 3, 1], s = 100, c = 'red', label = 'Target Customers(Old)')
- plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s = 50, c = 'black')
-
- plt.style.use('fivethirtyeight')
- plt.xlabel('Age')
- plt.ylabel('Spending Score (1-100)')
- plt.legend()
- plt.grid()
- plt.show()
根据我自己的直觉,通过查看客户年龄与他们相应的支出得分之间的上述聚类图,我将他们分为4个不同类别,即“常规客户”,“优先客户”,“老年人目标客户”,“年轻目标客户”。 然后,在获得结果之后,我们可以据此制定不同的营销策略和政策,以优化购物中心客户的消费得分
- x = df[['Age', 'Spending Score (1-100)', 'Annual Income (k$)']].values
- km = KMeans(n_clusters = 5, init = 'k-means++', max_iter = 300, n_init = 10, random_state = 0)
- km.fit(x)
- labels = km.labels_
- centroids = km.cluster_centers_
-
-
- df['labels'] = labels
- trace1 = go.Scatter3d(
- x= df['Age'],
- y= df['Spending Score (1-100)'],
- z= df['Annual Income (k$)'],
- mode='markers',
- marker=dict(
- color = df['labels'],
- size= 10,
- line=dict(
- color= df['labels'],
- width= 12
- ),
- opacity=0.8
- )
- )
- df = [trace1]
-
- layout = go.Layout(
- title = 'Character vs Gender vs Alive or not',
- margin=dict(
- l=0,
- r=0,
- b=0,
- t=0
- ),
- scene = dict(
- xaxis = dict(title = 'Age'),
- yaxis = dict(title = 'Spending Score'),
- zaxis = dict(title = 'Annual Income')
- )
- )
-
- fig = go.Figure(data = df, layout = layout)
- py.iplot(fig)
- #样式美化
- #获取所有的自带样式
- print(plt.style.available)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。