最近做的项目中有跟商品推广营销相关的,期望在中秋国庆期间,借助市场的天时地利(规律),在平台上挖掘出一波用户来创造一波营销和创收。项目周期大约3个月左右,从8月-10月。
这样的项目属于人货匹配模型中典型的有货找人的情况,一般都有比较固定的算法模型,给出多条人群策略,做赛马实验即可。比如人对货的意向预测模型(即CTR/CVR类的模型),又或者使用推荐算法里的模型(如I2I2U、或者I2U2U模型),或者根据产品和用户的显著性分析做一些规则类的标签组合。
在我们这个项目里,因为客户的产品是定制化的针对收藏爱好、商务送礼需求的人群的产品,通过实际数据表现发现CTR/CVR模型转化一般。大家在观察和分析了用户购买行为后才发现,这些商品更适合的是SMB用户,因为他们有送礼/商务宴请需求,所以定下了一个针对B用户的挖掘方案。然后对于那些爱好喝酒的C用户,几轮赛马策略下来,I2I2U的高相关算法明显胜出。这个算法是利用用户的购买、加购行为序列,使用FastText模型做训练,找出目标商品高相关的item,然后找的目标人群进行营销,即典型的I2I2U算法。
实现步骤:
1、类目商品信息整理
对商品类目下的所有商品进行属性数据整理和预处理,获得结构化的数据,比如商品所属的多级分类、品牌、进口/国产、价格区间、包装形式(礼盒/整箱)、量级、口味、度数、适用场景(收藏/自饮/送礼宴请/婚宴/聚会)等。
这一步商品信息整理的目的是做粗筛召回使用,即根据客户的目标商品属性,从上千万条的商品信息中粗召回上百万的候选商品。
这里的数据处理并没有特别大的技术难点,主要是要花时间和精力在数据清洗和对齐上,比较繁琐。比如将不同描述的商品适用场景做归类, 像这样:
case when a.scene in ('自饮','自斟自饮','自饮自酌','居家自饮') then '自饮'
when a.scene in ('送礼/礼品','送礼礼品','宴请','礼节拜访','商务宴请','亲友馈赠') then '送礼宴请'
when a.scene in ('喜宴','婚宴','婚礼婚宴','婚宴喜宴','婚宴用') then '婚宴'
when a.scene in ('收藏/摆件','收藏','收藏投资') then '收藏'
when a.scene in ('派对','派对必备','派对活动','轰趴推荐','酒吧夜店','调酒必备','百搭调配') then '派对'
when a.scene in ('朋友小聚','闺蜜之夜','闺蜜私语','聚会','家庭聚会','野餐出游','情侣约会','约会','纪念日') then '聚会'
else '未知' end as scene
或者对于商品量级做统一处理,或者统一描述的不规范造成的差异,
case when a.package in ('箱装','整箱','整箱装') or a.package_unit in ('箱装','整箱','整箱装') or a.package_type in ('箱装','整箱','整箱装') or a.package_quatity in ('箱装','整箱','整箱装') then '整箱装'
when a.package in ('礼盒','礼盒装','套装','组合套装','组合装') or a.package_unit in ('礼盒','礼盒装','套装','组合套装','组合装') or a.package_type in ('礼盒','礼盒装','套装','组合套装','组合装')or a.package_quatity in ('礼盒','礼盒装','套装','组合套装','组合装') then '礼盒装'
when a.package in ('双支','双支装') or a.package_unit in ('双支','双支装') or a.package_type in ('双支','双支装') or a.package_quatity in ('双支','双支装') then '双支装'
else '未知'
end as package_type
虽然这一步的数据清洗很枯燥和浪费时间,但它对于CTR/CVR模型的商品特征输入是有用的,对于商品的粗筛召回也是关键的。
2、构造用户对候选集商品的行为序列
可以是同购行为序列、同浏览行为序列、或者同加购行为序列,根据你对召回人群精准度的需求来选择。这里拿同构行为序列来举例。
---获取序列
create table
dmb_dev.dmb_dev_user_order_white_alcholo_item_sku_seeds_sequence as select
user_acct,b.sale_ord_id,b.item_sku_id,a.main_sku_id,a.sku_name,b.item_name,a.shop_id,b.sale_ord_tm
from
(select * from dmb_dev.dmb_dev_alchole_items_attribute_a where favor3 in ('香型1', '香型2') and price>=280 and price<=200000) a
join
dmb_rpt.dmb_dmbrpt_all_mall_order_detail_s_det_d b
on a.item_sku_id = b.item_sku_id
where b.dt='{DATE}' and amount_pay >200
group by user_acct,b.sale_ord_id,b.item_sku_id,a.main_sku_id,a.sku_name,b.item_name,a.shop_id,b.sale_ord_tm;
---聚合
CREATE TABLE dmb_dev.dmb_dev_user_order_white_alcholo_item_sku_seeds_sequence_collect as select
user_acct, concat_ws(',',collect_list(seq_sku_id)) as hist_sku_seq, concat_ws(',',collect_list(seq_sku_name)) as hist_item_seq
from
(select user_acct, item_sku_id as seq_sku_id,item_name as seq_sku_name ,sale_ord_tm
from dmb_dev.dmb_dev_user_order_white_alcholo_item_sku_seeds_sequence
distribute by user_acct sort by sale_ord_tm) a
group by user_acct
3、训练fasttext模型
# 1-准备数据: 大规模的语料库文件。 这里大约150W条训练样本
corpus_file = 'large_corpus_sku_name_for_train.txt'
tmp.toPandas().to_csv(corpus_file, sep=',', index=False, mode='w',header=False )
# 2-读取语料文件
from gensim.models import FastText
from gensim.test.utils import common_texts # some example sentences
# 定义一个函数来读取语料库文件
def read_corpus(file_path):
lines = []
with open(file_path, 'r', encoding='utf-8') as f:
for i, line in enumerate(f):
lines.append(line.replace('"','').strip().split(',')) # 假设每行已经分好词了,按,分割
return lines
corpus = read_corpus(corpus_file)
print(corpus[5:10] )
# 3-模型训练
model = FastText(vector_size=20, window=3, min_count=1) # instantiate
model.build_vocab(corpus_iterable=corpus)
model.train(corpus_iterable=corpus, total_examples=len(corpus), epochs=20)
# #或者
# model2 = FastText(vector_size=20, window=3, min_count=1, sentences=common_texts, epochs=10)
# 4-保存模型
model_save = "white_alchole_item_fasttext_embedding.model"
model.save(model_save)
4、模型高相关查询
# 4- 模型加载
import numpy as np
from gensim.models import FastText
from gensim.test.utils import common_texts # some example sentences
model_new = FastText.load(model_save)
# 定义一个函数来读取 商品文件
def read_target_items(file_path):
lines = []
with open(file_path, 'r', encoding='utf-8') as f:
for i, line in enumerate(f):
# print(line.replace('"','').strip().split(',')[1])
lines.append(line.replace('"','').strip().split(',')[1]) #目标商品、相关商品、score
f.close()
return list(set(lines))
# 5-白酒TopN相关商品 的 迭代查询
top_similarity_save_file = "items_top_similarity_file.txt"
# 迭代两轮
for i in np.arange(2):
print(i)
if i == 0:
# 首轮是目标商品,查询其高相关Top300 or Top500,相关系数在0.8以上的商品
ta_items = ['这里是你的营销目标商品名称或描述1', '这里是你的营销目标商品名称或描述2',]
topn = 500
else:
# 找出与目标商品次/间接相关的。 直接socre * 间接score >0.75 or 0.80
ta_items = read_target_items(top_similarity_save_file)
topn = 300
with open(top_similarity_save_file, 'a') as f1:
for ta_item in ta_items:
most_sim_res = model_new.wv.most_similar(ta_item, topn=topn)
for sim_item in most_sim_res:
item_name, score = sim_item
if score >=0.8:
f1.write('%s,%s,%f\n'%(ta_item,item_name,score))
# 写入文件
f1.close()
# 6-把商品上传到HIVE表
import pandas as pd
file1 =pd.read_csv(top_similarity_save_file, sep=',', header=None)
# 数据结构
from pyspark.sql.types import *
schema = StructType([
StructField("ta_item", StringType(), True),
StructField("sim_item", StringType(), True),
StructField("score", FloatType(), True)
])
from pyspark.sql.functions import max,expr, col
df = spark.createDataFrame(file1, schema).dropDuplicates()
df.cache()
df.show(10,False)
df.write.format("orc").mode("overwrite").saveAsTable("dmb_dev.dmb_dev_target_items_topn_similar_items")
5、找出高相关商品的兴趣用户
找出商品集的兴趣用户方法有很多,比如历史购买/加购/浏览/或者CTR/CVR意向用户等。这里示例就用历史已购代替了。
---高相关商品召回人群
select b.* from
(select ta_item as item_name from dmb_dev.dmb_dev_alchole_target_items_topn_similar_items group by ta_item
union
select sim_item as item_name from dmb_dev.dmb_dev_alchole_target_items_topn_similar_items group by sim_item) a
join
dmb_rpt.dmb_dmbrpt_all_order_detail_rect_s b
on a.item_name =b.item_name
where b.dt='{TX_DATE}'
6、投放实验和效果分析
一般会有几个不同的算法人群策略来同时赛马验证,上线后就可以根据转化效果数据来判断和分析哪个人群的算法策略更优更适合,哪个该调整和淘汰。在这三个月的项目实践验证上,高相关算法挖掘出来的人群转化效果还是很不错的,达到了运营和客户的目标转化期望和收入目标。在后来其他类似项目上迁移应用,也超出了运营们的期望目标,收获了不错的转化效果。
虽然算法不复杂,但关键就是要在项目进展中不断的发挥自己的主观能动性,积极发现问题、提出不同的解决方案,大胆上线实验,不怕犯错误。勇于尝试,勇于承担,才会有预料之外的收获。
Done