一、关于 NDCG

[LTR] 信息检索评价指标(RP/MAP/DCG/NDCG/RR/ERR)

二、代码实现

1、训练数据的加载解析

import scala.io.Source

/*
* 训练行数据
* */
case class TrainDataRow(target: Int, qid: Int, features: Array[Double]) object TrainDataRow {
// 加载文件数据
// 格式:
// <line> .=. <target> qid:<qid> <feature>:<value> <feature>:<value> ... <feature>:<value> # <info>
// <target> .=. <positive integer>
// <qid> .=. <positive integer>
// <feature> .=. <positive integer>
// <value> .=. <float>
// <info> .=. <string>
def loadFile(file: String): List[TrainDataRow] = {
Source.fromFile(file).getLines.toList.par.map(x => {
val strArray = x.split(' ')
val label = strArray(0).toInt
val qid = strArray(1).split(':')(1).toInt
val fValArray = strArray.drop(2).map(x => x.split(':')(1).toDouble)
new TrainDataRow(label, qid, fValArray)
}).toList
}
}

2、NDCG 的实现

object NDCG {
/*
* 计算 NDCG 分值
* */
def score(rows: List[TrainDataRow], k: Int): Double = {
val size = k.min(rows.length - 1)
// 理想 DCG
var idealDcg: Double = 0
val sortedList = rows.sortWith((x, y) => x.target > y.target)
for (i <- 0 to size) {
// 计算累计效益
val gain = (1 << sortedList(i).target) - 1
// 计算折扣因子
val discount = 1.0 / (Math.log(i + 2) / Math.log(2))
idealDcg += gain * discount
}
if (idealDcg > 0) {
var dcg: Double = 0
for (i <- 0 to size) {
// 计算累计效益
val gain = (1 << rows(i).target) - 1
// 计算折扣因子
val discount = 1.0 / (Math.log(i + 2) / Math.log(2))
dcg += gain * discount
}
dcg / idealDcg
}
else 0
}
}

3、训练数据集的 NDCG 计算

def calcNDCG(trainDataFile: String, k: Int): Double = {
println("开始计算...")
val start = System.nanoTime()
val data = TrainDataRow.loadFile(trainDataFile) // 加载训练数据文件
println("数据量:" + data.length + ",用时:" + (System.nanoTime() - start) / 1000000 + " ms")
val grpData: Map[Int, List[TrainDataRow]] = data.groupBy(_.qid) // 根据 qid 分组
val resultNDCG = grpData.map(x => NDCG.score(x._2, k)).sum / grpData.size
println(s"NDCG@$k: $resultNDCG")
val end = System.nanoTime()
println("计算运行时间:" + (end - start) / 1000000 + " ms")
resultNDCG
}

by. Memento

[Scala] 实现 NDCG的更多相关文章

  1. Spark Streaming高级特性在NDCG计算实践

    从storm到spark streaming,再到flink,流式计算得到长足发展, 依托于spark平台的spark streaming走出了一条自己的路,其借鉴了spark批处理架构,通过批处理方 ...

  2. jdb调试scala代码的简单介绍

    在linux调试C/C++的代码需要通过gdb,调试java代码呢?那就需要用到jdb工具了.关于jdb的用法在网上大家都可以找到相应的文章,但是对scala进行调试的就比较少了.其实调试的大致流程都 ...

  3. scala练习题1 基础知识

    1, 在scala REPL中输入3. 然后按下tab键,有哪些方法可以被调用? 24个方法可以被调用, 8个基本类型: 基本的操作符, 等:     2,在scala REPL中,计算3的平方根,然 ...

  4. 牛顿法求平方根 scala

    你任说1个整数x,我任猜它的平方根为y,如果不对或精度不够准确,那我令y = (y+x/y)/2.如此循环反复下去,y就会无限逼近x的平方根.scala代码牛顿智商太高了println( sqr(10 ...

  5. Scala集合和Java集合对应转换关系

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 用Scala编码的时候,经常会遇到scala集合和Java集合互相转换的case,特意mark一 ...

  6. Scala化规则引擎

    1. 引言 什么是规则引擎 一个业务规则包含一组条件和在此条件下执行的操作,它们表示业务规则应用程序的一段业务逻辑.业务规则通常应该由业务分析人员和策略管理者开发和修改,但有些复杂的业务规则也可以由技 ...

  7. Scala快速概览

    IDEA工具安装及scala基本操作 目录 一. 1. 2. 3. 4. 二. 1. 2. 3. 三. 1. 2. 3. 4. 5. 6. 7. 四. 1. (1) (2) (3) (4) (5) ( ...

  8. Scala Macros - scalamela 1.x,inline-meta annotations

    在上期讨论中我们介绍了Scala Macros,它可以说是工具库编程人员不可或缺的编程手段,可以实现编译器在编译源代码时对源代码进行的修改.扩展和替换,如此可以对用户屏蔽工具库复杂的内部细节,使他们可 ...

  9. Scala Macros - 元编程 Metaprogramming with Def Macros

    Scala Macros对scala函数库编程人员来说是一项不可或缺的编程工具,可以通过它来解决一些用普通编程或者类层次编程(type level programming)都无法解决的问题,这是因为S ...

随机推荐

  1. javax.servlet.JspTagException:Illegal use of &lt;when&gt;-style tag without &lt;choose &gt;as its di

    1.错误描述 javax.servlet.JspTagException:Illegal use of <when>-style tag without <choose >as ...

  2. INS-30011 输入的ADMIN口令不符合Oracle建议的标准

    1.错误描述 2.错误原因 由于在设置密码时,首个字符为数字,导致出错 a.必须以字母开头 b.长度不超过30个字符 c.只能包含字母.数字和_.$.# d.不能使用关键字和保留字 3.解决办法 重新 ...

  3. 使用NPOI导入导出标准Excel

    尝试过很多Excel导入导出方法,都不太理想,无意中逛到oschina时,发现了NPOI,无需Office COM组件且不依赖Office,顿时惊为天人,怀着无比激动的心情写下此文. 曾使用过的方法 ...

  4. P1141 01迷宫

    https://www.luogu.org/problemnew/show/P1141 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样 ...

  5. Struts2【开发Action】知识要点

    前言 前面Struts博文基本把Struts的配置信息讲解完了.....本博文主要讲解Struts对数据的处理 Action开发的三种方式 在第一次我们写开发步骤的时候,我们写的Action是继承着A ...

  6. C#多线程编程(1)--线程,线程池和Task

    新开了一个多线程编程系列,该系列主要讲解C#中的多线程编程.    利用多线程的目的有2个: 一是防止UI线程被耗时的程序占用,导致界面卡顿:二是能够利用多核CPU的资源,提高运行效率. 我没有进行很 ...

  7. springboot--springboot+mybatis多数据源最简解决方案

    说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解 ...

  8. [BZOJ1061] [Noi2008] 志愿者招募 (费用流)

    Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能 ...

  9. Vue-框架模板的源代码注释

    请稍等..吃完饭回来写 吃饭回来了~嘿 ----------------正经分割线----------------- 先看我的目录结构:这是配置好node环境和配置好webpack后,生成的原始框架. ...

  10. 通过logstash-input-mongodb插件将mongodb数据导入ElasticSearch

    目的很简单,就是将mongodb数据导入es建立相应索引.数据是从特定的网站扒下来,然后进行二次处理,也就是数据去重.清洗,接着再保存到mongodb里,那么如何将数据搞到ElasticSearch中 ...