总体思路

基于聚类的精准推荐总体
先基于聚类:把用户分群,对每一个客户都标记上标签值。1号和3号都属于标签A的客户。
推荐规则生成:

  • 推荐个客户的商品,都是ta没买过的
  • 在ta没有购买过的商品中,哪些是和ta同类客户最喜欢的?
    – 同类客户总购买次数(平均购买次数)最多的商品,就是这类客户最喜欢的商品
    – 同类客户总购买数量(平均购买数量)最多的商品,就是这类客户最喜欢的商品

数据整理和数据清洗的总体思路:

  1. 最终要生成推荐列表,前提是有一张表记录所有用户的购买行为(一行记录一个用户的所有购买行为信息)
  2. 用户购买行为记录表中所有的字段可以从什么地方提取。
  3. 从3张表中提取用户的购买行为数据,这3张表有什么关联(每张表中每一行记录有什么关系,通过什么条件来将不同表中的记录连接在一起)
    – 3张表哪些字段需要保留–和用户购买行为相关的字段尽可能保留(对聚类算法有用的尽可能保留)
    – 有些需要优先删除:1, 缺失率80%以上 2,一整个字段只有1个值 3,整个字段有效信息几乎没有
    – 需要转码:
    — 分类型变量: 如果是回归类模型:转哑编码
    — 分类型、基于距离的模型:主要独热编码
    – 每一张表都完成上面的处理,3张表最后合并到一起---->“用户购买行为记录表”
    — 最终的合并表,再作最后一次数据清洗

数据清洗和探索

订单表的清洗

import numpy as np,pandas as pd
order=pd.read_csv(r"D:\电商玩具店营销案例\data\order.csv",index_col=0) - 导入订单表
order.head()```
order.info()  - 查看订单表信息

删除无关字段

  • 删除缺失率高达80%以上的字段

```python
order=order.dropna(axis=1,thresh=order.shape[0]*0.2)
order.head()

删除整个字段只有一类的元素


```python
for  i in order.columns:if order[i].nunique()==1:del order[i]
order.shape
(3989, 17)

经过上面的操作,我们可以对剩下的字段进行人工筛选,哪些对作聚类有用的就留下来:


```python
order.columnsIndex(['订单编号', '买家会员名', '买家应付货款', '买家应付邮费', '总金额', '买家实际支付金额', '收货人姓名', '收货地址','联系手机', '订单创建时间', '订单付款时间 ', '宝贝标题 ', '宝贝种类', '物流单号 ', '物流公司', '宝贝总数量','退款金额'],dtype='object')order=order[["订单编号","买家会员名","买家实际支付金额","收货地址","宝贝标题 ","宝贝种类","宝贝总数量","退款金额"]]
order.shape
(3989, 8)

分类型变量编码

退款金额0-1编码(由于’退款金额’字段严重偏态,需做简单的分箱)

order.退款金额=np.where(order.退款金额>0,1,0)

收货地址独热编码

address=order.收货地址.str[:3].str.strip()
address
address=pd.get_dummies(address,prefix="地址")
address.head()

宝贝种类独热编码

kinds=pd.get_dummies(order.宝贝种类,prefix="宝贝种类")
kinds.head()

合并订单表

删除原表中已经编码完成的字段

order=order.drop(["收货地址","宝贝种类"],axis=1)
order

把编码成功之后生成表(address,kinds)和order合并:

order=pd.concat([order,address,kinds],axis=1)
order.head()

订单详情表

导入数据

order_detail=pd.read_csv(r"D电商玩具店营销案例\data\Items_order.csv")
order_detail.head()

删除无关字段

order_detail=order_detail.dropna(axis=1,thresh=order_detail.shape[0]*0.2)
order_detail.head()
for  i in order_detail.columns:if order_detail[i].nunique()==1:del order_detail[i]order_detail.shape

选择对表有用的字段,且与用户购买行为有关的字段

order_detail=order_detail[["订单编号","标题","价格","购买数量","订单状态"]]
order_detail.head()

