[Scala] 实现 NDCG
一、关于 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的更多相关文章
- Spark Streaming高级特性在NDCG计算实践
从storm到spark streaming,再到flink,流式计算得到长足发展, 依托于spark平台的spark streaming走出了一条自己的路,其借鉴了spark批处理架构,通过批处理方 ...
- jdb调试scala代码的简单介绍
在linux调试C/C++的代码需要通过gdb,调试java代码呢?那就需要用到jdb工具了.关于jdb的用法在网上大家都可以找到相应的文章,但是对scala进行调试的就比较少了.其实调试的大致流程都 ...
- scala练习题1 基础知识
1, 在scala REPL中输入3. 然后按下tab键,有哪些方法可以被调用? 24个方法可以被调用, 8个基本类型: 基本的操作符, 等: 2,在scala REPL中,计算3的平方根,然 ...
- 牛顿法求平方根 scala
你任说1个整数x,我任猜它的平方根为y,如果不对或精度不够准确,那我令y = (y+x/y)/2.如此循环反复下去,y就会无限逼近x的平方根.scala代码牛顿智商太高了println( sqr(10 ...
- Scala集合和Java集合对应转换关系
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 用Scala编码的时候,经常会遇到scala集合和Java集合互相转换的case,特意mark一 ...
- Scala化规则引擎
1. 引言 什么是规则引擎 一个业务规则包含一组条件和在此条件下执行的操作,它们表示业务规则应用程序的一段业务逻辑.业务规则通常应该由业务分析人员和策略管理者开发和修改,但有些复杂的业务规则也可以由技 ...
- Scala快速概览
IDEA工具安装及scala基本操作 目录 一. 1. 2. 3. 4. 二. 1. 2. 3. 三. 1. 2. 3. 4. 5. 6. 7. 四. 1. (1) (2) (3) (4) (5) ( ...
- Scala Macros - scalamela 1.x,inline-meta annotations
在上期讨论中我们介绍了Scala Macros,它可以说是工具库编程人员不可或缺的编程手段,可以实现编译器在编译源代码时对源代码进行的修改.扩展和替换,如此可以对用户屏蔽工具库复杂的内部细节,使他们可 ...
- Scala Macros - 元编程 Metaprogramming with Def Macros
Scala Macros对scala函数库编程人员来说是一项不可或缺的编程工具,可以通过它来解决一些用普通编程或者类层次编程(type level programming)都无法解决的问题,这是因为S ...
随机推荐
- javax.servlet.JspTagException:Illegal use of <when>-style tag without <choose >as its di
1.错误描述 javax.servlet.JspTagException:Illegal use of <when>-style tag without <choose >as ...
- INS-30011 输入的ADMIN口令不符合Oracle建议的标准
1.错误描述 2.错误原因 由于在设置密码时,首个字符为数字,导致出错 a.必须以字母开头 b.长度不超过30个字符 c.只能包含字母.数字和_.$.# d.不能使用关键字和保留字 3.解决办法 重新 ...
- 使用NPOI导入导出标准Excel
尝试过很多Excel导入导出方法,都不太理想,无意中逛到oschina时,发现了NPOI,无需Office COM组件且不依赖Office,顿时惊为天人,怀着无比激动的心情写下此文. 曾使用过的方法 ...
- P1141 01迷宫
https://www.luogu.org/problemnew/show/P1141 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样 ...
- Struts2【开发Action】知识要点
前言 前面Struts博文基本把Struts的配置信息讲解完了.....本博文主要讲解Struts对数据的处理 Action开发的三种方式 在第一次我们写开发步骤的时候,我们写的Action是继承着A ...
- C#多线程编程(1)--线程,线程池和Task
新开了一个多线程编程系列,该系列主要讲解C#中的多线程编程. 利用多线程的目的有2个: 一是防止UI线程被耗时的程序占用,导致界面卡顿:二是能够利用多核CPU的资源,提高运行效率. 我没有进行很 ...
- springboot--springboot+mybatis多数据源最简解决方案
说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解 ...
- [BZOJ1061] [Noi2008] 志愿者招募 (费用流)
Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能 ...
- Vue-框架模板的源代码注释
请稍等..吃完饭回来写 吃饭回来了~嘿 ----------------正经分割线----------------- 先看我的目录结构:这是配置好node环境和配置好webpack后,生成的原始框架. ...
- 通过logstash-input-mongodb插件将mongodb数据导入ElasticSearch
目的很简单,就是将mongodb数据导入es建立相应索引.数据是从特定的网站扒下来,然后进行二次处理,也就是数据去重.清洗,接着再保存到mongodb里,那么如何将数据搞到ElasticSearch中 ...