Scala-Spark digamma stackoverflow问题
这两天在用spark做点击率的贝叶斯平滑,参考雅虎的论文进行了一番尝试。
先上代码:
# click_count, show_count # this method takes time
def do_smooth(data_list):
import scipy.special as sp
a, b, i = 1.0, 1.0, 0
da, db = a, b
while i < 1000 and (da > 1.0E-10 or db > 1.0E-10):
x1, y1, x2 = 0.0, 0.0, 0.0
for lineList in data_list:
x1 += sp.digamma((lineList[0]) + a) - sp.digamma(a)
y1 += sp.digamma((lineList[1]) + a + b) - sp.digamma(a + b)
x2 += sp.digamma((lineList[1]) - (lineList[0]) + b) - sp.digamma(b)
na, nb = a, b
a *= (x1 / y1)
b *= (x2 / y1)
da, db = abs(a - na), abs(b - nb)
i += 1
print i, a, b
return a, b
这是我之前用的python代码,改成scala也相当容易,digamma函数非常耗时,而且还要迭代1000次。最要命的是digamma在scala里面默认的实现会出现栈溢出!!!
var a, b, da, db: Double = 1.0
var index = 0
while (index < 1000 && (da > 1.0E-9 || db > 1.0E-9)) {
var x1,x2,y1 = 0.0
traindata.foreach(p => {
x1 += MBlas.digamma(p(2) + a) - MBlas.digamma(a)
y1 += MBlas.digamma(p(1) + a + b) - MBlas.digamma(a + b)
x2 += MBlas.digamma(p(1) - p(2) + b) - MBlas.digamma(b)
val na = a
val nb = b
a *= (x1 / y1)
b *= (x2 / y1)
da = Math.abs(a - na)
db = Math.abs(b - nb)
})
}
digamma 函数是个递归函数,问题就处在递归上了。
public static double digamma(double x) {
if (x > 0 && x <= S_LIMIT) {
return -GAMMA - 1 / x;
}
if (x >= C_LIMIT) {
double inv = 1 / (x * x);
return FastMath.log(x) - 0.5 / x - inv * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252));
}
return digamma(x + 1) - 1 / x;
}
既然知道问题所在,是不是就可以重写递归为非递归呢?在Stack Overflow上找到了一个答案
val GAMMA = 0.577215664901532860606512090082
val GAMMA_MINX = 1.e-12
val DIGAMMA_MINNEGX = -1250
val C_LIMIT = 49
val S_LIMIT = 1e-5
var value = 0.0
var x = input
while (true) {
if (x >= 0 && x < GAMMA_MINX) x = GAMMA_MINX
if (x < DIGAMMA_MINNEGX) {
x = DIGAMMA_MINNEGX + GAMMA_MINX
} else {
if (x > 0 && x <= S_LIMIT) return value + -GAMMA - 1 / x
if (x >= C_LIMIT) {
val inv = 1 / (x * x)
return value + Math.log(x) - 0.5 / x - inv * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252))
}
value = value - 1.0 / x
x += 1
}
}
经测试,没看出什么问题,可以用了。
不过,上面的代码并没有解决慢的问题,当需要计算CTR的对象比较多时(几百万),仍然比较耗时。所以我决定用两个替代方法:
- 抽样,抽取能在可接受时间内出结果的样本数,得到α和β;
- 直接使用平均值作为α和β
- 使用平均值做迭代初值(推荐)
Scala-Spark digamma stackoverflow问题的更多相关文章
- brdd 惰性执行 mapreduce 提取指定类型值 WebUi 作业信息 全局临时视图 pyspark scala spark 安装
[rdd 惰性执行] 为了提高计算效率 spark 采用了哪些机制 1-rdd 基于分布式内存数据集进行运算 2-lazy evaluation :惰性执行,即rdd的变换操作并不是在运行该代码时立 ...
- Eclipse+maven+scala+spark环境搭建
准备条件 我用的Eclipse版本 Eclipse Java EE IDE for Web Developers. Version: Luna Release (4.4.0) 我用的是Eclipse ...
- 在IntelliJ IDEA中创建和运行java/scala/spark程序
本文将分两部分来介绍如何在IntelliJ IDEA中运行Java/Scala/Spark程序: 基本概念介绍 在IntelliJ IDEA中创建和运行java/scala/spark程序 基本概念介 ...
- eclipse构建maven+scala+spark工程 转载
转载地址:http://jingpin.jikexueyuan.com/article/47043.html 本文先叙述如何配置eclipse中maven+scala的开发环境,之后,叙述如何实现sp ...
- Windows下Eclipse+Scala+Spark开发环境搭建
1.安装JDK及配置java环境变量 本文使用版本为jdk1.7.0_79,过程略 2.安装scala 本文使用版本为2.11.8,过程略 3.安装spark 本文使用版本为spark-2.0.1-b ...
- Scala - Spark Lambda“goesto“ => 分析
/// 定义一个函数AddNoise,参数分别为rdd,Fraction.其中rdd为(BreezeDenseMatrix, BreezeDenseMatrix)元组构成的RDD.Fraction为一 ...
- Eclipse + Idea + Maven + Scala + Spark +sbt
http://jingpin.jikexueyuan.com/article/47043.html 新的scala 编译器idea使用 https://www.jetbrains.com/idea/h ...
- eclipse构建maven+scala+spark工程
前提条件 下载安装Scala IDE build of Eclipse SDK 构建工程 1.新建maven工程 2.配置项目信息 3.新建scala对应的Source Folder 4.添加scal ...
- scala spark 机器学习初探
Transformer: 是一个抽象类包含特征转换器, 和最终的学习模型, 需要实现transformer方法 通常transformer为一个RDD增加若干列, 最终转化成另一个RDD, 1. 特征 ...
随机推荐
- 201521123071 《JAVA程序设计》第七周学习总结
第7周-集合 1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 1.1 Iterator<E> iterator(); //iterator()返回一个实现了It ...
- 201521123059 《Java程序设计》第五周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 1.Comparable与Arrays.sort,其功能是对指定对象数组按升序进 ...
- 201521123014 《Java程序设计》第4周学习总结
1. 本周学习总结 1.1 有关继承的知识点 1.2 使用常规方法总结其他上课内容 多态性 相同的形态,不同的行为 例子: public class Manager extends Employee{ ...
- 201521123096《Java程序设计》第一周学习总结
1. 本章学习总结: 对JAVA的发展有一定的了解.JAVA是一种高级语言,需要在JVM上执行.初步学会使用eclipse和NOtepad++. 2. 书面作业 Q1:为什么java程序可以跨平台运行 ...
- 201521123016 《Java程序设计》第13周学习总结
1. 本周学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? ping w ...
- Junit4学习(六)Junit4参数化设置
一,背景, 有时候会对相同的代码结构做同样的操作,不同的时对参数的设置数据和预期结果:有没有好的办法提取出来相同的代码,提高代码的可重用度,junit4中使用参数化设置,来处理此种场景: 二,代码展示 ...
- Hibernate第十篇【Hibernate查询详解、分页查询】
前言 在Hibernate的第二篇中只是简单地说了Hibernate的几种查询方式-.到目前为止,我们都是使用一些简单的主键查询阿-使用HQL查询所有的数据-.本博文主要讲解Hibernate的查询操 ...
- [01] Servlet是什么
1.Servlet是什么 Servlet(Server Applet),全称Java Servlet,是用Java编写的服务器端程序.其主要功能在于交互式地浏览和修改数据,生成动态Web内容. 1.1 ...
- Oracle-表被锁住
1.如果update 某个表,没有报错,等待很久都没结束,那很有可能是表被锁了. 2.查看被锁的对象 select sid,serial#,username,SCHEMANAME,osuser,MAC ...
- 二叉树终极教程--BinarySearchTree
BinarySearchTreeMap 的 实现 public interface Map<K extends Comparable<K>, V> { void put(K k ...