筛选交易成功的记录

order_detail=order_detail[order_detail.订单状态=="交易成功"]
order_detail.head()
order_detail=order_detail.reset_index(drop=True).iloc[:,:-1]
order_detail.head()

商品详情表

导入数据

items_detail=pd.read_csv(r"D:\电商玩具店营销案例\data\Items_attribute.csv")
items_detail.head()
items_detail.isnull().sum()  - 查看缺失值
items_detail.玩具类型.value_counts()  - 发现“玩具类型”字段有价值的信息极少,不能体现用户购买行为的特征,字段删除
items_detail.适用年龄.value_counts().index  - 年龄字段过于混杂,需要将字段拆分处理

年龄字段处理

items_detail.适用年龄
0                                   3岁,4岁,5岁,6岁
1                                   3岁,4岁,5岁,6岁
2              3岁,4岁,5岁,6岁,7岁,8岁,9岁,10岁,11岁,12岁
3      3岁,4岁,5岁,6岁,7岁,8岁,9岁,10岁,11岁,12岁,13岁,14岁
4                                         3岁,4岁items_detail.适用年龄=items_detail.适用年龄.fillna(items_detail.适用年龄.mode()[0]) - 填充缺失值

对出现的所有年龄小标签进行人工分组

“婴儿”:一岁以内:3个月,6个月,12个月
“幼儿”:1岁到3岁:18个月,2岁,3岁
“学前”:3岁到7岁:4岁,5岁,6岁
“学生”:7岁以上:7岁,8岁,9岁,10岁,11岁,12岁,13岁,14岁,14岁以上
封装函数:

def change(x):a=x.split(",")                 # 将字符串切割“3岁,4岁,5岁,6岁”--->['3岁','4岁','5岁','6岁']st=""                          # 空字符串用来装载新的年龄标签,比如“幼儿”、“学前”...for i in a:                    #  把a看成['3岁','4岁','5岁','6岁']if i in baby:                    # 每次遍历出来一个旧年龄标签,都判断一下这个年龄标签属于哪个新类别,下面for循环代码体就是不断地判断旧年龄标签if st.find("婴儿")!=-1:continue                    # 跳过for循环该次遍历st=st+"婴儿|"elif i in youer:if st.find("幼儿")!=-1:         # 第一次遍历"3岁",此时st还是空列表,因此第一次循环不会执行continuecontinue                    # 执行continue的前提是此次for遍历,str字符串中已经"幼儿"两个字st=st+"幼儿|"                   # 第一次遍历"3岁",str从空字符串变成"幼儿|"elif i in xueqian:if st.find("学前")!=-1:continuest=st+"学前|"           else:if st.find("学生")!=-1:continuest=st+"学生|"    return stage=items_detail.适用年龄.apply(change)
age0         幼儿|学前|
1         幼儿|学前|
2      幼儿|学前|学生|
3      幼儿|学前|学生|
4         幼儿|学前|...
283    幼儿|学前|学生|
284    幼儿|学前|学生|
285       婴儿|幼儿|

品牌字段独热编码处理

brand=pd.get_dummies(items_detail.品牌,prefix="品牌")
brand.head()

商品详情表合并

items_detail=pd.concat([items_detail.iloc[:,:3],age,brand],axis=1)
items_detail.head()

表合并

第一次表合并:尽可能的保留客户的购买行为信息

  • table_01是由item_detail表和order_detail合并的
  • table_01表中记录了用户在所用订单中购买的所有商品的详细信息(19877个记录)
  • order表记录了用户所有订单的订单信息(3989)
table_01=pd.merge(order_detail,items_detail,how="inner",on="标题")
table_01.head()

第二次表合并:

table_02=pd.merge(table_01,order,how="left",on="订单编号")
table_02.head()

