该文档涉及的组件

排序评估 (EvalRankingBatchOp)

Java 类名:com.alibaba.alink.operator.batch.evaluation.EvalRankingBatchOp

Python 类名:EvalRankingBatchOp

功能介绍

对推荐排序算法的预测结果进行效果评估。

算法原理

在排序问题中,可以忽略顺序,将问题看作多标签分类问题。这样多标签分类评估中的指标都能使用。

在考虑顺序时,假设有$M$个用户,每个用户的真实标签集合为 $D_i = \left{d_0, d_1, …, d_{N-1}\right}$,模型推荐的集合为 $R_i = \left[r_0, r_1, …, r_{Q-1}\right]$,按相关程序递减排序。
定义$rel_D(r)$在满足$r\in D$时为1,否则为0。
那么,还可以支持以下评估指标。

Hit Rate

$HitRate=\frac{1}{M}\sum_{i=0}^{M-1} \sum_{j=0}^{\left|D\right| - 1}rel_{{d_0}}(R_i(j))$

Average Reciprocal Hit Rank

$ARHR=\frac{1}{M}\sum_{i=0}^{M-1} \sum_{j=0}^{\left|D\right| - 1}\frac{1}{j+1}rel_{{d_0}}(R_i(j))$

Precision at k

$p(k)=\frac{1}{M} \sum_{i=0}^{M-1} {\frac{1}{k} \sum_{j=0}^{\min(\left|D\right|, k) - 1} rel_{D_i}(R_i(j))}$

这里 $k$ 是一个参数。

Recall at k

$recall(k)=\frac{1}{M} \sum_{i=0}^{M-1} {\frac{1}{N} \sum_{j=0}^{\min(\left|D\right|, k) - 1} rel_{D_i}(R_i(j))}$

这里 $k$ 是一个参数。

MAP (Mean Average Precision)

$MAP=\frac{1}{M} \sum_{i=0}^{M-1} {\frac{1}{\left|D_i\right|} \sum_{j=0}^{Q-1} \frac{rel_{D_i}(R_i(j))}{j + 1}}$

NDCG at k (Normalized Discounted Cumulative Gain)

$NDCG(k)=\frac{1}{M} \sum_{i=0}^{M-1} {\frac{1}{IDCG(D_i, k)}\sum_{j=0}^{n-1} \frac{rel_{D_i}(R_i(j))}{\ln(j+2)}},$

其中,$n = \min\left(\max\left(|R_i|,|D_i|\right),k\right)$, $IDCG(D, k) = \sum_{j=0}^{\min(\left|D\right|, k) - 1} \frac{1}{\ln(j+2)}$。

这里 $k$ 是一个参数。

使用方式

该组件通常接推荐排序预测算法的输出端。

使用时,需要通过参数 labelCol 指定预测标签列,参数 predictionCol 和 predictionCol 指定预测结果列。

参数说明

名称 中文名称 描述 类型 是否必须? 取值范围 默认值
labelCol 标签列名 输入表中的标签列名 String ✓
predictionCol 预测结果列名 预测结果列名 String ✓
labelRankingInfo Object列列名 Object列列名 String “object”
predictionRankingInfo Object列列名 Object列列名 String “object”

代码示例

Python 代码

from pyalink.alink import *

import pandas as pd

useLocalEnv(1)

df = pd.DataFrame([
    ["{\"object\":\"[1, 6, 2, 7, 8, 3, 9, 10, 4, 5]\"}", "{\"object\":\"[1, 2, 3, 4, 5]\"}"],
    ["{\"object\":\"[4, 1, 5, 6, 2, 7, 3, 8, 9, 10]\"}", "{\"object\":\"[1, 2, 3]\"}"],
    ["{\"object\":\"[1, 2, 3, 4, 5]\"}", "{\"object\":\"[]\"}"]
])

inOp = BatchOperator.fromDataframe(df, schemaStr='pred string, label string')

metrics = EvalRankingBatchOp().setPredictionCol('pred').setLabelCol('label').linkFrom(inOp).collectMetrics()
print(metrics)

Java 代码

import org.apache.flink.types.Row;

import com.alibaba.alink.operator.batch.BatchOperator;
import com.alibaba.alink.operator.batch.evaluation.EvalRankingBatchOp;
import com.alibaba.alink.operator.batch.source.MemSourceBatchOp;
import com.alibaba.alink.operator.common.evaluation.RankingMetrics;
import org.junit.Test;

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

public class EvalRankingBatchOpTest {
	@Test
	public void testEvalRankingBatchOp() throws Exception {
		List <Row> df = Arrays.asList(
			Row.of("{\"object\":\"[1, 6, 2, 7, 8, 3, 9, 10, 4, 5]\"}", "{\"object\":\"[1, 2, 3, 4, 5]\"}"),
			Row.of("{\"object\":\"[4, 1, 5, 6, 2, 7, 3, 8, 9, 10]\"}", "{\"object\":\"[1, 2, 3]\"}"),
			Row.of("{\"object\":\"[1, 2, 3, 4, 5]\"}", "{\"object\":\"[]\"}")
		);
		BatchOperator <?> inOp = new MemSourceBatchOp(df, "pred string, label string");
		RankingMetrics metrics = new EvalRankingBatchOp().setPredictionCol("pred").setLabelCol("label").linkFrom(inOp)
			.collectMetrics();
		System.out.println(metrics.toString());
	}
}

运行结果

-------------------------------- Metrics: --------------------------------
microPrecision:0.32
averageReciprocalHitRank:0.5
precision:0.2667
accuracy:0.2667
f1:0.3761
hitRate:0.6667
microRecall:1
microF1:0.4848
subsetAccuracy:0
recall:0.6667
map:0.355
hammingLoss:0.5667