Python数据分析案例27——PCA-K均值-轮廓系数客户聚类

news/2024/5/20 9:41:57 标签: python, 聚类, 数据分析, 数据挖掘, 主成分分析

本案例适合应用统计,数据科学,电商专业


K均值对客户进行分类的案例都做烂了......但我认为这个案例还是有一定的价值的,使用了pca,还有轮廓系数寻找最优的聚类个数。

下面来看看


代码准备

导入包

python">import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
import seaborn as sns

pd.set_option('display.max_columns', None) 

读取客户的特征数据,就是每个客户买不同种类的商品的消费金融

python">category_spends = pd.read_csv("category_spends_sample.csv")
category_spends.fillna(0, inplace=True)
print(category_spends.shape)
category_spends.head()

可以看到总共有3000个客户,

下面把这3000客户的消费记录都读取进来

python">baskets_sample = pd.read_csv("baskets_sample.csv")
baskets_sample.fillna(0, inplace=True)
print(baskets_sample.shape)
baskets_sample.head()

 

可以看到这3000个客户有19w的消费记录。

查看一下是不是3000个客户

python">baskets_sample['customer_number'].unique().shape

 

没问题。

然后我们需要构建一个特征,表示客户的最近一次消费的时间,就是FRM模型里面的R,

python">recent =baskets_sample.groupby('customer_number').agg({'purchase_time': 'max'})
recent['purchase_time']= pd.to_datetime(recent['purchase_time'])
recent.head()

 

然后处理一下

python">recent=recent.assign(recency=pd.to_datetime('2007-08-31 21:55:00')-recent['purchase_time'])
recent = recent.reset_index()[['customer_number','recency']]
recent['recency']=recent['recency']/pd.Timedelta(days=1)    #变成天
recent = recent.drop_duplicates()
recent.head()

 

这样客户就多了Recency这个特征,然后再读取一个顾客消费金融的数据集

python">customers_sample = pd.read_csv('customers_sample.csv')
customers_sample.fillna(0, inplace=True)
print(customers_sample.shape)
customers_sample.head()

就是每个客户的一些特征。

总之上面的事情都是在提取客户的特征。把这些特征进行合并

python">data =pd.merge(category_spends, customers_sample, on='customer_number')
data=pd.merge(data, recent, on='customer_number')
customer_ID=data['customer_number']
data.drop(['customer_number'], axis = 1, inplace = True)
data.head()

然后下面对这些特征进行可视化


可视化图 

python">data.hist(grid=False,figsize =(16,10))
plt.tight_layout()
plt.show()

相关性热力图

python">plt.figure(figsize=(18,18),dpi=128)
sns.heatmap(data.corr(), cmap="Oranges",annot=True)
plt.xticks(range(len(data.columns)), data.columns);
plt.yticks(range(len(data.columns)), data.columns);
plt.show()

 

删除一些不用的特征

python">data.drop(['average_spend','average_quantity','total_quantity'], axis = 1, inplace = True)

 直方图

python">logged_data = np.log(data+1)
logged_data.columns = data.columns
logged_data.hist(grid=False, figsize=(15,13))  
plt.show()


PCA主成分

进行pca降维

python">from sklearn.decomposition import PCA
pca = PCA()
pca.fit(logged_data)
print(data.columns)
print(len(data.columns))
print(pca.explained_variance_ratio_)

python">plt.plot(pca.explained_variance_ratio_.cumsum(), 'o-')
plt.xlabel('Principal Component')
plt.ylabel('Cumulative Proportion of Variance Explained')
plt.axvline(8, color='k', linestyle='--', linewidth=1)
plt.title('Cumulative PVE')

 

可以看到大概9个主成分就到了进80%的解释能力

拟合9个主成分,画图,表示每个主成分和原来的x的关系

python">#-- Generate a PCA factorization of your data
pca = PCA(n_components= 9)
pca.fit(logged_data)
#-- import a helpful set of functions to ease displaying results..
import renders as rs
#-- Generate a PCA results plot 
pca_results = rs.pca_results(data, pca)

 

这个图可以清楚的看到每个主成分是员原来的X的如何的线性组合。

拟合

python">from sklearn.decomposition import PCA

pca = PCA(n_components=9)
pca.fit(logged_data)
print(data.columns)
print(pca.components_)

计算轮廓系数,寻找最佳的聚类个数

python">from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# Create range of clusters 
range_n_clusters = list(range(5,8))
print(range_n_clusters)
range_score = []
# Loop through clusters
for n_clusters in range_n_clusters:
    # TODO: Apply your clustering algorithm of choice to the reduced data 
    clusterer = KMeans(n_clusters=n_clusters).fit(reduced_data)

    # TODO: Predict the cluster for each data point
    preds = clusterer.predict(reduced_data)

    # TODO: Find the cluster centers
    centers = clusterer.cluster_centers_

    # TODO: Calculate the mean silhouette coefficient for the number of clusters chosen
    score = silhouette_score(reduced_data, preds, metric='euclidean')
    range_score.append(score)
    print("For n_clusters = {}. The average silhouette_score is : {})".format(n_clusters, score))