构建用户行为表

  • 把table_02转化为一行记录一个用户所有购买行为的信息表。–>要经历按照用户名来groupby的过程。
  • 由于table_02每一行记录是代表某一笔订单中某一类商品的购买信息,大多数字段根据将table_02按照买家会员名进行分组求和,
  • 但是某些字段不能直接求和,比如“买家实际支付金额”在同一订单中不同类型的商品信息会重复出现,直接按照买家会员名进行分组求和会重复计算
table_02=table_02.drop_duplicates()
table_02[table_02.订单编号==24043728806509300][["订单编号","宝贝总数量","宝贝ID","标题"]]

剔除合并表中与用户购买行为无关的字段

table_03=table_02.drop(["订单编号","标题","宝贝ID","宝贝标题 ","价格_x","价格_y"],axis=1)
table_03.head()

对以上的字段以外的分组求和

table_04=table_03.drop(["买家实际支付金额","宝贝总数量"],axis=1)
table_04.head()
order_tag_01=table_04.groupby("买家会员名").sum()
order_tag_01.head()
  • 买家实际支付金额:来源order表,记录一笔订单实际支付金额
  • 宝贝总数量:来源order表,记录一笔订单宝贝总数量
  • 以上需要分组求均值。
table_05=table_02[["订单编号","买家会员名","买家实际支付金额","宝贝总数量"]]
table_05.head()
  • 如何使用“买家实际支付金额”体现买家每一笔订单的平均支付能力?—>不要再使用table_02表了,因为:

    • table_02中的一行记录的是不同订单中不同款产品数据
    • 而table_02中的“买家实际支付金额”,“宝贝总数量”字段却是记录的是每一个订单的总金额和总数量
    • 使用原表order来统计不同买家每笔订单的平均实际支付金额与平均购买宝贝数量
    • 只要生成的字段能够体现每个买家的购买力和购买数即可
order_tag_02=order.groupby("买家会员名")[["买家实际支付金额","宝贝总数量"]].mean()
order_tag_02
order_tag_all=pd.merge(order_tag_01,order_tag_02,how="inner",on="买家会员名")
order_tag_all=order_tag_all.set_index("买家会员名")
order_tag_all.head()order_tag_all.isnull().sum()[order_tag_all.isnull().sum()!=0] - 观察由于缺失值

归一化

from sklearn.preprocessing import MinMaxScalermms=MinMaxScaler()
data_norm=mms.fit_transform(order_tag_all.values)
data_norm

K-Means聚类

确定k值方法:

  • 业务经验;
  • 手肘法+轮廓系数

手肘法

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
sse=[]
for k in range(1,25):km=KMeans(n_clusters=k)km.fit(data_norm)sse.append(km.inertia_)
sseplt.plot(range(1,25),sse,marker="o")   - 轮廓系数1400,过大

删除一些不是特别重要的特征:‘宝贝种类’,‘地址’,‘品牌’

a=[]  # 空列表用来存储可能对聚类没太大作用特征for i in order_tag_all.columns:if i.find("宝贝种类")!=-1 or i.find("地址")!=-1 or i.find("品牌")!=-1 :a.append(i)
order_tag_all.drop(a,axis=1,inplace=True)

重新归一化,重新拟合模型

# 重新再做归一化
from sklearn.preprocessing import MinMaxScaler
mms=MinMaxScaler()
data_norm=mms.fit_transform(order_tag_all.values)# 重新拟合模型
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
sse=[]
for k in range(1,25):km=KMeans(n_clusters=k)km.fit(data_norm)sse.append(km.inertia_)plt.plot(range(1,25),sse,marker="o")

轮廓系数图

from sklearn.metrics import silhouette_score
score=[]
for k in range(2,25):km=KMeans(n_clusters=k)res_km=km.fit(data_norm)score.append(silhouette_score(data_norm,res_km.labels_))plt.plot(range(2,25),score,marker="o")

发现k=5是误差平均和极小值点,轮廓系数在极大值位置

重新建模

km=KMeans(n_clusters=5)
km.fit(data_norm)clusters=km.labels_
clustersorder_tag_all["类别"]=clusters
order_tag_all.head()result=order_tag_all["类别"]
result

