该文档涉及的组件

swing训练 (SwingTrainBatchOp)

Java 类名:com.alibaba.alink.operator.batch.recommendation.SwingTrainBatchOp

Python 类名:SwingTrainBatchOp

功能介绍

Swing 是一种被广泛使用的item召回算法,输入数据只包含user和item即可,使用简单。

Swing算法原理比较简单,是阿里最早使用到的一种召回算法,在阿里多个业务被验证过非常有效的一种召回方式。 它认为 user-item-user 的结构比 itemCF 的单边结构更稳定。

Swing指的是秋千,例如用户u和用户v,都购买过同一件商品i,则三者之间会构成一个类似秋千的关系图。
若用户u和用户v之间除了购买过i外,还购买过商品j,则认为两件商品是具有某种程度上的相似的。
也就是说,商品与商品之间的相似关系,是通过用户关系来传递的。为了衡量物品i和j的相似性,考察都购买了物品i和j的用户u和用户v,
如果这两个用户共同购买的物品越少,则物品i和j的相似性越高。

Swing算法的表达式如下:

用户权重 w_u = 1 / (user_click_num + userAlpha) ^ userBeta

score(item_i, item_j) = sum(wu * wv / (alpha + common_items(wu, wv)))

其中userAlpha、userBeta和alpha,用户可以根据自己的数据情况设置。

此外,可以通过设置maxUserItems和minUserItems,过滤掉关联item太多或者太少的用户信息。
对于出现次数过多的item,设置maxItemNumber参数,当出现次数大于maxItemNumber时,算法从所有的user中随机抽取maxItemNumber个用户,计算结果,因此该算法两次执行的结果不一定相同。

在电商场景中,user和item的关系可以为点击、购买、收藏等。在Feed流场景关系可以为点击、点赞、评论、收藏等,item可以为文章、博主、话题等。

参数说明

名称 中文名称 描述 类型 是否必须? 取值范围 默认值
itemCol Item列列名 Item列列名 String
userCol User列列名 User列列名 String
alpha alpha参数 alpha参数,默认1.0 Float 1.0
maxItemNumber item参与计算的人数最大值 如果item出现次数大于该次数,会随机选择该次数的用户数据,默认1000 Integer 1000
maxUserItems 用户互动的最大Item数量 如果用户互动Item数量大于该次数,该用户数据不参与计算过程,默认1000 Integer 1000
minUserItems 用户互动的最小Item数量 如果用户互动Item数量小于该次数,该用户数据不参与计算过程,默认10 Integer 10
resultNormalize 结果是否归一化 是否归一化,默认False Boolean false
userAlpha 用户alpha参数 用户alpha参数,默认5.0, user weight = 1.0/(userAlpha + userClickCount)^userBeta Float 5.0
userBeta 用户beta参数 用户beta参数,默认-0.35, user weight = 1.0/(userAlpha + userClickCount)^userBeta Float -0.35

代码示例

Python 代码

from pyalink.alink import *

import pandas as pd

useLocalEnv(1)

df_data = pd.DataFrame([
    ["a1", "11L", 2.2],
    ["a1", "12L", 2.0],
    ["a2", "11L", 2.0],
    ["a2", "12L", 2.0],
    ["a3", "12L", 2.0],
    ["a3", "13L", 2.0],
    ["a4", "13L", 2.0],
    ["a4", "14L", 2.0],
    ["a5", "14L", 2.0],
    ["a5", "15L", 2.0],
    ["a6", "15L", 2.0],
    ["a6", "16L", 2.0],
])

data = BatchOperator.fromDataframe(df_data, schemaStr='user string, item string, rating double')


model = SwingTrainBatchOp()\
    .setUserCol("user")\
    .setItemCol("item")\
    .setMinUserItems(1)\
    .linkFrom(data)

model.print()

predictor = SwingRecommBatchOp()\
    .setItemCol("item")\
    .setRecommCol("prediction_result")

predictor.linkFrom(model, data).print()

Java 代码

import org.apache.flink.types.Row;

import com.alibaba.alink.operator.batch.BatchOperator;
import com.alibaba.alink.operator.batch.recommendation.SwingRecommBatchOp;
import com.alibaba.alink.operator.batch.recommendation.SwingTrainBatchOp;
import com.alibaba.alink.operator.batch.source.MemSourceBatchOp;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public class SwingTrainBatchOpTest {
	@Test
	public void testSwingTrainBatchOp() throws Exception {
		List <Row> df_data = Arrays.asList(
			Row.of("a1", "11L", 2.2),
			Row.of("a1", "12L", 2.0),
			Row.of("a2", "11L", 2.0),
			Row.of("a2", "12L", 2.0),
			Row.of("a3", "12L", 2.0),
			Row.of("a3", "13L", 2.0),
			Row.of("a4", "13L", 2.0),
			Row.of("a4", "14L", 2.0),
			Row.of("a5", "14L", 2.0),
			Row.of("a5", "15L", 2.0),
			Row.of("a6", "15L", 2.0),
			Row.of("a6", "16L", 2.0)
		);
		BatchOperator <?> data = new MemSourceBatchOp(df_data, "user string, item string, rating double");
		BatchOperator <?> model = new SwingTrainBatchOp()
			.setUserCol("user")
			.setItemCol("item")
            .setMinUserItems(1)
			.linkFrom(data);
		model.print();
		BatchOperator <?> predictor = new SwingRecommBatchOp()
			.setItemCol("item")
			.setRecommCol("prediction_result");
		predictor.linkFrom(model, data).print();
	}
}

运行结果

mainItems recommItemAndSimilarity
11L {“object”:[“12L”],“score”:[1.3015095],“itemCol”:“item”}
14L {“object”:[],“score”:[],“itemCol”:“item”}
16L {“object”:[],“score”:[],“itemCol”:“item”}
15L {“object”:[],“score”:[],“itemCol”:“item”}
13L {“object”:[],“score”:[],“itemCol”:“item”}
12L {“object”:[“11L”],“score”:[1.3015095],“itemCol”:“item”}
user item rating prediction_result
a1 11L 2.2000 {“item”:“["12L"]”,“score”:“[1.3015094995498657]”}
a1 12L 2.0000 {“item”:“["11L"]”,“score”:“[1.3015094995498657]”}
a2 11L 2.0000 {“item”:“["12L"]”,“score”:“[1.3015094995498657]”}
a2 12L 2.0000 {“item”:“["11L"]”,“score”:“[1.3015094995498657]”}
a3 12L 2.0000 {“item”:“["11L"]”,“score”:“[1.3015094995498657]”}
a3 13L 2.0000 {“item”:“[]”,“score”:“[]”}
a4 13L 2.0000 {“item”:“[]”,“score”:“[]”}
a4 14L 2.0000 {“item”:“[]”,“score”:“[]”}
a5 14L 2.0000 {“item”:“[]”,“score”:“[]”}
a5 15L 2.0000 {“item”:“[]”,“score”:“[]”}
a6 15L 2.0000 {“item”:“[]”,“score”:“[]”}
a6 16L 2.0000 {“item”:“[]”,“score”:“[]”}