机器学习:从数据中找到用户的RFM值分布情况

释放双眼,带上耳机,听听看~!
本文介绍了如何使用聚类算法分析RFM值分布情况,了解用户的价值分布以及使用K-Means算法确定聚类数量的方法。

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,《机器学习:从数据中找到用户的RFM值》跟着课程进行了定义问题、数据收集和预处理得到了RFM值,但是并不能直观的看出用户的 “价值”分布 情况,下面可以先通过分布直方图来大致的分布情况。

大致看看RFM分布情况

R值分布

df_user['R值'].plot(kind='hist',bins=25,title='新进度分布直方图') #R值直方图

机器学习:从数据中找到用户的RFM值分布情况

F值分布

df_user.query('F值 < 800')['F值'].plot(kind='hist',bins=50,title='消费频率分布直方图') #F值直方图

之所以筛选了 'F值 < 800' 是因为后面的值占比过于小,可以通过df_user.describe()#df_user的统计信息,默认只对数值类数据进行统计 查看

机器学习:从数据中找到用户的RFM值分布情况

M值分布

df_user.query('M值 < 20000')['M值'].plot(kind='hist',bins=50,title='消费金额分布直方图') #M值直方图

机器学习:从数据中找到用户的RFM值分布情况

第一感受是越靠近前面的值人数越多,但是并不能将用户划分为像“高”、“中”、“低”价值。

那么我们有没有办法将用户划分为呢?当然可以最简单的方法是去试比如将R值0-50分为一组,50-150分为一组,150以上分为一组,看用户是不是在次分组下聚集,如果不聚集就继续尝试,很显然这种方法不够高效,那么就需要借助算法了。

使用聚类算法贴标签

给用户分组画像属于无监督学习,因为源数据中没有字段指明用户的价值是“高”还是“低”。在无监督学习中,聚类和降维是最常见的算法,这里要使用的就是聚类了。

聚类算法

聚类算法可以让机器把数据集中的样本按照特征的性质分组,不过它只帮助我们把特征彼此邻近的用户聚成一组(这里的组称为聚类的蔟)。而这里说的“特征彼此邻近”,指的这些用户的数据特征在坐标系中有更短的向量空间距离。也就是说,聚类算法是把空间位置相近的特征数据归为同一组。

机器学习:从数据中找到用户的RFM值分布情况

分为组之后就可以人为贴标签了,比如这里的“价值高低”。这样就可以实现监督学习向监督学习的转换。

K-Means算法

课程中作者没有说为啥选择K-Means,这个展示搁置。

算法中的K代表聚类的簇(也就是组)的个数,指定K的数值后,K-Means算法会在数据中随机挑选出K个数据点,作为簇的质心(centroid),这些质心就是未来每个簇的中心点,算法会根据其他数据点和它的距离来进行聚类。

如果质心离在数据簇中不够中心就会进行移动,直到质心的移动变化很小了,或者说固定不变了,那么K-Means算法就可以停止了。

下面是选取质心并移动的过程:

机器学习:从数据中找到用户的RFM值分布情况

那么K值怎么确定呢?

手肘法选取K值

“手肘法”(elbow method)可以帮我们决定,在某一批数据点中,数据分为多少组比较合适。

手肘法是通过聚类算法的损失值曲线来直观确定簇的数量。损失值曲线,就是以图像的方法绘出,取每一个K值时,各个数据点距离质心的平均距离。

机器学习:从数据中找到用户的RFM值分布情况

定义手肘点的函数:

from sklearn.cluster import KMeans #导入KMwans模块
def show_elbow(df): # 定义手肘函数
    distance_list = [] # 聚质心的距离(损失)
    K = range(1,9) #K值范围
    for k in K:
        kmeans = KMeans(n_clusters=k,max_iter=100) # 创建KMeans模型
        kmeans = kmeans.fit(df) # 拟合模型
        distance_list.append(kmeans.inertia_) # 创建每个K值的损失
    plt.plot(K,distance_list,'bx-') # 绘画
    plt.xlabel('k') # X轴
    plt.ylabel('距离均方误差') # Y轴
    plt.title('k值手肘图') # 标题

R值聚类K值手肘图:

show_elbow(df_user[['R值']]) # 显示R值聚类K值手肘图

机器学习:从数据中找到用户的RFM值分布情况

F值聚类K值手肘图:

show_elbow(df_user[['F值']]) # 显示F值聚类K值手肘图

机器学习:从数据中找到用户的RFM值分布情况

M值聚类K值手肘图:

show_elbow(df_user[['M值']]) # 显示M值聚类K值手肘图

机器学习:从数据中找到用户的RFM值分布情况

选取肘部位置,选择3作为R值簇的个数,选择4作为F值簇的个数(笔者觉得5才是,先按课程的来),选择4作为M值簇的个数(笔者觉得3才是,先按课程的来)。

创建和训练模型