构建推荐系统

基于聚类的精准推荐总体

  • 先基于聚类:把用户分群,对每一个客户都标记上标签值。
  • 推荐规则生成:
    – 推荐个客户的商品,都是ta没买过的
    – 在ta没有购买过的商品中,哪些是和ta同类客户最喜欢的?
    ---- 同类客户总购买次数(平均购买次数)最多的商品,就是这类客户最喜欢的商品
    ---- 同类客户总购买数量(平均购买数量)最多的商品,就是这类客户最喜欢的商品

用户-商品-购买次数表

  • 想要提取所有用户对所有商品的购买次数信息,需要从order表和order_detail中提取对应的记录:
user_itmes=pd.merge(order_detail,order,how="left",on="订单编号")
user_itmes.head()
user_itmes=user_itmes[["买家会员名","标题"]]
user_itmes
user_itmes["购买次数"]=1
user_itmes
  • 我们需要知道所有会员对所有商品的购买总次数,所以被透视的字段“购买次数”:
user_itmes=user_itmes.pivot_table("购买次数","买家会员名","标题",aggfunc=np.sum).fillna(0)
user_itmes.head()user_itmes=user_itmes.stack().reset_index()
user_itmes.rename(columns={0:"购买次数"},inplace=True)
user_itmesaa=pd.DataFrame([[1,2,3],[1,2,3]],index=["第一行","第二行"],columns=["第一列","第二列","第三列"])
aapd.DataFrame(aa.stack())

用户-未购买商品表

user_item_notbuy=user_itmes[user_itmes.购买次数==0.0]
user_item_notbuy.head()

用户-未购买商品-类别表

clusters=pd.DataFrame(result).reset_index()
clustersuser_itme_notbuy_clu=pd.merge(user_item_notbuy,clusters,how="left",on="买家会员名")
user_itme_notbuy_clu.drop("购买次数",axis=1,inplace=True)user_itme_notbuy_clu=user_itme_notbuy_clu.dropna()
user_itme_notbuy_clu

类别-商品-购买次数表

cluster_item_num=pd.merge(user_itmes,clusters,how="left",on="买家会员名").iloc[:,1:]
cluster_item_num.head()cluster_item_num=cluster_item_num.groupby(["类别","标题"]).sum().reset_index()
cluster_item_num.head()

最终推荐表

user_notbuy_fre=pd.merge(user_itme_notbuy_clu,cluster_item_num,how="left",on=["类别","标题"])
user_notbuy_fre.head()def change(x):  # x看做每个小子表,小子表是DataFrame对象recom=x.sort_values("购买次数",ascending=False)[:5]   # 将每一个小子表按照“购买次数”字段降序,然后返回前5行记录return recom  recom=user_notbuy_fre.groupby("买家会员名").apply(change).reset_index(drop=True)
recom.head()

