本文是对七月在线关于用户画像构建与协同过滤的一个随堂笔记。用户画像部分主要围绕用户画像的核心-文本挖掘、需要哪些用户画像信息、怎么构建这些基本用户画像信息以及倒排索引的案例简单描述展开,协同过滤部分主要是实训内容,需要消化基于用户和基于item的协同过滤改进算法实现。
目录
推荐系统中最核心的数据之一是 user profile 数据。需要从大量用户历史行为中分析和挖掘各种维度的特征,来刻画用户的兴趣偏好。
需要怎么的用户画像?
• 人口学
• 性别、年龄、地域etc
• 内容特征(标签):类别category、主题topic、关键字keyword、实体词entity(属于keyword里更具代表性更细的名词)
• 喜欢、不喜欢
• 长期、短期
• 协同特征 (主要通过协同过滤算法来找到)
相似用户
用户画像如何构建
用户人口学属性:
性别/年龄:(推测依据)
账号注册
人工标注数据+规则+ 模型
用户app安装列表/用户行为
手机品牌
地域:
GPS定位
主要是kaggle的一个用户画像例子。
用户画像: 核心是做文本挖掘
• 信息检索
• 文本分类
• 关键词提取
• 文本主题模型
信息检索中的案例:
倒排索引(可以用作召回)
建倒排索引的步骤:
todo 倒排索引的代码参考: https://github.com/matteobertozzi/blog-code/blob/master/py-inverted-index/invindex.py
TF-IDF:
词项频率Tf、 文档频率df ,逆文档频率 idf 。根据tf-idf 的排序。
关键词keywords提取 的做法
• 基于统计特征的关键词提取算法
• 核心:利用文档中词语的统计信息抽取文档的关键词
• 步骤
• 文本经过预处理得到候选词语的集合
• 采用特征值量化的方式从候选集合中得到关键词
• 关键是采用什么样的特征值量化指标的方式
• 特征值量化指标
• 基于词权重的特征量化
• 基于词权重的特征量化主要包括词性、词频、逆向文档频率、相对词频、词长等。
• 基于词的文档位置的特征量化
• 根据文章不同位置的句子对文档的重要性不同的假设来进行的。
• 文章的前N个词、后N个词、段首、段尾、标题、引言等位置的词具有代表性,这些词作为关键词可以表达整个的主题
• 基于词的关联信息的特征量化
• 词的关联信息是指词与词、词与文档的关联程度信息,包括互信息、hits值、贡献度、依存度、TF-IDF值等。
文本主题模型 :
算法LDA,简单介绍了下。感觉这个也不是推荐的重点,如果学NLP需要侧重了解。
用户画像中的权重计算:
对应关键字等的权重是如何计算的
简述: • 记录用户曝光点击历史 • 提取文章相关标签• 曝光且点击加权• 曝光不惦记降权 热门降权• 按照时间衰减 • 归一化
最基本的TF-IDF算法的权重归类
模型召回只是一种召回类别。
时间衰减 (权重需要随着时间进行衰减或增大)
• 牛顿冷却定律数学模型
• w(P , T)表示一个标签T被用于标记用户P的次数
• 不同时间的w(P,T)可以做时间衰减
• 如: 指定45分钟后物体温度为初始温度的0.5,即0.5=1×exp(-a×45),求得α=0.1556。
用户标签:需要考虑多维度多层次
• 用户长期/短期行为
• 需要分开计算
• 短期行为多采用实时架构
• 用户精确兴趣/泛化兴趣
• 精确兴趣通过点击行为得到
• 泛化兴趣通过精确兴趣+近似算法扩充
其他: 人口学预测:
talkingData的案例 ,根据数据来预测。
看各种数据 data 目录下。 代码直接运行kaggle上别人的代码的,注意sklearn 版本的可能需要更改远程运行的数据目录可能有点点变化,注意用魔术命令查看当前路径和上下环境路径。
协同过滤:
todo 待总结概括成文字
基于改进的物品余弦相似度的推荐
def UserIIF(train, K, N):
'''
:params: train, 训练数据集
:params: K, 超参数,设置取TopK相似用户数目
:params: N, 超参数,设置取TopN推荐物品数目
:return: GetRecommendation, 推荐接口函数
'''
# 计算item->user的倒排索引
item_users = {}
for user in train:
for item in train[user]:
if item not in item_users:
item_users[item] = []
item_users[item].append(user)
# 计算用户相似度矩阵
# todo 这块的实现需要在详细看下
# 本身算法的理解参考: https://zhuanlan.zhihu.com/p/83409812 这个有给值
#https://blog.csdn.net/xpsallwell/article/details/86227676
sim = {}
num = {}
for item in item_users:
users = item_users[item]
for i in range(len(users)):
u = users[i]
if u not in num:
num[u] = 0
num[u] += 1
if u not in sim:
sim[u] = {}
for j in range(len(users)):
if j == i: continue #
v = users[j]
if v not in sim[u]:
sim[u][v] = 0
# 相比UserCF,主要是改进了这里
sim[u][v] += 1 / math.log(1 + len(users))
for u in sim:
for v in sim[u]:
sim[u][v] /= math.sqrt(num[u] * num[v])
# 按照相似度排序
sorted_user_sim = {k: list(sorted(v.items(), \
key=lambda x: x[1], reverse=True)) \
for k, v in sim.items()}
# 获取接口函数
def GetRecommendation(user):
items = {}
seen_items = set(train[user])
for u, _ in sorted_user_sim[user][:K]:
for item in train[u]:
# 要去掉用户见过的
if item not in seen_items:
if item not in items:
items[item] = 0
items[item] += sim[user][u]
recs = list(sorted(items.items(), key=lambda x: x[1], reverse=True))[:N]
return recs
return GetRecommendation
鸣谢:
七月在线官方课程
https://github.com/matteobertozzi/blog-code/blob/master/py-inverted-index/invindex.py