创建模型

from sklearn.cluster import KMeans #导入KMeans模块
kmeans_R = KMeans(n_clusters=3) #设定K=3
kmeans_F = KMeans(n_clusters=4) #设定K=4
kmeans_M = KMeans(n_clusters=4) #设定K=4

训练模型

kmeans_R.fit(df_user[['R值']]) #拟合模型
kmeans_F.fit(df_user[['F值']]) #拟合模型
kmeans_M.fit(df_user[['M值']]) #拟合模型

使用模型进行聚类,并给用户分组

给R、F、M值聚类

df_user['R值层级']=kmeans_R.predict(df_user[['R值']]) #通过聚类模型求出R值的层级
df_user.head()#显示头几行数据

机器学习:从数据中找到用户的RFM值分布情况

df_user.groupby('R值层级')['R值'].describe() # R值层级分组统计信息

机器学习:从数据中找到用户的RFM值分布情况

0表示距离上次消费以来从231到372天,1表示0-94天,2表示95-225天。可以看出不能直接使用体现价值的高低,需要人为排序。

为聚类的层级做排序

#定义一个order_cluster函数为聚类排序
def order_cluster(cluster_name, target_name,df,ascending=False):
    new_cluster_name = 'new_' + cluster_name #新的聚类名称
    df_new = df.groupby(cluster_name)[target_name].mean().reset_index() #按聚类结果分组,创建df_new对象
    df_new = df_new.sort_values(by=target_name,ascending=ascending).reset_index(drop=True) #排序
    df_new['index'] = df_new.index #创建索引字段
    df_new = pd.merge(df,df_new[[cluster_name,'index']], on=cluster_name) #基于聚类名称把df_new还原为df对象,并添加索引字段
    df_new = df_new.drop([cluster_name],axis=1) #删除聚类名称
    df_new = df_new.rename(columns={"index":cluster_name}) #将索引字段重命名为聚类名称字段
    return df_new #返回排序后的df_new对象
  • 排序后的R值聚类
df_user=order_cluster('R值层级','R值',df_user,False)
df_user.groupby('R值层级')['R值'].describe()

机器学习:从数据中找到用户的RFM值分布情况

  • 排序后的F值聚类
df_user['F值层级']=kmeans_F.predict(df_user[['F值']]) # 通过聚类模型求出F值的层级
df_user=order_cluster('F值层级','F值',df_user,True) # 调用蔟排序函数
df_user.groupby('F值层级')['F值'].describe() 

机器学习:从数据中找到用户的RFM值分布情况

  • 排序后的M值聚类
df_user['M值层级'] = kmeans_M.predict(df_user[['M值']]) #通过聚类模型求出M值的层级
df_user = order_cluster('M值层级', 'M值',df_user,True) #调用簇排序函数
df_user.groupby('M值层级')['M值'].describe() #M值层级分组统计信息
df_user = df_user.sort_values(by='用户码',ascending=True).reset_index(drop=True) #根据用户码排序
df_user.head() #显示头几行数据

机器学习:从数据中找到用户的RFM值分布情况

为用户整体分组画像

这里可以把R、F、M三个层级的值相加,得到总体价值。

df_user['总分']=df_user['R值层级']+df_user['F值层级']+df_user['M值层级'] # 求出每个用户RFM总分

总价值,最大值为8,所以范围是0-8,可以根据以下规则给用户分层:

  • 0-2 分,低价值用户
  • 3-4 分,中价值用户
  • 5-8 分,高价值用户
#在df_user对象中添加总体价值这个字段
df_user.loc[(df_user['总分']<=2) & (df_user['总分']>=0), '总体价值'] = '低价值' 
df_user.loc[(df_user['总分']<=4) & (df_user['总分']>=3), '总体价值'] = '中价值' 
df_user.loc[(df_user['总分']<=8) & (df_user['总分']>=5), '总体价值'] = '高价值'
df_user #显示df_user

机器学习:从数据中找到用户的RFM值分布情况

现在有了“标签”可以看看R、F、M和标签的相关性:

# 显示高、中、低价值组分布散点图(F值与M值)
plt.scatter(df_user.query("总体价值 == '高价值'")['F值'],df_user.query("总体价值 == '高价值'")['M值'],c='g',marker='*')
plt.scatter(df_user.query("总体价值 == '中价值'")['F值'], df_user.query("总体价值 == '中价值'")['M值'],marker=8)
plt.scatter(df_user.query("总体价值 == '低价值'")['F值'], df_user.query("总体价值 == '低价值'")['M值'],c='r')

机器学习:从数据中找到用户的RFM值分布情况

来源

06 | 聚类分析:如何用RFM给电商用户做价值分组画像?

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

人类与AI GPT-4首次辩论:挑战未来的对决

2023-12-14 17:58:14

AI教程

基于深度学习的海洋生物识别技术

2023-12-14 18:06:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索