基于聚类的个性化推荐相关推荐

  1. 基于机器学习的个性化推荐算法的研究

    基于 机器学习 的个性化推荐算法的研究 摘要: 如今互联网发展 十分迅速,每天产生的数据量一直在增加,传统的搜索引擎已经不能够适用当前的需求,推荐系统已经成为互联网时代的新宠儿.它已经发展成为一门跨学 ...

  2. 在加权异构图上的基于元路径个性化推荐——SemRec

    主要参考论文:<Semantic Path based Personalized Recommendation on Weighted Heterogeneous Information Net ...

  3. 基于SpringBoot的个性化推荐的图书借阅管理系统前后台设计

    目录 1 需求分析 1 2技术栈 1 3 总体设计 1 3.1 系统功能概述 1 3.1.1 前台系统 1 3.1.2 后台系统 2 3.2 E-R模型 2 3.3 系统流程图 4 4 详细设计 5 ...

  4. 基于内容的推荐算法的php实现,基于内容的个性化推荐算法

    摘要:个性化推荐算法有许多类别,主要包括基于内容的推荐.协同过滤.SVD.基于知识的推荐以及混合推荐算法.本文介绍基于内容的推荐算法(Content-basedRecommendation).基于内容 ...

  5. 基于内容的个性化推荐算法

    一.什么是推荐算法 随着移动互联网的高速发展与智能手机的普及,海量的有用信息虽然为人们提供了更多的价值,然而信息的泛滥也意味着为了寻找合适的信息必须付出更多的时间成本.事实上,有时候仅仅是浏览和简单的 ...

  6. springboot基于java的个性化推荐的电商购物商城平台设计与实现

    本文主要探讨了个性化推荐的电商平台的设计与实现.并对其详细的设计方案.实现技术和运行情况做了分析和研究,最后对未来的工作做了研究与探讨.本文重点研究了以下几个方面: (1)系统的体系结构.主要功能模块 ...

  7. android个性化推荐选择页面,基于Android的菜谱个性化推荐系统的设计与开发

    汪丽娟+钱育蓉 摘要:据调查,当今社会中,有不少人存在"选择吃什么"的困难症,为解决这一问题,文章设计了一种菜谱个性化推荐系统.该系统分为客户端和服务端,服务端进行系统的推荐计算, ...

  8. 计算机配件推荐系统论文摘要,个性化推荐系统设计

    内容简介: 个性化推荐系统设计,毕业设计,共65页,29540字,附外文翻译. 摘要 个性化推荐系统根据用户的历史数据,利用推荐算法向他们推荐可能感兴趣的商品.协同过滤(CF)是目前研究最多.应用最广 ...

  9. 读懂你性格的个性化推荐

    作者 | 谢幸.张富峥 编者按:互联网的迅猛发展为信息量的惊人膨胀提供了肥沃的土壤.丰富的信息资源给用户提供更多选择的同时,信息的泛滥也意味着用户必须为信息筛选付出更大的成本. 应运而生的个性化推荐技 ...

最新文章

  1. oracle自增列问题i,关于oracle中自增列问题
  2. Nature发文:深度学习系统为什么这么好骗?
  3. MCS-51系列特殊功能寄存器(摘抄)
  4. 十九、前端必学Bootstrap美化(下篇)
  5. 【springboot】静态资源设置缓存时间
  6. throwable_您想了解的所有Throwable
  7. java命令添加classpath_java和javac命令的classpath用法
  8. 去掉左边0_TiDB 4.0 在 VIPKID 的应用实践
  9. Xposed 之旅 -- 微信防撤回
  10. 计算机无法安装dx11,Windows10系统DX11正确的安装路径是什么?
  11. matlab机器学习之knn算法实例
  12. ogg格式怎样才能转换成mp3
  13. 2022自动驾驶竞赛WAD介绍 CVPR 2022 Workshop on Autonomous Driving
  14. Android 支付宝支付SDK接入
  15. 上海学车科目二,科目三容易扣分点分享,你了解多少
  16. 加强【圣域2】各个技能的打击感-华丽的击飞效果
  17. python中的大数据品牌运营策划营销_大数据时代的品牌营销
  18. android编辑框禁用emoji表情和颜文字
  19. java实现红包要多少钱_2020情人节红包数字寓意 214情人节给女朋友发多少钱红包合适...
  20. host速度 mtk usb_mtk-usb代码分析之枚举过程

热门文章

  1. 微服务远程调用的用法
  2. 信号采样中,频率分辨率的定义
  3. 百度手机卫士精准定位伪基站
  4. TCP面试常见题:time_wait状态产生的原因,危害,如何避免
  5. 阿Q:被恶心的虫子咬了
  6. C#语言实例源码系列-实现图片合成功能
  7. point 如何求elbow_如何选择kmeans中的k值——肘部法则–Elbow Method和轮廓系数–Silhouette...
  8. layui 鼠标移动到单元格显示tips(layer.tips)
  9. 什么是无线AP,无线AP和无线路由器之间有什么区别
  10. add函数 pytorch_Pytorch的高级训练,数据增强和实用程序 - pytorch中文网