概述
推荐系统一般除了会返回推荐的结果 id 列表以外,还会返回一些辅助参数,例如算法 id,也可以称为推荐的 rdna(recommended dna),可以用于描述该推荐结果的「来龙去脉」。比如说,推荐流程经过了召回、混排和排序三个阶段,而每个阶段都可能会有 ab 实验,为了标识所属阶段和实验,都会给实验分配一个 id,用于追踪推荐的完整过程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
{
"status": true,
"result": [
{
"rdna": 1150982,
"itemId": "69",
"itemType": "Item",
"debug": {
"rtime": 1544502577084
}
},
{
"rdna": 1150982,
"itemId": "0",
"itemType": "Item",
"debug": {
"rtime": 1544502577084
}
},
{
"rdna": 1150982,
"itemId": "88",
"itemType": "Item",
"debug": {
"rtime": 1544502577084
}
}
]
}
|
传入相应的三个参数,可以返回一个 Long 类型的 rdna 值,而在分析过程中,也可以通过返回值的 rdna 解析出 recallId,mixId 和 rerankId,以此来区分业务。rdna 的实现其实很简单,主要运用了位运算。也可以用 python 或者其他语言来实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 该样例类的参数为召回 id,混排 id 和 重排 id,并且都是在0到1023间的整数
case class DNA(recallId: Int, mixId: Int, rerankId: Int) {
require(recallId < 1024, s"Invalid recall id: [ $recallId ] > 1024 or < 0.")
require(mixId < 1024, s"Invalid mix id: [ $mixId ] > 1024 or < 0.")
require(rerankId < 1024, s"Invalid rerank id: [ $rerankId ] > 1024 or < 0.")
def dnaToLong: Long = {
recallId.toLong + (mixId << 10).toLong + (rerankId << 20).toLong
}
}
# 该对象通过传入一个 dna 数值,分别取得召回 id,混排 id 和 重排 id
object DNA {
def apply(dnaCode: Long): DNA = {
val rc = dnaCode & 1023
val m = dnaCode >> 10 & 1023
val rr = dnaCode >> 20 & 1023
new DNA(rc.toInt, m.toInt, rr.toInt)
}
}
|
算法ID如何转rdna
考虑一个召回,混排,精排的组合为(6, 0, 7),如何转换成为 rdna。
1
2
3
4
5
6
7
8
9
10
11
|
# 首先计算 recallId
recallId.toLong = 6
# 然后计算 mixId
(mixId << 10).toLong = 0
# 最后计算 rerankId
(rerankId << 20).toLong = 7340032
# 最后的 rdna 是通过将以上三部分的结果相加得到的
rdna = 6 + 0 + 7340032 = 7340038
|
rnda如何转算法id
根据 rdna 获得召回,混排,精排的组合。仍然使用实例1的数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 以下是解析 rdna 为7340038的过程
# 十进制化为二进制
7340038 => 100 0110 0000 0000 0000 0000 1000
recallId = dnaCode & 1023
= 7340038 & 1023
= 100 0110 0000 0000 0000 0000 1000 & 11 1111 1111
= 6
mixId = dnaCode >> 10 & 1023
= 7340038 >> 10 & 1023
= 7168 & 1023
= 0
rerankId = dnaCode >> 20 & 1023
= 7340038 >> 20 & 1023
= 7 & 1023
= 7
|
解析点击、行为日志的时候,可以通过注册 Hive 的 UDF 函数来解析不同的推荐业务的 rdna,从而实现报表的开发。
脚本解析
提供一个样例脚本,用于在 shell 模式下方便解析,其实就是一个关于位运算的 shell 脚本。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#!/bin/bash
function longtordna() {
RECALL=$1
MIX=$2
RERANK=$3
RDNA=$((RECALL + (MIX << 10) + (RERANK << 20)))
echo "Input racall: $RECALL, mix: $MIX and rerank $RERANK, convert to rdna: $RDNA."
}
function rdnatolong() {
RDNA=$1
echo "Input rdna: $RDNA to convert to recall: $((RDNA & 1023)), mix: $((RDNA >> 10 & 1023)) and rerank: $((RDNA >> 20 & 1023))."
}
function usage() {
cat << EOF
Usage: ./rdna.sh longtordna recallId mixId rerankId
./rdna.sh rdnatolong rdna
./rdna.sh help
EOF
}
case "$1:$2:$3" in
longtordna:*)
longtordna "${@:2}"
;;
rdnatolong:*)
rdnatolong $2
;;
h|help)
usage
;;
*)
usage
exit 0
esac
|
总结
实际上 rdna 的设计、叫法这些都不重要,重要的是理解一种思想,就是通过你的推荐系统推荐出来的东西,可以通过一定的工具,来排查推荐的来龙去脉,这在实际的业务运营上是很重要的,假设有天用户反馈推荐的内容并不感兴趣,通过这些工具,我们可以清晰的找到推荐的逻辑,这样可以为以后的优化提供非常重要的依据,至于怎么做,或者是否做成可视化、血缘关系之类的,就看开发的能力和时间了。
警告
本文最后更新于 2017年5月9日,文中内容可能已过时,请谨慎参考。