python">plt.plot(range_n_clusters, range_score)
plt.show()

 

聚类个数为6的时候最大,我们选择聚类6个。

聚类结果画图上

python">clusterer = KMeans(n_clusters=6).fit(reduced_data)
preds = clusterer.predict(reduced_data)
centres = clusterer.cluster_centers_

#-- Put the predictions into a pandas dataframe format
assignments = pd.DataFrame(preds, columns = ['Cluster'])

#-- Put the predictions into a pandas dataframe format
plot_data = pd.concat([assignments, reduced_data], axis = 1)

#-- Color the points based on assigned cluster (n.b scatter will do this for us automatically)
plt.rcParams['figure.figsize'] = (14.0, 8.0)

for i, c in plot_data.groupby('Cluster'):  
    plt.scatter(c[0], c[1])
    
#-- Plot where the cluster centers are
for i, c in enumerate(centres):
    plt.scatter(x = c[0], y = c[1], color = 'white', edgecolors = 'black', marker = 'o', s=300);
    plt.scatter(x = c[0], y = c[1], marker='${}$'.format(i), alpha = 1, s=50);

 

 查看聚类中心

python"># TODO: Inverse transform the centres
log_centres = pca.inverse_transform(centres)

# TODO: Exponentiate the centres
true_centres = np.exp(log_centres)

#-- Display the true centres
segments = ['Segment {}'.format(i) for i in range(0, len(centres))]
true_centres = pd.DataFrame(np.round(true_centres), columns = data.columns)
true_centres.index = segments
true_centres

  合并聚类的结果

python">final_assigments = pd.concat([customer_ID,assignments, data], axis = 1)
#final_assigments['customer_number']=customer_ID
final_assigments

 储存:

python">final_assigments.to_csv('result.csv',index=False)

这样每个客户属于哪一类都打上了标签,他们的特征也都跟在后面了


http://www.niftyadmin.cn/n/354689.html

相关文章

appsync unified怎么安装

一、什么是AppSync Unified? AppSync Unified是一款iOS设备上的越狱插件,它可以帮助用户安装和运行未经苹果审核的应用程序和插件。AppSync Unified可以支持iOS 11-14系统,并可以在iPhone和iPad上使用。它的功能主要是允许用户安装和运行不经…

Linux工具:vim常用快捷键

1、拷贝行(一般模式下) 拷贝当前行 将光标移动到指定行,yy 移动到想要粘贴的行,p 即可把拷贝的行粘贴到该行下方 拷贝n行 将光标移动到指定行,比如拷贝5行,5yy 移动到想要粘贴的行,p 即可把拷贝的几行粘贴到该行下方…

day17 回话跟踪技术Cookie与Session

会话跟踪技术 问题:一次会话中的多次请求不会共享数据,不能显示.若通过传参数在路径上来解决该问题,不安全. 作用:解决HTTP无状态 http,cookie,session使用的区别 如果使用http中的request.setAttribute(),只能一次共享一个 若使用cookie,cookie存在浏览器中,每一次请求都…

sqlmap命令大全(附详细扫描流程)

一、sqlmap命令大全。 -u 指定目标URL (可以是http协议也可以是https协议)-d 连接数据库--dbs 列出所有的数据库--current-db 列出当前数据库--tables 列出当前的表--columns 列出当前的列-D 选择使用哪个数据库-T 选择使用哪个表-C 选择使用哪个列--dump 获取字段中的数据--…

day3 - 图像在不同色彩空间间的转换

本期将了解三种不同的颜色空间,RGB,HSV,GRAY。会使用OpenCV来读取三种颜色空间,并且操作不同空间的转换,观察不同颜色空间的特点。 完成本期内容,你可以: 了解RGB,HSV,G…

【严重】ejs 存在服务端模板注入漏洞(存在POC)

漏洞描述 EJS 是开源的 JavaScript 模板引擎,允许在HTML代码中使用JavaScript代码块,closeDelimiter 参数是 EJS 模板中的结束标记,用于指定结束分隔符。 由于对 CVE-2022-29078 漏洞修复不完全,当应用程序使用 EJS 模板引擎&am…

使用 Vite 安装 Tailwindscss

两个都是目前很火的开发工具,使用起来效率会很高 1:创建项目目录 2:进入项目目录初始化 NPM npm init -y 3:将 Tailwindscss 与 vite 一起安装 npm install -D tailwindcss postcss autoprefixer vite 4: 创建 Tailwindscss 初始化文件 npx tailwindcss init…

c++术语大总结

参数 (实参)像函数传递的值 赋值 抹去一个对象的当前值,用一个新值取代之。 程序块 零条或多条语句的序列,用花括号包围。 缓冲区 是一个储存区域,用于保存数据。IO 设施通常将输入(或输出&#xff…